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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.* N, a$ J( j# }7 C
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=) A" m0 w4 \& B- m
/**************表达式计算器************/
9 \6 t8 k( J, X0 g  S#include <stdio.h>
. H. A8 M* `8 R) v+ o) E5 B$ m#include <stdlib.h>
2 L9 W6 p% w0 t7 [/ a#include <string.h>
+ C  J4 j4 f9 o: G#include <conio.h>) g$ s$ J1 p5 S
#include <malloc.h>( t: {1 m. j5 @: R/ r

, H3 {$ d- ]0 C4 g#define STACK_SIZE 100
* p3 {9 C9 v* m2 F, t# [#define APPEND_SIZE 102 S! e8 a; ^" P7 T* B

0 t1 ^1 E; M* D  Q/ F  _struct SNode{0 F; M- Y  J/ A; [4 ^# s
    float data; /*存放操作数或者计算结果*/
+ u+ M- \+ l2 Q0 S3 y$ @2 Q8 `    char ch; /*存放运算符*/# c( n3 Y6 V, |' `8 a4 L( o
};
& r$ o1 T% x% d4 f8 l, q0 {/ Q: D3 t' f; A4 D& U
struct Stack{) A8 p. v5 U( Y& r: ]
    SNode *top;
+ I8 J/ J6 Y6 {+ g3 v5 q3 v  t% D    SNode *base;2 d' W8 m# ]+ Q3 m0 k, M8 P5 L' ]
    int size;
3 D+ ]* I. f9 U};
9 R6 f8 F) H; [, ]. I% V* f4 _! j6 q! ?: V" U& B( T. ]4 P, E* ]
/*栈操作函数*/
  Z' I& v0 K7 l) G4 i$ H3 r/ ]int InitStack(Stack &S); /*创建栈*/
: m( B9 K7 C: X- i  F& |* {9 S' E2 Eint DestroyStack(Stack &S); /*销毁栈*/
$ {. C4 a& J" u7 u2 }- e: Q  ]int ClearStack(Stack &S); /*清空栈*/
  G! j# [. |) |3 M, f% J) bint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
; w; X% G% t4 V- Q% I0 S% U4 b9 ?& cint Push(Stack &S,SNode e); /*将结点e压入栈*/5 A) Q6 e8 o4 _9 E
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
" t2 [% D$ t  Q6 M/ t8 z4 p9 ^6 K9 h3 T
/*表达式计算器相关函数*/( u* z# J2 C9 O* \# t. O- M
char get_precede(char s,char c); /*判断运算符s和c的优先级*/8 e% }& W" o6 z1 h( b
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/& S' ^0 u: w0 R/ H. z& @
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
( M( n# F$ h3 kfloat compute(); /*表达式结算器主函数*/
6 D0 y2 t4 m- X' z5 X9 Gchar *killzero(float result); /*去掉结果后面的0*/ ( E5 G) {( u$ x2 Z
8 Y+ x7 N( h5 a1 e; a/ U5 d
int InitStack(Stack &S)
6 V! G5 l" b/ H0 |1 Z" b7 d& ~{( k  a$ A3 G- |1 n3 Q' L
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));8 O5 S" ~+ u' W# g: I
    if(S.base==NULL)
: j; [; I2 t4 L& B9 ~    {. @) X8 s: ~! G: P
        printf("动态分配内存失败!");5 ?/ f; a. c4 u& x
        return -1;
0 z5 w( m6 |: A( @- c* ]    }( j% G0 u- J; B
    S.top=S.base;: f" i3 l( d8 [) Q+ Q% ^
    S.size=STACK_SIZE;% @( _" ]5 K- @2 Y4 g/ g
    return 0;" t' X- m5 @9 s/ {" H
}
  A* b! v( |2 s. X* \, P5 x! t2 n' P" v. [5 y$ G; w
int DestroyStack(Stack &S)
: m" R7 h2 N" u+ l2 A$ g{' S# f  @2 H2 z& I' I- H% K/ i' O
    free(S.base);; R/ H4 V/ T6 [7 ~' C
    return 0;; I8 I3 \# b7 o# T9 `- \: p
}
) B1 Z" u6 |2 R: e8 \0 W# m: g* S, t) _4 a
int ClearStack(Stack &S)
# L" S7 s% B# m8 o# I{' H' w; P5 e: d. ?& ]% a
    S.top=S.base;
" C5 ~3 D" v: [  n& m9 y    return 0;
6 R* j+ P3 p% u* ^}0 f, a% h& Y/ H) v; \& l2 q8 N
) ~2 s4 `$ `7 N+ y3 ~7 u# V( v
int GetTop(Stack S,SNode &e)
/ d" f' ~! S0 x{5 Y; o0 a, K: U1 U* u6 P. d
    if(S.top==S.base)& e7 P/ ?0 @$ t- q% O0 D8 Z/ R" Y
    {
" p- R% x' B( j& y! D! x2 g& c' h! n        printf("栈以为空!");
, A% [# f9 e+ M  |        return -1;6 H. R2 L# J: q0 x9 `
    }
. k* f% \9 b8 \+ V! w& K    e=*(S.top-1);
6 h$ T: s6 M2 l6 j    return 0;
' x0 Z0 [+ v+ m. ^& Z+ Z3 r0 P}
+ c" p5 G4 _; q' t, I8 N4 A4 Y3 M
3 |- C4 V/ Q  Gint Push(Stack &S,SNode e)& t1 Q' s0 |) k. i
{
' u0 j+ T) j& [0 I! c+ a5 l    if(S.top-S.base>=S.size)
& S& J0 G. s# q  i1 w3 |0 Z    {
: m2 d* c* q: c2 p8 @% b        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));# }) W' n! b% g4 B# q
        if(S.base==NULL)& }, S0 I9 M& H* d$ y
        {
* W0 `1 `& [( M            printf("动态分配内存失败!");' X; }" y7 q) Q# D
            return -1;
, Z8 Z3 _& ^* H# {        }
* }! G# X  C8 e$ d, J/ [9 o        S.top=S.base+S.size;
, P. Q( d* M$ w1 p  F( J5 D        S.size+=APPEND_SIZE;
3 B4 S% j/ B9 `    }
( s" ?& Z$ D7 j+ v+ ~8 h  ]    *S.top=e;
# M9 }. A% }9 m    S.top++;/ @) z) c$ K1 ?, H3 _( B6 w2 R' T
    return 0;
+ P: ~4 u3 D! ~6 m}! O2 D* c& i2 j8 n
& M: X& m2 s5 p5 w# _3 p5 O& Y
int Pop(Stack &S,SNode &e); c# _, ^9 K) c
{
! ~% y4 H  n* I2 P% c    if(S.top==S.base)
5 h+ k8 m; e) ]    {
# C! C4 e, m; P! U# ~1 _* A6 k        printf("栈为空!");
- t8 m: |, I! c. ]        return -1;
! L1 s! K' c. P* n% P& M$ |    }7 ]. g0 G. S9 K3 ^$ @
    e=*(S.top-1);
* x/ H. N) T& G: J. s$ K5 L    S.top--;  u+ x, x5 y! G6 z+ o  e  J6 ]
    return 0;
- R) {! ~) b  h2 B+ ~' f* I}
# b- l6 c' k8 E" l5 w
, n# M, s& ~- ]6 kchar get_precede(char s,char c)# B4 t$ s/ K* z
{
' b  t! y; u2 M$ @, L& _, i& i    switch(s)
2 Q- Z+ G  T2 H. Z* p    {6 @) F0 x8 [/ c' w; N( b
        case '+':                 
+ h1 u( t2 C; S2 w! v        case '-':
0 K' J% F0 \! ?' z" K3 m             if(c=='+'||c=='-')9 w+ z% |1 B+ b( z- B
                 return '>';
! d# K8 w( K) V7 Y; ?  S- h             else if(c=='*'||c=='/'). d  M  K& L3 d# I
                 return '<';. v: ~) K# ?( T) ~
             else if(c=='(')
" ~7 Y$ [1 O- x( l7 E* b- l                 return '<';
. _/ z: H/ n) M& w             else if(c==')')
! ?  f( K0 [1 h2 ?# L: j                 return '>';" t! m, A, k% S  ~0 K2 c5 p
             else # h6 d# z* C* }9 V
                 return '>';
. ?6 d; @# V) f+ |4 ~1 u        case '*':
" {* B7 e  J7 w1 q        case '/':  `7 j, u; L7 q; L- f4 x* K8 c, [" j
             if(c=='+'||c=='-')
, ^6 N9 F& k, u                 return '>';$ X( h( G. M7 |2 i
             else if(c=='*'||c=='/')0 v+ ~* _0 I. |7 K) W. Y, w0 H
                 return '>';! J5 z3 M  T9 Y4 S; q+ n0 W
             else if(c=='(')2 {2 v5 B7 F$ X2 r/ o( ]; f- c
                 return '<';9 T5 o( U( X8 T6 Z) F
             else if(c==')'): J3 D5 |0 ~- _2 t( v
                 return '>';
2 X  I2 d5 N9 O6 c6 ^. N* G             else, O2 |/ H5 W" q7 N( ^- C# O% X
                 return '>';
/ e* D5 G- L1 i( P7 l        case '(':
# r7 x3 `4 Y* v             if(c=='+'||c=='-')
* A) D! J+ t% n' Q% M- K7 Z                 return '<';
3 b5 m/ K6 ?+ w. k( H             else if(c=='*'||c=='/')
5 h1 Z( r% F4 @& k' s                 return '<';
+ T) d5 B# S# Y             else if(c=='(')5 G6 d4 p- J/ S4 z) o
                 return '<';- ?$ F2 \: _6 }! v/ q7 a1 l1 @: d
             else if(c==')'); w% g0 }( F( l1 _) t
                 return '=';$ p; R: ?5 [% N5 T* X3 u
             else1 `* n8 x) ]4 x% }3 ~" z" ]
                 return 'E';: P2 q# M) B1 l. X. f# H
        case ')':+ a3 K3 F( q- S' B/ ^
             if(c=='+'||c=='-')- B8 [) F; X& s9 ?8 I
                 return '>';
! a( F3 |  J) R7 r8 {1 s             else if(c=='*'||c=='/')/ z7 d4 {" ]* f& \" B) {
                 return '>';
: n3 T& x9 G9 V( [1 l5 o9 v             else if(c=='(')
4 Z0 ~! k6 y# L4 j5 I- d: r* y                 return 'E';% X8 B; m6 ?2 l7 f, v
             else if(c==')')# }0 j& _2 }7 W: B# n
                 return '>';$ p- \6 e2 g5 ~4 q* W
             else
! ]9 J  @7 Q- {; w                 return '>';, `4 u* o, k+ W- j7 I# ?) r5 r$ }
        case '#':# ?& K2 v$ y: w3 M
             if(c=='+'||c=='-')- t4 @& o( l. X( s
                 return '<';
6 A) G2 E* k0 x" r             else if(c=='*'||c=='/')/ s) S1 g0 t, ?9 |6 e3 M6 U
                 return '<';
0 n- F4 Y+ D3 Z" u; ~+ ]             else if(c=='(')# [- B6 l) T3 A" Z, F
                 return '<';9 M1 Q: L6 X% e6 `5 l
             else if(c==')')0 t' n' |. u- P: [# o
                 return 'E';3 r3 N9 a: g6 F
             else8 v5 {. V: T' E& d+ Q
                 return '=';+ t% T# @! O! ^! o! m- Q0 p( W
        default:+ [/ \+ t5 U" c0 F( R" {
             break;4 U6 Q6 k% j% r& ^1 b; L7 Z9 Q
    }5 n- _: ?( _3 S) ]  }/ Q
    return 0;   
1 F3 N$ g9 m4 `& c8 ~6 p$ K}
1 n2 J' ?/ p7 k2 g$ Y: {& \7 j- o
int isOpr(char c)  Y8 T$ K( _! k' M. H
{  Y. C1 l7 a( R( h0 `: x' O0 }
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
4 W5 G- l3 i$ `# |. x% f        return 0;. E. g+ n2 S+ m( k) |8 N" X2 C
    else - r+ Z8 c4 m. s. Z
        return 1;& j! I8 \8 x) A5 X. }( @1 F
}
0 l7 V2 z3 q, o4 }" }' ^2 A/ _+ g( V8 t9 O
float operate(float x, char opr, float y)
3 [8 R; E# j) U3 ~2 E& S5 B{
2 H7 l4 \$ l+ J: H2 A; S4 l. ^9 E    float result;2 t) l* F: p5 Y5 C
    switch (opr)
' K1 }' e( m: c( }    {
4 A9 E: a1 z) N9 n+ h        case '+': $ r! S4 B# A. {
             result = x + y;
7 o8 l: i: V. C8 m" g+ Y5 u             break;- ]7 b5 p) D! r9 J6 m
        case '-':
& o# ~* M# W. D) g  x9 I             result = x - y;
; T( q/ U% v7 x; A             break;, X6 _" P0 p$ a$ I& Y
        case '*':
0 D( @! G' E8 [' [' E5 J# t             result = x * y;) {# p% p1 f# H# n2 M$ p* X
             break;4 r% f! m# q: c4 L' z
        case '/': 0 q6 a- Z- l; D% ^# j; S
             if (y == 0)
8 W" n; {- `! Q: F! l( T9 p- I$ U             {
; V* H/ O' h! \( {                printf("Divided by zero!\n");
4 [% Y! n* J) j                return 0;# o; u4 A" X3 ?: X6 _7 {+ I
             }
0 L3 ^, I9 x) F: S. p( M             else
+ Q8 J# g8 w7 K9 H8 R  W. \             {
6 x% |5 a, \5 ?                 result = x / y;% s$ V/ o; O$ H6 d8 d
                 break;- A) E& o* I7 `* b
             }0 y! R; ^$ S1 N7 \) l
       default: 4 U( B& N( |6 L5 X& d, S
             printf("Bad Input.\n"); + o  x. Z- C8 E8 X) H/ j/ C' K
             return 0;
1 ~" o# e  r% k: o( J. u5 u6 a    }+ h( z6 u* H: q* u0 S
    return result;
1 B$ {# U( b* D3 H3 a- P}   
9 m6 r% X1 Z9 X3 E0 i2 q2 p1 q( w0 ~' i5 w0 f- O8 z. i: L4 k8 h: H
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
1 g. K9 A/ d: |& V, S{( R* A, U' [( H3 p1 \  _; m
    Stack optr,opnd;
7 w5 s* N. a* x; {, V; [9 g% W    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
5 t, D. i) \% p5 ]0 Z  F* a    char c;5 @: d. M0 a. u- @3 \$ R5 |
    char buf[16];
# h' H" s/ F" W* t* k    int i=0;- C1 L* G3 k7 [7 x
   
* `) a( ]2 f( _" `    InitStack(optr); /*用于寄存运算符*/9 t4 y( L2 \2 l& ]; }
    InitStack(opnd); /*用于寄存操作数和计算结果*/: Q1 u5 A; o% m# n) E! ]% @- Q. ~
    memset(buf,0,sizeof(buf));
* F( ?) V: q. B1 j" f   
7 v* c$ V! Z6 B+ V    printf("Enter your expression:");5 u# I$ P7 A" H' T( L
          d# O/ V& A2 l8 B
    opr_in.ch='#';8 S5 c9 s  F; {' q% @
    Push(optr,opr_in); /*'#'入栈*/& R) R7 L" D; [  p' H) h
    GetTop(optr,opr_top);5 [' R# M- F5 F4 s0 K8 @7 u
    c=getchar();
8 P5 }. s& H5 ?) r5 ~. e! A7 d    while(c!='='||opr_top.ch!='#')
+ a0 w! c+ [! N& G7 C3 ~; C$ m, |    {; Q! z1 z3 X7 b% V2 m1 {
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/3 h* c: e  f7 M2 @5 J8 y$ ^
        {
  g8 }3 m) F, }7 B. |1 k) P            buf=c;
# V' k) ~2 b6 r            i++;
* K+ V2 R) ^/ f- ]( \' H, O            c=getchar();$ Q/ n& Q# Q9 I& p  A
        }
, B/ `- `) |, A& E4 j2 B: R  M        else /*是运算符*/
; M: I, d8 g3 g) F+ \        {
* j; }- t. [6 s1 p6 P% d* r            buf='\0';
8 g# m, @1 m: ~0 K            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/5 y7 i& ?7 \) d% s
            {4 ?1 z7 W& W8 u6 q+ V) {6 Z9 j0 K0 Y
                 opn_in.data=(float)atof(buf);
/ q3 Q+ Q4 L$ r6 {3 e2 {/ g% C                 Push(opnd,opn_in);
$ i# u, S, t' o( {/ K3 C" K                 printf("opnd入栈:[%f]\n",opn_in.data);" B  b2 T) Y6 R" D$ ?* r
                 i=0;* b0 p7 ~& i, b$ U1 P
                 memset(buf,0,sizeof(buf));
' z7 z2 l" Q( F) p+ @9 M9 b# I            }+ e' v2 U, s' r8 }: G  b  T
            opr_in.ch=c;0 Z8 Z" `3 b: k1 t5 v  \
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/+ f0 i9 O  D6 r% Z+ c
            {; Q. y- s" |2 O: e* V, }2 e% Z3 P) w
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
" I. D* `9 r  G' {8 ?                     Push(optr,opr_in);
. V" L/ }( S/ j; q' }- H0 ~8 O                     printf("optr入栈:[%c]\n",opr_in.ch);
! w$ X+ v( @/ M/ Q9 V& o                     c=getchar();" e8 x7 W& A0 D7 Q9 `2 @+ P
                     break;
: ^2 e: V6 F8 {- w% Z                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
- H6 D, p/ j% e5 w5 M8 s* X                     Pop(optr,e);! S/ b( W7 h- U5 Y0 U# B2 J
                     printf("optr出栈:去掉括号\n");
2 U" W' z* A5 ]! L4 x                     c=getchar();
6 q( E* {/ c: P                     break;0 ^' m  k, a1 I$ L1 W
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/$ g8 D" r, h* ?6 I1 U
                     Pop(optr,opr_t);
: F/ s" K7 Z. P( b                     printf("optr出栈:[%c]\n",opr_t.ch);, [* l4 l( Q8 M) \# |
                     if(Pop(opnd,b)<0)
5 k* S9 K4 @# O) I4 }) g                     {
# H. P- m$ g9 ?: p                         printf("Bad Input!\n");4 i' g/ `1 K* [8 K$ g# Y( z+ V  G
                         fflush(stdin);4 T) P& x8 Y6 y2 v( h: m- D; c
                         return -1;
, w, V9 b3 [+ ?- n4 h                     }
* M3 f' \( J( u; l& W/ y                     printf("opnd出栈:[%f]\n",b.data);( T6 D; s$ V$ _5 \( E" L
                     if(Pop(opnd,a)<0)
- l# C( o- Y) k                     {
; X) p0 C+ Q7 g/ X2 x1 |                         printf("Bad Input!\n");
# d" `3 J% S  X2 L+ G; x$ A, {                         fflush(stdin);
+ m% ?( B- n: T) j                         return -1;
3 P/ s; t/ n& g" T' Q$ {" w                     }! K6 M% F7 o$ |& M  E, G/ H
                     printf("opnd出栈:[%f]\n",a.data);& @, G  H8 i* |0 r# C% v* i: J; {
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
2 d1 o3 k3 A5 {, F' r5 F2 e; ~                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/9 x- v& W" w8 ^- r" V1 H
                     printf("结果入栈:[%f]\n",opn_tmp.data);! F$ I. I: p6 I) U7 x0 O  w( s2 m
                     break;
: _9 E4 w" f2 ]( A% x! W4 ]            }
/ U3 l: }2 L, e/ r/ t3 k        }! G7 }5 {9 e) r
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
0 q- e# o/ g9 Q    }& m; i3 _2 [) ~6 e4 n* x
    GetTop(opnd,opn_tmp);
& z5 {' L: t& T    DestroyStack(optr);
* h8 `) }7 |7 P$ y+ r" e+ r9 w    DestroyStack(opnd);& G8 b5 T( \4 r. Y6 D
    return opn_tmp.data;. P4 s, c9 P) D+ I- j+ c
}
. g1 S6 S) F5 _' B* L' x& k2 O, I
6 G# S8 E6 [4 b9 Uchar *killzero(char *res,float result)( M5 G2 z, m/ R* R  [
{! y4 H1 k2 Q9 N/ G/ \! u4 Z( T4 E
    int i;" m9 ?' {, B" s" I1 i0 M1 p3 o

* V& ]/ B$ H( @! u7 x/ x    sprintf(res,"%f",result);! P$ m2 p: M7 u/ m
    i=(int)strlen(res)-1;
( v6 R( i, D5 S! @! ?3 C# K% Q, X    while(i&&res=='0')
" ]8 V+ p# D. }6 l& a    {
8 }0 n9 h% x3 i7 D1 Z. P9 b1 T; E- y7 O        res='\0';
/ b. p) ?$ }/ z8 l; U        i--;
. L! R: B1 U7 i& J    }; L" d! e: Y$ z, \9 m$ y
    if(res=='.')
# D3 o* m' F5 d. m, Z  j  a  d        res='\0';
6 c7 M" j- W- _    return res;
4 u. |" f+ X; ~' s  w. e3 I$ U3 m# z}
! L8 ]# [% L7 r
) C. P" [5 f! n& Y( w) gint main()
  ]" U; b: i; v8 H, R5 H{
7 o; f4 D  k9 ~/ ^9 f; @2 Z) u1 p    char ch;- h# m  p. Q# ^: t9 I+ M: u
    char res[64];
) b7 `- B4 P" S( L  q( a! I8 L    float result;
+ }. q4 W8 F) e3 ?4 X, Z2 r    while(1)- K* s/ K% U/ h, ?% w* }
    {
, c& F/ T1 N% j: `1 `        result=compute();
4 D( T3 ]" }) \/ b: h        printf("\nThe result is:%s\n",killzero(res,result));
* y" ?. T- h+ G8 D2 Y8 I        printf("Do you want to continue(y/n)?:") ;
7 b% k6 F. @% [4 v) A        ch=getch();
: f8 E3 h8 k6 K9 D9 L8 [; j) \( t$ G        putchar(ch);
8 p! Q2 Z9 F8 [$ O        if(ch=='n'||ch=='N')
$ G; E! x- ~4 U5 e/ `* q            break;
5 q  S* [/ N6 B4 U% @! s; b        else
' w2 P# M, w. k0 }2 M+ i            system("cls");& m( Q$ w; Q/ {$ F0 f
    }
, `$ Y" G' T6 }% x, x9 X6 g) a    return 0;- `7 S* t3 S& E
}

$ G/ M# c' {. h3 E1 t! Z( W5 y7 |3 ~) G/ n  e5 ~
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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