返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.3 o/ q* Q4 R4 |. x* w% X6 w8 m4 f
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
# e. P' S3 ~! r$ N/**************表达式计算器************/5 V9 A& O0 H. k5 s- q# I
#include <stdio.h>
8 Y3 S2 T! [% t5 x) I#include <stdlib.h>: L+ w0 K% A# w  y2 b) S
#include <string.h>
: ~- c; z; B8 E, ~+ I1 T#include <conio.h>
6 A6 K) o2 I, q  N" [#include <malloc.h>
% i' G: m8 K9 I/ c% g
5 G9 r7 A# j0 O' \0 I. J#define STACK_SIZE 1003 x6 {) m& x% z. c. w& B0 |8 A
#define APPEND_SIZE 108 w0 Z9 M7 \# I# W1 j) \. h+ x

* f/ z) \& \4 }9 ?. Kstruct SNode{5 E( I/ l3 Z/ y" Q  `. J
    float data; /*存放操作数或者计算结果*// g4 U( l/ s) Q" f0 K$ s8 r" M+ |
    char ch; /*存放运算符*/
' r# _5 n& K& B$ a( k1 {5 E};
& g& K& A2 ^; u9 A3 ]$ ]$ s. n, L% \& ], f) b
struct Stack{
$ e5 K) ?; \. X# c    SNode *top;
2 v$ c# c: b4 d$ G$ a# f$ T    SNode *base;
5 ]! J; {) ]5 `0 J9 g  f2 \& M1 E4 k2 M* ?    int size;
1 f3 n3 g; f  \$ V8 {1 O; F};
2 ^1 X- ?0 v$ r2 C1 g9 n0 ]' M9 w, h# l. T* b; J% {+ T' G$ W& w
/*栈操作函数*/" r9 `7 s( v/ T- [; |5 a* i
int InitStack(Stack &S); /*创建栈*/
" e3 _. x5 _4 s# ~5 ?5 }) Eint DestroyStack(Stack &S); /*销毁栈*/
  _( j  p3 i( l% P8 Z  dint ClearStack(Stack &S); /*清空栈*/
/ t. r# X- w& O3 W' l; n% B% E% _int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
" k7 L2 f% l% i- ~. \; z' A& ^int Push(Stack &S,SNode e); /*将结点e压入栈*/
$ Q0 G& @: P' C" ^* J( o) z% S+ ?int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
2 A  i# G6 r8 @- X3 H4 R+ N
6 T0 i! u5 A' v% _* Q  V/*表达式计算器相关函数*/
( c* U6 a3 ^* q% J4 xchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
2 g* K8 u3 c( [  N& u3 Tint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
& p/ z8 ^! ]( u! O- ^float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/6 H- `4 ]0 w. I8 s- V
float compute(); /*表达式结算器主函数*/% L; h/ ]- i6 N; d  c+ v, A
char *killzero(float result); /*去掉结果后面的0*/ & ~3 a, m! d9 G; n1 p4 O- r/ Y2 c

. B' V; K4 n* [$ \int InitStack(Stack &S)  s* ^- a& s& _* S0 V# ]
{; N- @$ U) K, D$ C4 t& R; l3 \; x4 g
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
* w4 C7 O8 `: g: }) l. z6 S    if(S.base==NULL)3 D  o/ _3 e- p
    {
; t2 x! [7 g% A/ h" N) u  ]        printf("动态分配内存失败!");
* I2 G: I9 b9 I* w8 w        return -1;
/ _) u7 j3 V/ R    }
) [2 t. V& \' o1 X0 c    S.top=S.base;
) b" ^2 [: k  S* a- O: I/ C    S.size=STACK_SIZE;
: Z5 _$ e* H' I5 N    return 0;; r  |$ G0 R9 Z  M* J( a+ N; m; |
}
$ ]. D! z5 L7 Z# Q4 I! F, z$ ^; Y' X- q: g# p: e, I3 q
int DestroyStack(Stack &S)
7 K4 I$ d0 p* ^& C3 x{
0 s! Z7 D8 H0 g4 T2 J    free(S.base);3 ^: W# o3 m. T) b) \% W
    return 0;& O8 O4 L# J- Y9 O7 }; ]. L
}
% R) `, c% R: F0 P9 i8 W3 l
) `& o+ _/ B# L0 a4 ?$ S7 n+ A) oint ClearStack(Stack &S)
; q9 G( g! D5 U$ I' U, o: {3 {) j: X/ K{& X" Z) i# O5 P4 q% J$ U% a
    S.top=S.base;* x- r9 a* n- I; t/ W% f
    return 0;: u9 q4 i0 j+ M% P+ I
}* o$ M' R4 Y6 M7 a  W' V  |( y
& T! F, Z- A& r# P: P! b1 Z
int GetTop(Stack S,SNode &e)8 J" O! w6 X- _- `- F4 ]7 n+ u* y
{
$ [9 L: O6 I" y$ U& M; u2 s    if(S.top==S.base)( f$ r* d; `( I5 v2 I
    {
# e" I. {. \1 u7 q5 c2 v8 K        printf("栈以为空!");
: l/ I" O  T" x9 m4 b, m" P        return -1;
5 ]) _0 _1 z& I: |    }
  c9 Y; J& w+ j& a! b$ Y9 Q    e=*(S.top-1);
. g+ I% b' N* y  _    return 0;, z4 \8 ?- u9 m/ E' ~
}8 t; S: D0 ]( c/ _
) ^3 |1 C6 b0 r5 i" W' r
int Push(Stack &S,SNode e)+ ^" Z& N! p) o3 v
{* C, o2 S2 r& ]$ \' c  h$ S+ a2 b
    if(S.top-S.base>=S.size)
. c/ F9 {; o+ Y3 T9 [    {
( n- y, H2 e( j  c, U1 Z! m, _        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));+ j+ L7 [$ B( Q
        if(S.base==NULL)
1 X4 y- I4 N8 x* }( d        {
9 h  v  e5 y2 V8 b            printf("动态分配内存失败!");9 _" X" N% v8 _
            return -1;
3 J( Z4 K- }( a; |- _        }
6 M, \* U! U" ]        S.top=S.base+S.size;
4 G# K/ @- T7 i        S.size+=APPEND_SIZE;
: r; F4 }) V$ q9 p4 \8 b! r/ H; Q1 V    }6 p/ r3 R' _6 W
    *S.top=e;0 L' D& L  T5 J1 G
    S.top++;3 l4 W7 i$ A, ]+ L* u' ~1 Q
    return 0;8 H3 g) I" w+ f5 j
}% @6 s# }! y# Q3 v+ i% n7 b7 r8 `& s( \
) H  X& w% U  j/ b- g4 A8 L/ u
int Pop(Stack &S,SNode &e)
$ A$ x6 l( A; m) A4 N+ K4 i% f{, N4 T/ ?- m) P! {; b2 |
    if(S.top==S.base)
7 U2 G6 \  t3 D  ^( a* w8 k; a0 ~    {
  C9 h! R! K* R5 c. z1 E4 D4 O! v  a/ K4 \        printf("栈为空!");1 v% M! A- d" m0 J* p, a
        return -1;, H7 H  c6 |8 U) S
    }
2 g3 K% r7 U. s2 K: A: l    e=*(S.top-1);
2 P) M  `9 T. N& E    S.top--;
* t0 j7 w* ?1 F5 o2 Z    return 0;
& T3 w8 R. S$ q5 }}7 ^  _" k8 H! t# j& @; x) O
/ ]0 [4 k" \% ~* F
char get_precede(char s,char c)
% \& c) I, H: C7 ]+ P. K. V/ r{" i) U% `! K7 B  a5 i
    switch(s)
) a4 A% b1 Z) A    {
% i7 k) g0 _  O5 v9 b+ [1 Y' L        case '+':                 . D3 [" ^8 w6 _7 ~
        case '-':/ Q5 S( y* |0 S% |" L5 s
             if(c=='+'||c=='-'); A" W& X* c* p; O* i* H
                 return '>';6 }3 ^7 w) k9 L
             else if(c=='*'||c=='/')4 o! c/ K; D1 x
                 return '<';! w* o  h2 g) ~0 W+ d2 z3 h
             else if(c=='('); ?" r7 N* G4 s5 d# F9 z
                 return '<';3 I( i! ^6 x& |
             else if(c==')')- N& L$ Z0 \# L
                 return '>';
7 Z/ n4 W, K4 Y4 O# w( e             else
# N, V+ @* J/ R  I( E( |/ E                 return '>';  H! X+ u. a  M) C
        case '*':
- r5 y# S$ W0 u4 }        case '/':
! t" K; I2 m6 r             if(c=='+'||c=='-')/ H* }" G1 R5 b, ?
                 return '>';. e- [; d% d/ O, l+ S6 r: g  \
             else if(c=='*'||c=='/')- b* L, w+ D# k% q
                 return '>';
+ g6 n, P( Y8 m             else if(c=='(')
. u/ o- l; T9 E5 t9 f' D5 H' E                 return '<';
; c* w( {; ]- u             else if(c==')')8 {  p0 u4 M2 ]. G. U' M7 T& i& {9 t
                 return '>';
: f3 q0 A. l% p: r6 P/ Z             else4 B$ k  J- ]3 p$ h- s8 G" n
                 return '>';
4 ]. Y0 f6 }$ R        case '(':8 z% c* b( F  k! ?' r
             if(c=='+'||c=='-')2 v4 y  r) h" ^+ C, v- `
                 return '<';/ A- X% J/ A$ r/ Y6 D! g' L
             else if(c=='*'||c=='/')
% C# D% c& c6 j: j                 return '<';: W2 j# F1 e# K  }
             else if(c=='(')
8 p1 m; j. U  |+ l8 e                 return '<';
, f0 u! _1 @. l" E  S, Y             else if(c==')')
( \* y/ q$ S. Y' p0 D7 k                 return '=';
" X) S3 Y8 d" x) o6 F             else4 e/ r: n; s& X- `
                 return 'E';
- P# x4 |' B: d        case ')':* a& ~. ^" s* x. K5 x3 F
             if(c=='+'||c=='-')% r: q; s. l: x+ N0 W
                 return '>';
8 x1 f$ o- `1 H$ I$ b             else if(c=='*'||c=='/')
/ ]. \! X# D7 {- ]                 return '>';
& i/ U7 `" W' q& ~$ }) {             else if(c=='(')$ Y+ t% V) x+ I0 \7 j, y- l' z$ E
                 return 'E';& n3 O. L; D0 G9 q' n- }* a0 A. ~
             else if(c==')')+ L. c8 ^1 P5 [* z
                 return '>';9 o2 P; \2 f" g4 f: ~9 i
             else
2 M2 h- ]* ^) F/ s- o3 Y4 m1 s                 return '>';2 e+ T8 t' \% Q
        case '#':3 A+ o+ I' y. W( ?
             if(c=='+'||c=='-')" N# I# g5 L7 j4 c. a: [2 y
                 return '<';4 k/ U0 W7 y0 E$ R0 e, U
             else if(c=='*'||c=='/')
2 n. e% @6 ]' [: Z0 Y4 N  V% Y5 H                 return '<';
0 @) J0 ~' [  I/ o7 H             else if(c=='(')
. W: S# Y% V9 C$ c7 Y                 return '<';2 l0 o# P0 M7 R" u
             else if(c==')')
5 u  u5 f4 v1 t7 V4 p                 return 'E';' N' o+ K7 S$ d6 X" l
             else
. r% `4 e3 ?# ^( Z4 g                 return '=';
! L% F1 s3 e" E5 I2 ?        default:: F2 X' e) h$ b2 |
             break;
: x$ ^( P( j2 u2 Z2 @    }+ `7 O( X! _. S! q& M
    return 0;    & O8 F9 `( \# M  [* T7 @5 `9 L2 Q
}/ X; }9 ?# ?  c2 a3 l6 s
5 r6 z% [: ~8 d( b3 M
int isOpr(char c)
) {% e7 G1 d$ A1 r- U7 o' }( ?{
/ M$ v, w* h$ A0 ]    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')4 H9 H% v- q: Z$ ^  V
        return 0;* @0 W+ x  F2 Z. Z1 M- Y  @
    else + v" T& J# X% J3 F
        return 1;
% v0 Q1 |* c$ H% u/ J}: j$ U1 I- m  a8 D' u2 x  A4 I0 h6 z: `
7 e* g" u- x- D- Q, b
float operate(float x, char opr, float y)! I3 u9 V3 _, u: l
{, h: u( s3 H) W, K6 h# h  G
    float result;* T6 f( j& u9 B" c& g2 h8 z
    switch (opr)6 C" x8 U" f5 t
    {  r6 A; f4 Z& ]( z6 t6 d
        case '+':
( \$ @% v; k4 s: L* }6 e             result = x + y;
3 _; c8 |6 t3 u0 \+ E3 ]( E2 W$ K             break;2 Z) B( M7 [# ^
        case '-':
  K6 A) e4 e$ w. I% }" J! ]             result = x - y;
8 t, ^+ `/ O8 M             break;
2 }" F$ R1 B$ |. o$ u- a" _        case '*': 6 G8 ^: L: Y' V; y0 d9 g) O
             result = x * y;
$ C0 V% t1 D  b/ u7 I             break;
7 A& {5 [6 m. b+ f% S+ _' q        case '/':
. @. h2 J2 W6 C& {& O             if (y == 0)
0 Y- ]$ }8 T8 N9 @  t             {8 C$ t- S, A6 a9 y5 }  ~
                printf("Divided by zero!\n");
. x  T) u6 u7 Q) k7 V/ g1 J                return 0;
' W$ O9 }# L7 G$ H: ^0 _& g             }
. M; k8 a) x6 A0 M  h             else+ ~% j% x6 |3 r9 W0 m# l
             {. @7 `; o' @+ p$ h9 C
                 result = x / y;, G) i# Q; v9 K, s3 C
                 break;
* H: z. M4 r7 L3 }" O             }
: X, C0 M! ?: l5 w; r/ Y, |  \       default: 2 c7 G1 ]$ F  N5 h. h
             printf("Bad Input.\n");
1 ?5 O3 Y+ d% Q) Q3 P! K             return 0;
. {+ S/ {  @. U: e$ b/ b    }! t' K2 _' ?( R+ f+ i% [* c& w* q
    return result;5 X# e+ J# U/ W) [
}    8 A/ J5 ^9 `7 {* c; R0 l" `7 N

' J1 l1 N# s$ e+ b7 _! e& r/ E. ffloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
" z$ G# E+ V: _% C9 e* {& T{& g/ O# [: B9 x+ \  E. o. C8 p
    Stack optr,opnd;
% ?% w0 ~5 c$ \! u  l0 L    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
! |( p5 ]3 J9 R3 ?8 h5 a7 ]    char c;
) C. w; X4 @$ w! m2 `" P+ j    char buf[16];
3 a: B4 W; p, x, R4 o$ J& L7 ?    int i=0;
) r) l6 N* [8 f   
  x2 ^% ]- e6 M9 n- X  x/ U6 R8 S1 |    InitStack(optr); /*用于寄存运算符*/$ M2 b& K0 B9 V- s) w  q; b) }! @5 r
    InitStack(opnd); /*用于寄存操作数和计算结果*/
) B, A+ x% c, [% [, v    memset(buf,0,sizeof(buf));2 _3 J" ]5 D( @3 |4 U. Z+ b7 A' V
    $ V! B: X& |3 \- x) k
    printf("Enter your expression:");
# a1 x9 B9 w7 D9 Q          a6 x( h4 g& d) m# V2 w
    opr_in.ch='#';
5 s. |' j7 B0 U. H& [' t- A    Push(optr,opr_in); /*'#'入栈*/
2 D3 \; d" g) x3 S5 A& E7 L    GetTop(optr,opr_top);
% _/ e$ K. ^  m2 y# W, y    c=getchar();
& b% L" b) X3 @' ^4 `    while(c!='='||opr_top.ch!='#')& Y) j- D0 z+ K. {
    {
- }2 Z6 k9 V6 V6 [        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
, E4 C; W7 r9 C4 R% y3 j, ?  ~        {
+ v0 k+ i4 C$ D# f& O* S            buf=c;  Q6 Y0 d) X" i
            i++;% l$ K* V8 \" x' \
            c=getchar();: J# j$ J/ R  h8 @- A
        }5 S/ s0 F& k  k9 T8 d! n
        else /*是运算符*/
0 [0 L- @* o! z2 S) \! U+ X. T        {
2 a' F1 ?, u+ }            buf='\0';
. l+ X: D) `$ B/ V, L" j8 d: q            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
. z. ^  l8 R( ]) y            {9 Q1 m2 e' @, d7 G' F/ D
                 opn_in.data=(float)atof(buf);
) Q3 g+ s' m5 D. k1 B0 W                 Push(opnd,opn_in);2 ^- p/ y0 _: o, r
                 printf("opnd入栈:[%f]\n",opn_in.data);( ~6 X# `7 z' }4 M; t8 D3 g! S( \
                 i=0;
; X6 k( G6 w" W) V  L  k3 b                 memset(buf,0,sizeof(buf));
7 E. V* _% H. _; F- A4 I. t            }- N) H" E& v1 X3 |
            opr_in.ch=c;, l, I/ m  S3 Y  y! R
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/9 N! Z/ C6 _; s. t+ B5 F1 r9 o* K! r
            {
" H1 _# ]) z0 V. F0 O6 M% z0 s                case '<': /*优先级小于栈顶结点,则运算符入栈*/
: h+ y2 b& E% D. J                     Push(optr,opr_in);
2 k9 s, E  [! [9 D                     printf("optr入栈:[%c]\n",opr_in.ch);" B) D: y- L  r- h2 \6 ~: m5 X
                     c=getchar();9 T( C3 D, B( `! G) U4 |5 F
                     break;: x; c# I* N; s' W; R: O
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/' \& r( @. f: r8 m
                     Pop(optr,e);
" M+ K$ B+ k% k3 U# Y/ W# ^3 J                     printf("optr出栈:去掉括号\n");
# a, ]7 w3 ?) N+ u. ]                     c=getchar();
- |, |; c( I5 n' D* b# w3 ~                     break;
8 B) p. ~$ ^3 b                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
6 N: Z" p( a6 P                     Pop(optr,opr_t);, q! o$ a. _3 S) Z' Y: R6 T# [6 S
                     printf("optr出栈:[%c]\n",opr_t.ch);
% A8 d5 s/ z/ D# @                     if(Pop(opnd,b)<0)
( I* S% F: i2 j; X& C                     {& H2 g5 h  r, E) ^
                         printf("Bad Input!\n");
0 g: e' E8 i( D+ x8 v                         fflush(stdin);/ h2 K6 b" S5 _7 v& H0 D8 E2 F
                         return -1;$ N, @. \- r* w0 n2 `' U
                     }
/ ]' [- Q+ G: ]4 l1 v                     printf("opnd出栈:[%f]\n",b.data);" `, M4 V1 h* r! R& |6 V$ z9 n/ Z. E
                     if(Pop(opnd,a)<0)7 T/ e' p, e; ?9 R* G
                     {
" L+ {  C/ |( s- k+ P                         printf("Bad Input!\n");
% f4 l7 T2 V0 W                         fflush(stdin);
; @, Y' M0 ]! S1 j                         return -1;
4 {; C% r4 S: k; \- y                     }; D$ ]8 G1 Z# v
                     printf("opnd出栈:[%f]\n",a.data);
* @7 C+ P" n9 H0 K  v' _$ j/ ?                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/0 k; F& x' h+ J
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/. q! n9 m3 _( c/ W6 i( h7 p* ]) U
                     printf("结果入栈:[%f]\n",opn_tmp.data);
6 z6 T/ o# w  Z/ v                     break;, B- x- K( _! v0 ?% x9 M( o; }
            }
" K  A/ d, h. S/ D' f& G, P        }. H9 G* B: x# d; C6 D# S
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
0 e; @2 o% J8 _: L, F& ]    }
. \/ I) H1 L) W) n- y% b3 W    GetTop(opnd,opn_tmp);
0 A0 h# z1 J) P. H8 d9 }    DestroyStack(optr);
: N8 l" \4 A9 ]4 f; m  J% w    DestroyStack(opnd);
& G1 C* o% X5 N" G% e* D* c0 Q    return opn_tmp.data;- T; K9 t; J& i4 k  S9 \
}) p( x- o# Q7 A' L+ p& G
5 e& L! g# v3 H' w! C  P3 o
char *killzero(char *res,float result)7 g! {* R& v. d: n
{
+ d! o, _) l+ }% ^% |% b    int i;
) _0 n! b0 T7 G! c- N* U8 @
+ O2 B: s% J) l' r4 c& P+ g9 |" k' D- Q    sprintf(res,"%f",result);3 g8 f9 y1 G5 i. K0 B  R
    i=(int)strlen(res)-1;
. E; j& ?( ]0 L! ~4 F& |& I2 ]; |    while(i&&res=='0')
+ u# d" J/ z4 `0 i0 K4 x; n    {
2 n! n9 v$ H' }% B( [; y        res='\0';1 O4 k' U3 V+ ~# C2 p
        i--;# k  ~7 Z, p+ \) Q
    }7 e8 |' @; O, |8 m# j1 B
    if(res=='.')
, Q0 A7 r: U0 c4 x0 H+ f$ j: V        res='\0';
% a1 G4 Q$ u% Z) O3 z4 a8 g# e    return res;3 }3 p& f+ P% I0 f1 q4 e5 b: x
}* v0 g2 {/ P# T" {6 @
& U, M% Y) {2 d6 A; J! m  a
int main()+ I1 G5 L: O4 G; |! W" b  c" y
{
  c$ k% z# z2 b    char ch;
2 g0 t0 J0 q! p8 o    char res[64];
! N- E6 _: `$ u) _6 O    float result;
* n. p2 c, `$ C  {    while(1)
) ]. ]$ p/ l( j    {  c. o& x1 C' f( O- c: L" B
        result=compute();7 R5 V) t+ {+ ]4 g' O# Q6 M
        printf("\nThe result is:%s\n",killzero(res,result));& U5 b3 L( G+ [2 @3 e
        printf("Do you want to continue(y/n)?:") ;, _- D' ]9 I6 Y
        ch=getch();9 X" `9 ^7 Z  m. Q0 K- P8 o
        putchar(ch);; y1 t: o- n9 i1 P0 h( E. S1 r8 |7 a
        if(ch=='n'||ch=='N')# }- ^2 C! I% [* L$ h  j: N1 Q
            break;
* Q9 A7 Y' L" ~1 w        else/ s$ B# l$ W/ Z& `$ S" P' p
            system("cls");
. r. f. z% t2 Q: p$ ]- e    }
" }$ Y6 |4 ~% L    return 0;
* x, M3 z9 D/ U4 j+ h( ]. u* |4 |}
% K  g% h- c8 G
6 j7 J" v1 P- W: E) |
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

返回列表
【捌玖网络】已经运行: