获得本站免费赞助空间请点这里
返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.1 G; B* w; b7 u, l
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
% G, R; K/ E) A  g( N* g  t. A/**************表达式计算器************/
. x4 ~' R& T: H8 j2 J8 ]5 h#include <stdio.h>
/ y, {2 o1 r: n#include <stdlib.h>
7 C7 W: \0 i9 o#include <string.h>
- }$ T+ \; L, ~5 x& Z#include <conio.h>
8 u' k7 B" F. n  \. p#include <malloc.h>" I: d5 R" {* Y/ ~( l9 }
) V8 G5 x3 L, O$ V( @
#define STACK_SIZE 100
! }  ~" C; X6 A" |#define APPEND_SIZE 104 G; k5 K! J# a' m* @* j3 h

; H$ E6 [  a3 F" j& s$ i% @' Pstruct SNode{, _2 x7 C' V1 o- Q. a4 i
    float data; /*存放操作数或者计算结果*/* N. R1 T( Q" c8 N2 g
    char ch; /*存放运算符*/
3 V! N1 ]  W" T4 N1 t, d# a};9 \: N  z2 e9 W# Q
5 h% p! }' K9 s. c' w
struct Stack{
- o  n2 d, j. t. W7 D" `5 ]% z5 X    SNode *top;9 `& }6 \7 e* t- b& ~5 O
    SNode *base;- V; w3 \3 J& P1 {; x% Z" K( C
    int size;
: [# }. [8 c/ B, d- x9 Y$ ]};
! g7 n2 p$ w* S# G
$ C4 ~. X6 ?4 u. b, ?/*栈操作函数*/
( o1 n% B9 g) J+ N) rint InitStack(Stack &S); /*创建栈*/
& x" }: B+ n1 iint DestroyStack(Stack &S); /*销毁栈*/
* ]6 F$ D/ B9 k1 U2 M0 W% Mint ClearStack(Stack &S); /*清空栈*/, X5 M4 h$ Z  G
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
7 @. X( V5 t2 Yint Push(Stack &S,SNode e); /*将结点e压入栈*/
/ o# Y$ }1 B1 b* F- eint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/3 A6 S, ~$ Q2 S
6 q6 z2 e. l7 Q: b" o; O
/*表达式计算器相关函数*/
# q  Q/ M1 W5 ]0 ]char get_precede(char s,char c); /*判断运算符s和c的优先级*/" `4 @% J( F/ x) j2 E
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/0 l3 _/ q* b( H# H
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
! a( }1 R7 K1 }& G) m5 G( O: Rfloat compute(); /*表达式结算器主函数*/1 \  e  [0 C2 w, y" V2 D
char *killzero(float result); /*去掉结果后面的0*/ 8 M0 M2 b4 Y8 H: t, w' x' L1 A

8 {" B0 q% S5 J1 u' H9 E- {int InitStack(Stack &S)/ f5 j0 {0 p6 A# Y3 n3 S8 e* E# Q
{
6 y" K4 f. A2 h: w$ ?    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
" D! i2 e3 d; P9 x, }! H    if(S.base==NULL)0 o( B; X+ A( q  n/ K4 K
    {) F/ T5 O# [+ S0 Y
        printf("动态分配内存失败!");8 w3 w4 s" O; k& Z
        return -1;
8 [+ ?- W4 j% u$ c7 N    }
' |4 u) e1 F) r- ?% x    S.top=S.base;
2 C- U$ B! s/ n* m    S.size=STACK_SIZE;
  e) q' J9 u1 i& O' Z; c7 z, N9 v    return 0;, X4 Q6 {: m- [% `0 @7 t( _
}
/ S; ]% P) c0 x! f
; X7 v- O7 q' a/ hint DestroyStack(Stack &S)
' b2 _7 Z, Y6 U- u{  X; P1 y; A$ }' k1 l3 }3 u
    free(S.base);
( n8 l6 c& ]; ]) O    return 0;$ T2 Z6 T6 t( @' w( }
}
) {* e$ G% A0 w% G& n0 R& o
* Q1 O& L& P) \  S5 E( Y( |! z6 z+ qint ClearStack(Stack &S)' B  K! c& }# }) ?) N. `
{
( e+ M6 N+ F, V( z) L$ a1 R    S.top=S.base;& p& l$ j% T$ [7 x+ ^. T1 O  d3 [
    return 0;
; H$ d# @. V. u; @7 h}8 [' Y- T" B: y. k3 `: M
: C: \- S& J1 C1 z
int GetTop(Stack S,SNode &e)( }4 y8 |  B* |5 R
{/ r0 f$ z/ R/ V' j) M7 M
    if(S.top==S.base). F: i4 o! I0 Q% g  o$ S( ^
    {( r$ e$ B2 X; n
        printf("栈以为空!");
8 U/ A; y3 A, p0 H/ f& m2 m        return -1;
. b: t3 j- W: M' ^. I$ @" L/ A    }& D( ?  h( o, D. v
    e=*(S.top-1);
" O; \; W; q6 Y8 V, f* _    return 0;- U+ c! L- ~- M4 I  U
}, ?  y  J9 ]3 u# H2 e! F8 @
/ e- U1 f+ ]% M' g- X& x$ ^
int Push(Stack &S,SNode e)
% l- K. |" k+ f% [! o{7 o) h; N9 ~, z: G+ X6 \$ B
    if(S.top-S.base>=S.size)
- m# X; ^8 S  U  J    {) R! m- r: i8 Z7 q( s( ?
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
! ?& _0 ]. {; l* |! w        if(S.base==NULL)/ o* |- n) q/ ?% ]
        {- z, I+ }2 T" [
            printf("动态分配内存失败!");4 C/ x* w1 j; r9 B% w  b: d
            return -1;
1 M' s# y4 P( [' A        }
8 D7 m# ]! l; u4 a" \& P3 f" q        S.top=S.base+S.size;* \% O; l1 u" ]$ U7 k
        S.size+=APPEND_SIZE;# t: g5 [. r; U, W* t4 A, @
    }# A$ O+ V7 h# k* S
    *S.top=e;
" K4 x- v' N7 @* ~( ?    S.top++;& _& l! ~7 j9 S( k0 D/ f9 x
    return 0;+ Q3 ~3 @* j  }& p, `) J9 V4 z
}
* Q$ c% ^' N6 i" b6 [. q7 d. S! L7 s( A3 J+ [
int Pop(Stack &S,SNode &e)
: K; L! x. h! ~+ W& Q+ c( P7 D{9 p1 b3 u$ m: _: h
    if(S.top==S.base)/ U! t% l' s- \8 N( q8 h
    {; j) e5 D! W/ ]
        printf("栈为空!");/ N0 b) [0 X/ w" J6 S& v) b5 F
        return -1;- D7 N1 ]$ M4 Y* n+ W% g
    }
; P7 O! ]3 p& ?    e=*(S.top-1);1 j5 t# X( M! n, d5 D' n6 g: h
    S.top--;3 N2 y% H# s4 D5 O! b7 L# B
    return 0;
  o2 u! |9 j( v$ j0 \* Z1 a}
+ N8 _5 e" H* L1 X0 o: s, b
# V& C# p/ a! U+ d. ichar get_precede(char s,char c)
1 V' \; m( x" K! A( A; k+ `{4 e) R& d  a6 X' Y+ ]# Y
    switch(s)
3 B& x) F- j/ h6 e6 |    {! D9 ^, T! c% N! a, q; E1 k( o7 Y" [  B
        case '+':                 9 j$ Z/ a' W8 D; `" C
        case '-':0 k/ q6 |" Q( e0 f6 l" V
             if(c=='+'||c=='-')
) z2 M# u4 S4 b9 }0 e# R                 return '>';
5 G) m* f$ S9 n- G; g             else if(c=='*'||c=='/')/ |  n  K  x3 i. j/ s* w% m$ ?
                 return '<';4 V  ~, Y; B8 @% e# C; f
             else if(c=='(')$ i, l7 `& [3 P: u/ `
                 return '<';
: h) ?4 I- n* |             else if(c==')')
# D: J/ Q! k- R3 k8 b  e8 B, w                 return '>';
( [0 b7 }' d9 Z4 z& r+ {2 m             else ! F, ^' O& e& `8 @
                 return '>';
' N: s8 C0 Z+ N" j        case '*':+ z1 l. z% O# j8 j
        case '/':
/ B- j- k8 j0 S             if(c=='+'||c=='-')
* e& u8 K7 W) S" b, F3 b, p                 return '>';
8 ^" I1 p  e# e  _" r% D* y, q             else if(c=='*'||c=='/')8 G8 l! H( K' G0 K$ w# Q8 l
                 return '>';: R* @8 Q2 F  y2 y
             else if(c=='(')+ u! k1 _. K5 W. q. D, e
                 return '<';1 e7 s0 a3 g% y
             else if(c==')')8 `3 E4 x7 K9 T, u
                 return '>';+ O; V8 H( R( H# `% X8 ?% n
             else1 j$ W) [! F! _
                 return '>';" M6 r/ ?/ _6 Z0 i
        case '(':
5 q6 ?3 d& `4 s             if(c=='+'||c=='-')8 u/ B5 _$ _- T- y9 E& ]
                 return '<';
1 D* i4 E: O  C  t9 C             else if(c=='*'||c=='/'), Z  e6 A% f4 i0 {* ^
                 return '<';
( |/ \. q- `2 t' \3 @  r/ ?             else if(c=='(')
& v$ S. R3 ]- T& V. k                 return '<';1 ]9 J' f9 i! `& D* y
             else if(c==')')) L2 c3 v+ J, A% H. b4 e
                 return '=';
* Y2 p& F' c- s% g2 q; M, r             else
2 ?( K8 Q9 g  p! G7 r0 r                 return 'E';3 r" \5 ~1 {) D9 U6 V" h- S) g" S: \
        case ')':5 }: o+ r( C5 E( k# T
             if(c=='+'||c=='-')0 H* y7 E, U! Q- o% ]
                 return '>';, m3 Z( [# ]/ o' U$ v
             else if(c=='*'||c=='/')8 [* p  N; ~9 E1 H6 F
                 return '>';
9 _: Z' M- Q9 J$ j             else if(c=='(')
! {$ }2 D# _, L$ k- o* h) c                 return 'E';% ~" \$ R* W: H) {2 G. C
             else if(c==')')% b! E( @+ ^0 q3 ?# T) n
                 return '>';6 G8 x2 G( Y4 C2 _/ T% H
             else& `% U$ n. O! M3 u
                 return '>';" m) X. t- a& D
        case '#':
! F' u2 x) @. P% N/ j1 P             if(c=='+'||c=='-')& f0 w7 l% ?2 D0 \) t& y
                 return '<';: i+ T. W, u4 Q8 o5 v5 e
             else if(c=='*'||c=='/')
: P4 m1 O: |. I8 p9 T                 return '<';" b( p" r6 g" D5 Z+ x$ ^
             else if(c=='(')6 l0 H5 c. O5 V! e3 e
                 return '<';1 f6 O8 a7 q1 O$ F0 I
             else if(c==')')+ w* i* G6 Z) X% ]0 j* j
                 return 'E';
" t& }8 E; g8 u* g( y8 H( m             else1 w- F; B% M% B; x; @% ]
                 return '=';
5 x8 S0 I# Z9 H/ ?+ N        default:7 @. A* T) d/ M" z4 \8 C& }! p0 t. b
             break;
* b+ I5 y: e+ p; ~& G: b1 r& r    }
5 _8 ?3 Z- S" E) |    return 0;    ' |1 Z0 H% }7 r0 ~9 j; M( P
}/ m! i2 q( \5 p2 l7 K

- U; ?- I9 ^- P5 Yint isOpr(char c)9 k6 S; q3 ~7 }  j& K
{
4 L5 w3 {9 s# B9 Y9 S# B    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='); t9 _" h4 H) S8 i
        return 0;
! t# G7 W  i  O+ r    else 8 F3 ~. x) [! N" R$ h. b
        return 1;# ?; ^7 L$ k  B! Z
}
" P6 B2 N" h1 ], \. k
# Y3 U# }. I* l/ z, ~' y5 s- Cfloat operate(float x, char opr, float y)$ W" \' Z2 X0 `. a  z" z
{
0 ^& D3 b9 k  v+ B    float result;
0 F- w, b9 G) B, b3 ]% v4 Z    switch (opr)
9 G$ s8 j% N: ?  x    {& g# `3 Y& k' L( P  k
        case '+':
. X; o, J5 {  T0 r/ V             result = x + y;) q4 E, E+ ~0 o9 |
             break;1 N" J$ n) G) h9 e, `& l3 l
        case '-': $ v: v) B$ f' _- H5 t
             result = x - y;
$ U% |; a6 v2 Y9 |             break;
9 ]! O. g, a: _; l7 B% M. D& T+ F+ L* \        case '*':
: y% m; \$ z1 v4 m             result = x * y;) a1 ^) J  L( c, M/ S' @
             break;% i; J: S5 c% ~+ e
        case '/': / C' P/ f9 k" `. p, \
             if (y == 0)1 v, j) [' a% A3 u/ G* G1 a2 v3 U; z* e
             {& z& J) d2 j3 Q, _& P* X' I
                printf("Divided by zero!\n");
3 o8 U) H4 l$ y4 ?6 F4 D                return 0;& F  c( L8 z& H: J. _) `' Q
             }
+ D- ^) w, N) i/ N2 I             else5 d" |" z4 E) z; @3 M& B* M
             {* K0 l9 H4 P( |( S; E8 R/ X
                 result = x / y;
/ ]! k% i& W% r' s2 l                 break;- f, M) Z* i5 f+ W8 e+ }/ s9 K6 G
             }
. y& c3 p1 w& J       default:
& I$ P2 }& W0 W/ q) ]# O% [             printf("Bad Input.\n"); 3 l- W$ ^3 o, V: B' H2 [
             return 0;
9 M. O7 v2 p9 ]* x5 X4 A; a  L, [+ Q    }
% a- `! c+ i/ u6 g    return result;( h4 P1 p# c+ s) }+ I) A+ w
}    , ]5 U( B7 F' n; B1 P6 ?

: j, C, L+ z$ x/ @7 ?/ Vfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
6 j( C% `8 }% @5 M{! ]" c! C2 ]' W- x
    Stack optr,opnd;  Y$ S- k% T4 z! D1 N
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;3 ^) y9 {0 C& `0 {
    char c;# w6 A/ z( o7 F$ |5 Q4 v
    char buf[16];% {" O( h( Z- w% R2 \3 l9 L
    int i=0;* |- r# y3 l# ~; h$ c$ x8 c9 Z4 D8 M3 d
    4 W% s0 l1 U& [/ P$ ]% {5 H2 _
    InitStack(optr); /*用于寄存运算符*/3 Y- |. q5 |6 e4 x! ~8 z2 R' q9 c) q
    InitStack(opnd); /*用于寄存操作数和计算结果*/
6 D, ^5 h3 G# o. w: B" Q1 W5 h, ?    memset(buf,0,sizeof(buf));
! C1 \8 T! r, c1 C/ S" R" F- U   
3 H% t+ I: F: C" f    printf("Enter your expression:");. S8 e4 B2 V2 f3 _7 ?4 G0 K8 L+ h
        
# h$ t  D5 {$ U, j    opr_in.ch='#';
/ f; F6 {/ R6 g    Push(optr,opr_in); /*'#'入栈*/
$ f/ v  J' W8 ^4 l) J) q    GetTop(optr,opr_top);
4 }) o* {$ t; h- S2 Y1 O    c=getchar();- K( f, _9 h: ~' `) P: r! c3 I
    while(c!='='||opr_top.ch!='#')* U" @. k1 w" |) m; N0 C$ H
    {4 t( E/ g& g! f. J* @" |0 f: {8 m
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/6 ]/ D" C- t1 U. S
        {
8 A5 x9 C* p0 U! S            buf=c;
% m2 B0 X& U4 _+ C& u) f: }' u            i++;
' u: k' h- G1 z. i! q            c=getchar();, h8 v) b) f0 i2 V
        }0 C% S% f$ p7 E' s1 z" J' G
        else /*是运算符*/+ y% ~. D' H* _/ n3 d5 d) l
        {
" _8 ^$ I. N! D4 i+ S2 A9 X) l) M            buf='\0';. S5 f) b3 j1 w3 m
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/, k9 R8 r7 \: i7 P9 r9 t! U3 {
            {
3 W/ |* q+ Z/ ^                 opn_in.data=(float)atof(buf);
5 K3 o& L2 B( r! Y2 G2 S                 Push(opnd,opn_in);/ `6 \( n, @" ^. I" [
                 printf("opnd入栈:[%f]\n",opn_in.data);6 Q, u# V& {! p) n7 u
                 i=0;4 V' B8 p) q6 {% s& U
                 memset(buf,0,sizeof(buf));
2 S+ E; |* t8 O( h% H0 {0 n            }( P/ Z8 \+ `6 b3 t% \
            opr_in.ch=c;
- _; x, U. M9 s  {1 r0 P            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
) j  o4 @, x' g+ r: E4 j* N            {; g/ W& Y0 w0 W% D. r: y
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
/ z7 Q$ b0 S' V& I  h                     Push(optr,opr_in);, ^4 w* y- C. n: T) s) t
                     printf("optr入栈:[%c]\n",opr_in.ch);
3 k: p- a) `# I" ]  g! h4 W                     c=getchar();
1 o0 Z" m8 m8 D; `1 g0 ]  s5 q                     break;
9 G. [& H9 J& |( _2 _                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
: B- H2 l3 O2 o/ |                     Pop(optr,e);
6 y; s+ D2 r4 N; h/ G                     printf("optr出栈:去掉括号\n");
1 v; K* Q3 g# s- Q5 ?9 @: a1 U$ ^( J+ O                     c=getchar();
, M$ l! A& ]1 O1 D; b/ U                     break;
2 P3 H) q5 V: d3 V! M2 v5 w7 H) a                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/: @% u' v( P7 @4 S
                     Pop(optr,opr_t);6 H  ^: T  t+ B3 j' y2 E) l+ n" B
                     printf("optr出栈:[%c]\n",opr_t.ch);5 l6 n3 }7 V( o) S3 I3 w. A: ]
                     if(Pop(opnd,b)<0)# d9 a  q$ |: A! u
                     {  x9 I7 w( _$ u7 I+ `' A
                         printf("Bad Input!\n");
/ d! Q* V% Z( `2 U* B2 G- K                         fflush(stdin);
8 O6 D) w  B+ q, n- h                         return -1;+ l4 t% Z  t2 F0 b' ?; h6 S' y& Y
                     }5 E) L, @1 Z) ^% T* s: W
                     printf("opnd出栈:[%f]\n",b.data);% r0 S" k1 [1 O
                     if(Pop(opnd,a)<0)
. h- `& Q% y: n) C9 d8 T! ?                     {
& ~6 d- o! N3 ]& k0 y' ^* i4 X                         printf("Bad Input!\n");
. t' V5 M& D3 I. g; m                         fflush(stdin);% j5 d6 i. o% K2 n
                         return -1;- U5 I4 K4 f5 I! R/ N2 M
                     }
. n5 v6 W1 G6 H+ z2 C                     printf("opnd出栈:[%f]\n",a.data);& q8 V1 g: v) E5 ]) N
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/; u: Y8 v: C, r0 F6 E* O  |" r- [
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
% u$ ?4 Q" i- ~* g/ F7 E7 F* t                     printf("结果入栈:[%f]\n",opn_tmp.data);
$ o) d( `  Z) q4 |* N2 [: J                     break;
. O" U# c3 K! e' s0 j2 }" {            }
* r+ I8 N9 @0 h2 R5 s/ n        }; q- N* y) ]3 ^" `+ @
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                : l+ ]  K! M, u9 j5 d: ~* p, `9 k  p
    }
, B3 j9 e  u! t! r    GetTop(opnd,opn_tmp);( s8 x# \5 u5 q6 X7 T. N
    DestroyStack(optr);  b+ \% @7 r$ P5 T# j' T
    DestroyStack(opnd);
) l7 @& C, y) P. `: u6 L) d- q4 w    return opn_tmp.data;  [! x2 E. J* W7 h+ v
}$ |/ Q8 h9 ?# [/ Z# `* s

3 n: T: h% ~# Y6 Achar *killzero(char *res,float result)
1 o! G+ h8 V* h2 P) l{2 _- y: v- t& ]1 l, m
    int i;) d' g5 y- m- J+ G  n

1 [! @, T7 g+ R. a  E6 r4 ]    sprintf(res,"%f",result);2 i5 @# D9 U$ x+ V) W8 r* |
    i=(int)strlen(res)-1;
5 \' K/ c  Y+ ~5 U8 y) {    while(i&&res=='0')
* s  X9 T1 [2 @, v4 L6 _4 ^1 e' L    {. c0 s4 m* P! x' {+ T
        res='\0';
" G% p- H9 l$ V5 L        i--;
5 U; t8 M' I. o3 T    }0 n+ w  J7 B$ j5 H; ]
    if(res=='.')
! R0 P9 Q9 y' r        res='\0';# Q5 I. |! y7 W% q: |
    return res;) d! m/ B& u# ^, w) r
}& k; X! K3 C1 y7 N2 f
" r. ]/ I: N! r
int main()0 b/ m9 \% q7 p. W1 ^
{
, L8 m+ i9 t8 o" s7 X    char ch;
; t: A( v9 g# k7 H8 o2 Z8 U    char res[64];
# @# _& A: f6 ^0 n0 H- M    float result;
" V) L, c  a* F    while(1)
" J2 K6 T5 j: ^5 E, |  \% i    {9 w0 O3 l; r3 Z1 @6 F% J6 J! i- N
        result=compute();
" z, V& e* M9 R) h+ g: n% ]        printf("\nThe result is:%s\n",killzero(res,result));
9 q9 y* x* R( O6 k- }! ~) u        printf("Do you want to continue(y/n)?:") ;- S$ }1 O2 D  e( f' }; o
        ch=getch();
7 n- N( P$ e2 ^7 l) i  a) i3 P* y        putchar(ch);
1 J& ?& R2 G) }        if(ch=='n'||ch=='N')( ^6 [2 H1 n, G9 n) t0 f% E' F4 N7 Z3 P0 I
            break;! L" O& A2 a1 n; O" z5 g
        else7 D% }4 o* i3 B$ ?
            system("cls");6 X/ \4 Z; _$ @9 M4 O7 J
    }1 T4 z6 ^$ m- [# O: {
    return 0;1 z$ a+ @: S0 l7 Z
}

9 `- n5 o& Z  K0 k& M0 T2 X' r- q8 @9 N- n
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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