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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
- N4 y6 ^  ]+ b5 u程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=. G. \0 h, j7 @2 A3 P7 c
/**************表达式计算器************/
2 ~8 Y+ L2 A! _#include <stdio.h>
% }# A! k( F" S# J2 f8 ~#include <stdlib.h>
' i2 X* ]4 o  e0 O4 _8 e+ Q- \#include <string.h>
$ n7 V" Z/ o( ?4 c, j! `3 R1 N#include <conio.h>" P5 ^: m; i& q8 x8 f# J
#include <malloc.h>: |' ?( g- \9 ]- X. `9 H
3 H' c" |' P- `& ]7 _* m; a
#define STACK_SIZE 100
  ?; W# _' ^7 E#define APPEND_SIZE 106 z! ^- m- e' [( w9 d

" P3 f, R9 b7 gstruct SNode{# m# S# [2 h4 O' \5 Z) e1 a0 P
    float data; /*存放操作数或者计算结果*/
) H2 ~9 v; `- G$ \9 S) R* L    char ch; /*存放运算符*/
9 W0 G3 f* y1 v};' ?- G& j6 e" A

/ W, Z% r3 m* {8 ]struct Stack{; Z! `0 j& D* E/ o  V
    SNode *top;4 I+ m9 ?# q. y
    SNode *base;
+ M) y* w, n2 T- ]2 V. M* y    int size;
8 i; N  I7 @& O$ P/ P: F/ t6 z: K};2 K$ M9 M4 G4 F3 x% |( W

' t6 @3 s8 E9 T$ D2 J/*栈操作函数*/5 }+ R0 L+ A; l( m4 {: t
int InitStack(Stack &S); /*创建栈*/: W5 I) W/ Q0 v2 C* N, l' {- z% a
int DestroyStack(Stack &S); /*销毁栈*/! f2 h- R+ c7 P, h, V$ I! h
int ClearStack(Stack &S); /*清空栈*/% v2 l. a6 b* u# G' l5 r
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
8 D( `. ~  B4 O8 Y4 |- i* R/ \int Push(Stack &S,SNode e); /*将结点e压入栈*/0 ?  n9 ~5 H) y4 c) d
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/2 s) ?7 N% d2 B: M/ T7 i/ j  z
% q$ v! R" r6 z+ [5 `1 l
/*表达式计算器相关函数*/3 E, \- Z' g; R" ]
char get_precede(char s,char c); /*判断运算符s和c的优先级*/. K7 i+ I3 L0 D- `
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
( u' W; z: S9 ^( e0 ]: ]' J$ {float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/( q$ g& q4 a7 |# t4 L: L+ I
float compute(); /*表达式结算器主函数*/! `9 `# l' ^4 ?8 f" Q
char *killzero(float result); /*去掉结果后面的0*/ 9 J1 W6 P" w7 o; V& ]

7 O% N3 s' S- ^& g/ Jint InitStack(Stack &S)
0 _" ?+ M$ e' M0 e% @9 P( a{5 }" c5 Q% |  t" `
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));( K! ?  M2 P$ M; \2 n
    if(S.base==NULL)
  w* m, E4 B2 ^, l0 U* E    {
0 K5 R2 F1 `  @, D        printf("动态分配内存失败!");
+ N. E" o9 `. M' [! m$ M        return -1;; I& W) G, I1 j  t
    }
5 \7 W: U- H& E$ s0 q8 C    S.top=S.base;6 U* t5 |; Y& M2 N* _
    S.size=STACK_SIZE;
3 ^2 X( m. ?& L  E    return 0;
) D" ?1 e$ t  A  d8 n4 m}; ~7 L0 Y' z$ w8 W* t1 L9 k& C

. y. O4 f1 J# z5 mint DestroyStack(Stack &S), r7 C. o) P: z/ Y0 p: Y
{
9 F2 }9 v% _6 m6 N    free(S.base);! T/ J* I  ^- U" S+ Q; |# O
    return 0;
" J8 Z* v. m8 {  G5 q  i" {( C4 l}6 y: f3 W. m4 k% }+ j
8 S) F) `5 M8 [
int ClearStack(Stack &S)) ]% s/ B% x/ f% G
{
6 Z7 H9 r- X% K' A/ E; n( Z    S.top=S.base;9 ^& g8 B1 c+ O, G
    return 0;
6 }# V4 l: V" p# g4 V0 J}
$ P* @+ \% j3 E) v1 ?/ n3 a' s* ?5 S+ i0 B8 D2 A
int GetTop(Stack S,SNode &e)
" O! S( E9 _* Y{& p" j% C6 v4 \+ n+ W
    if(S.top==S.base)( @" b! K5 F' U* b, i: |
    {6 S4 x  j1 N# s' T" v
        printf("栈以为空!");8 M/ \1 k8 W; g# R6 M6 e6 V" I
        return -1;: t2 h  M* m3 D; i* N
    }' A/ P) |2 o8 c
    e=*(S.top-1);
. N9 G+ {0 V! q8 ]    return 0;
  x+ v" N5 v1 _3 U" A}, f4 w% Z" l& [. h& Y0 c" p! x# C/ Z
: S1 z! L! u/ }/ i! o& o* K* _5 p1 s% n( n, W
int Push(Stack &S,SNode e), f0 C) n9 e" E, ~4 V3 [
{7 O6 M$ d( S# K6 j
    if(S.top-S.base>=S.size)  j2 K2 k  M( Y8 @. C/ P" z( J1 h
    {
4 B+ s3 g3 G& M- ?9 k/ }: P0 e        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));  o8 M" M% {5 n. v. |( s
        if(S.base==NULL)# w0 l4 _% [' k7 j: c$ k* o
        {, E4 p. ^4 P2 ?/ x
            printf("动态分配内存失败!");/ \3 [+ ^" V( s" q- B
            return -1;
8 V/ Y4 P7 M2 p  E0 T/ w; z        }3 v  D$ ~, T6 k7 V
        S.top=S.base+S.size;5 {7 D' E) H, a
        S.size+=APPEND_SIZE;7 b$ I- O. t2 s$ @% m2 {
    }
9 G7 z: v8 Q  u/ J    *S.top=e;
. _0 e2 a$ {# X9 ~6 W9 V4 x5 i  n  G    S.top++;- C0 C( H; P( L) Z
    return 0;
, F# P$ I( H- Z( S4 B}
+ u8 C( A8 d3 I, E. Z+ ^7 T$ t! j8 L5 x& f- C# G8 q
int Pop(Stack &S,SNode &e)
$ T' Z* T; }7 ~( Z{; u# }3 I+ x# R1 ]
    if(S.top==S.base)! t$ C* j4 @; v6 f+ K# n% X
    {
$ T0 O+ P& y9 P/ V        printf("栈为空!");
: w2 Y: K( S7 s% `9 M. e        return -1;
# X' M8 ?  @. a: g" q    }6 `0 T6 J8 b% Q# ]( z
    e=*(S.top-1);- r8 F0 e# a5 N) Y5 z& T# p
    S.top--;
) _+ g2 w3 ~% p. {7 |2 P* i* y    return 0;
- \: l* {1 |; z/ h0 I6 N}/ A3 g: ^8 b( N8 L; X

* A! H& `# p* Jchar get_precede(char s,char c)" W* f. p6 v. g% ?, Q
{: ~! \: P- I) F5 C. ?
    switch(s)
7 [& S; f! n9 ^' l; z    {, G4 T/ d3 s9 p2 n
        case '+':                 
* _1 l4 [( u9 c' f" y) N* O0 Q        case '-':
' E. @7 R' N$ o/ S& G+ E6 J             if(c=='+'||c=='-')
) T- c/ r& ~3 A/ ^% [8 h# E: w                 return '>';, e0 c: |1 r' O- F% g7 b
             else if(c=='*'||c=='/')- u$ i/ R, C; Q+ ]) p
                 return '<';& L4 `4 ?9 P' p
             else if(c=='('), J; U$ ?+ M1 d9 F( F
                 return '<';" n! o# l+ c- s( N( q
             else if(c==')')
* M) P1 e. u6 n) S# |                 return '>';1 s+ X6 v# ~& p$ z' ^
             else 0 G9 o1 q; w0 R+ e3 |( M
                 return '>';& ^+ B3 o$ G- K8 N& c1 j
        case '*':
/ x$ v2 p9 F/ f1 p, t6 P        case '/':& u" Q2 N+ a3 m. y% I& Z
             if(c=='+'||c=='-')+ {) G( E' F' `, I# I! x4 U3 i
                 return '>';
4 W  F) f! t1 ^/ Q             else if(c=='*'||c=='/')
+ [# O% t" N- Y! F( T0 l6 C4 A                 return '>';' P5 u) c6 Z: t
             else if(c=='(')
2 |5 s- g: d1 @) _' N8 C                 return '<';7 s6 I8 z- Y) O9 ?0 ^4 M; T% a
             else if(c==')'), ?/ @: f5 H: `, k8 Q4 ~
                 return '>';( g' |+ K1 C; x4 ]1 {/ x# z  I
             else
. D( M9 e8 c& s' a                 return '>';9 W, i- R2 }! s$ g3 B
        case '(':. \3 ?2 q5 R( }1 q
             if(c=='+'||c=='-')  }2 T- u$ Z0 A# Y
                 return '<';
; @7 k) W8 a1 A4 T0 y$ B             else if(c=='*'||c=='/')+ ~7 R& I! T" h4 j( F- H
                 return '<';
: U" [; d  C3 k, f$ h1 z( }  s             else if(c=='(')5 Q7 B0 g. N, ^8 Q
                 return '<';
' R3 ?& b. t! P1 w1 t+ p  n0 |5 k             else if(c==')')! G5 k; A! `6 H$ i" P2 V( t5 R4 r
                 return '=';
& W+ j. n; C( I! {" G8 c+ g             else
; J9 v) y5 K; u' V% Z) n: m7 X" o- X: \                 return 'E';
! c% }6 D. u: Z5 h* J6 f1 V- |3 y5 r        case ')':! ?+ a  ?& v% k
             if(c=='+'||c=='-')/ P8 s* d3 a+ g# x: p+ g0 l* D
                 return '>';
8 ]; L. j% `$ m             else if(c=='*'||c=='/')! C, I+ k# ^8 k9 Z$ t+ F
                 return '>';
  D/ v! z/ K( f- s/ m             else if(c=='(')" O2 i  F# H3 }' Y
                 return 'E';$ W- z3 Q! c9 c! w
             else if(c==')')& m1 ^" x8 O. u9 X2 V- _7 S* x- n0 G0 _
                 return '>';
& T8 |: _$ o# F% R0 s             else
9 q' J( g/ \" W0 t' ~4 b9 ~6 E6 Y                 return '>';
) D2 R- m6 ~( D3 y0 W! p4 C        case '#':' Z- j( [, q  y& ?: N/ s: E1 C
             if(c=='+'||c=='-')) {" {3 Y9 O: W6 V) j
                 return '<';
& z6 d; E6 v! U( S             else if(c=='*'||c=='/')7 B/ d; C9 E' j& ~) d2 _
                 return '<';$ C* x( M) @0 }5 A2 X+ y
             else if(c=='(')1 _' v; T# q4 c, e1 C: C( e/ B
                 return '<';
4 x& X4 I. K: N3 d& g             else if(c==')')
4 |& m* ?- r% [                 return 'E';
2 y5 q6 y" ~  Y* z9 Z             else# m9 w3 X1 s% @0 K' d  P
                 return '=';( R# j3 B" r6 s! g. ~
        default:
* j6 c7 `1 t! w% |  p9 @5 y2 O# n             break;
9 k2 O% R/ j4 a    }* D$ W+ `: P* k, b; E4 y8 u
    return 0;   
7 E! y) l0 |6 p4 C- P; c; v- e}
; P* _+ I) ?$ @1 a
# {9 Y$ T3 J4 G# Zint isOpr(char c)
3 W0 x$ h, G$ d! T4 ~# J{7 ?- v" Y% j$ q4 f# z4 i  J
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')& M# j4 t: K" l) i4 r4 Y
        return 0;
7 W) h+ B# W5 I6 m    else   D2 {6 l5 e/ k) c# U% C. s
        return 1;
& n* i. Q/ y" N! E! u}  @( h$ Z) D* j6 H: r+ K. F

; g( i: V7 _' E5 H. d3 E6 Yfloat operate(float x, char opr, float y)
) ~8 `" L9 T& b; U% O; D. N5 s  F{" Y* o  b( v- i% U5 C
    float result;
; r- f8 ^6 f1 G6 X5 F7 E) {    switch (opr)
. g2 s8 u6 ^  ~' v    {+ ~" \6 z6 D9 D" C; l
        case '+':
# ]# U  |; m' Z             result = x + y;5 Y6 Y& M+ m4 Z( h* F
             break;- M* q, X+ q. [/ h& e1 ]
        case '-':
: I6 j; {% y- }             result = x - y;8 l) e* W0 L7 Q" {  g- ]
             break;- Q) Q% s' Z1 B' q: P( Z3 E
        case '*':
- E7 \' R$ Q9 E+ n             result = x * y;
9 x8 @2 i3 [3 g- t( x             break;* `0 j% u3 `; s$ L, R' g$ [
        case '/': & d0 X9 }2 N9 _
             if (y == 0)
4 p. K7 G. O4 k4 n             {
# X$ p* }5 r: p& o+ p. g4 [  C                printf("Divided by zero!\n");
1 y" S) U, T$ l! ?/ v1 I                return 0;
: \. C7 J* `+ w- P- F$ i             }* z  R! W' U; e1 Z
             else7 w0 R* L  {, I/ ?
             {) c* W: x0 A, P" \, |
                 result = x / y;
4 h" c7 R4 |$ d6 }$ I; E8 a1 d                 break;! h: Y! l' f, e  O
             }
- \( W4 M0 a4 B0 y  M4 _$ m       default: ! Z4 g; P. |. q; N8 W
             printf("Bad Input.\n");
( ~& D, h& A2 K; N0 P' N7 N             return 0;
, G* o& k( b5 ?2 L    }+ p6 ~- a, D3 A1 Q
    return result;% D/ q2 X6 {0 Q+ Q; Q: i
}    ; u9 w6 w/ Q7 |( M6 K& q
$ \* j* H- w; Q! V1 l3 E
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
3 O' p3 B# z/ G' M( f{
/ p1 o9 ^' h, u+ e. `% ^    Stack optr,opnd;5 h2 r  A. I7 B( Y, R
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;. R  W% K3 ~' S! e, F) F, s5 F
    char c;8 p% X" D) f# I+ h2 ~
    char buf[16];; U+ V) q0 X" J, M1 \9 t
    int i=0;6 a4 l4 {! P+ P* B# ~
    : Q. G/ h( L: i) T! g# M
    InitStack(optr); /*用于寄存运算符*/
+ u4 L: c; F: A# F+ w' ?. s    InitStack(opnd); /*用于寄存操作数和计算结果*/
2 A) f5 A4 V) V) R9 i    memset(buf,0,sizeof(buf));) j( D6 L! T3 \0 E* c5 y
   
# g# i2 o: ^( p; C2 K    printf("Enter your expression:");  r' C% L9 q) [* ^7 \: C8 k
        $ I* W6 c& u; h4 E5 Q2 A. a/ J: g
    opr_in.ch='#';
" @9 F* j% F/ G/ n( w1 v, F2 h3 o    Push(optr,opr_in); /*'#'入栈*/
$ M$ C) n9 Q0 t- x    GetTop(optr,opr_top);
% R( o* {( ^/ Y& \# l' v& Z3 n  D. K    c=getchar();4 [; T4 l' m. e! v  I* L
    while(c!='='||opr_top.ch!='#')
; k) J0 [% e3 @0 {4 c9 D    {
9 K, [* {4 H  B        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/* U. k/ y  U2 ~8 e* m
        {
  E: L+ T/ v# I6 K$ _            buf=c;
0 A2 Q+ U2 Z' I7 f& r- B            i++;2 B+ j* _# g% J/ a, C9 m$ R
            c=getchar();! `- f) T) w) r, H/ ^9 m6 q% I
        }
$ m$ S# m! Y9 X( ], d        else /*是运算符*/
0 D# ~/ B: p! `- N        {( ^3 N$ h/ w7 }/ o4 x
            buf='\0';+ n* R. a' t" a- k9 Q8 q* l
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/7 j$ j( ^; k8 Q) ~
            {
6 b+ w9 ^' p1 d2 o, o0 B                 opn_in.data=(float)atof(buf);
! I2 A+ c6 S1 Z4 c" ]" ^5 x& z                 Push(opnd,opn_in);/ g2 [. Z6 q& `5 f& L
                 printf("opnd入栈:[%f]\n",opn_in.data);1 i1 ~; g6 j, [  I+ R" P
                 i=0;4 `, \* {3 n+ U, F
                 memset(buf,0,sizeof(buf));& G4 p8 ]1 a2 c
            }! k, ~$ C/ t* |& H( u3 H$ \8 F
            opr_in.ch=c;* c8 F+ e4 ^2 m* B* r
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
0 j4 t$ t( w# W$ Y% \) L2 S            {
# j+ x2 M# T5 w* ^- p' L5 z3 o                case '<': /*优先级小于栈顶结点,则运算符入栈*/2 w: h1 v6 @" J
                     Push(optr,opr_in);
- K2 y& c- `; L: R                     printf("optr入栈:[%c]\n",opr_in.ch);! G% o: e- ]" @; L  ^  r
                     c=getchar();6 ^6 s" \) l6 w4 P$ O( @3 v
                     break;. {3 Z# E7 E# U) [$ L1 r. F5 r
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
: p$ p7 E) r. ?                     Pop(optr,e);5 R/ @& U  I8 m1 g& s4 V% e  N) |# v
                     printf("optr出栈:去掉括号\n");: ?4 j: [" I  \% F1 h, M4 j- F* `
                     c=getchar();
8 f: w7 `, }3 G. |8 H                     break;
: R, I5 d- G) U* C9 H$ c0 h- _                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/  p% Z" x- Y$ S8 x/ R) y- o
                     Pop(optr,opr_t);& r/ Y5 I0 F6 c2 E0 S
                     printf("optr出栈:[%c]\n",opr_t.ch);
* B' R) Q( a+ d8 p% v9 j                     if(Pop(opnd,b)<0)7 [. N9 y0 q+ G
                     {/ C3 P5 D( M! C" x9 T
                         printf("Bad Input!\n");
+ B* h  U0 ]' C/ a6 n                         fflush(stdin);7 @; c. E1 l0 X% b) x
                         return -1;) m6 E8 l1 e+ _$ r
                     }
" I0 g* z( {5 e5 d1 v2 l                     printf("opnd出栈:[%f]\n",b.data);" X8 H9 m8 `$ d7 u4 w
                     if(Pop(opnd,a)<0)
5 }) d) h% n& O2 r0 ?0 s                     {2 ?5 N2 M7 e. N' C! Z% W
                         printf("Bad Input!\n");
$ z( I) T* s, s& h# k+ A                         fflush(stdin);0 B) S" |0 d! }, h. o* p; O2 z6 v
                         return -1;
# y, ~- g7 ^3 k2 V3 Y8 l                     }
$ y' f' ^* x( f4 X" b1 r3 J# o                     printf("opnd出栈:[%f]\n",a.data);
( R, _: R2 h3 |8 I+ a$ R                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
' V$ w1 @- \1 t9 B# ?/ n                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/' k7 k$ l' p$ t5 f
                     printf("结果入栈:[%f]\n",opn_tmp.data);6 f! v0 i* R) Y; m% U6 a
                     break;, h4 ^4 K1 Z- M  x7 l* G6 f
            }$ g# i0 v8 g% X# K" B
        }
; ]# b. L2 Y! z0 C" }        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                / w) e) w2 a6 P4 N7 j, J
    }
+ y' A) m. C8 g    GetTop(opnd,opn_tmp);2 ~9 z, D& C2 _( q7 K- `
    DestroyStack(optr);
6 q0 r# o7 Z% D+ r1 }    DestroyStack(opnd);
+ T8 I& L, m8 z. R    return opn_tmp.data;9 ?& M1 V8 w* q
}
- \$ q. k/ X0 L8 M! u& P% R& D2 ]( E4 r. F* X1 u
char *killzero(char *res,float result)
' o+ S5 u( ^" F{5 K& I% i2 z+ g/ u0 D/ P
    int i;
8 {) t$ _% G  F+ M! a: M  Z, x$ Z* z  s
    sprintf(res,"%f",result);1 l, N9 |+ \! R# X
    i=(int)strlen(res)-1;$ i$ w% S+ g" C6 L* v
    while(i&&res=='0')
/ [  g7 I( v, J8 a9 ~: p    {
+ ^. i0 W! t& B2 Z1 S        res='\0';
$ _# c7 O5 v" W9 l% Z3 }        i--;
# V0 ^, L/ C; [    }
2 c* Y$ E. k5 ^$ B% f) m    if(res=='.')0 b! q6 o+ V- \4 \0 v) a& p9 _; K- K
        res='\0';$ N+ q; t  a( ?& l
    return res;) c" u+ c- M3 ]3 y9 G2 i
}) N! P, n9 W# n: k
: y$ [6 s+ L3 ]3 v! m
int main()6 ^" p  O4 u  w* E
{
3 t* B+ i9 Z# z! @    char ch;
& B# W* ]. `' \    char res[64];; k5 O" C3 j( U) ]
    float result;
. ?) p6 L) L# H0 \% Y+ ^    while(1)) L9 n: z$ D) ]; Y- g
    {, p: w8 u& B5 N+ Q, x2 n3 l
        result=compute();
: S! _2 S2 T: X  o  f# e        printf("\nThe result is:%s\n",killzero(res,result));$ ?+ t& T9 m' C5 l4 @% G9 B
        printf("Do you want to continue(y/n)?:") ;1 f) ^# S2 [, s4 r+ v
        ch=getch();
8 A7 [4 e& t+ ~6 t        putchar(ch);& ?7 ^  e) P9 |5 }( i3 q7 m/ @) U
        if(ch=='n'||ch=='N')3 X2 h) c3 K. n' Z" R; ^
            break;
: {- Q5 d" w4 H; |        else# _3 v/ z  M! r& O
            system("cls");
5 T$ u! L) ]& r: [2 V7 }! o: p7 L    }
% A# `. `6 h+ W. Q" g    return 0;; ~) l7 g, G6 L$ @: z! _9 |
}

/ v  a" I; [, h$ ^- t' y! I
7 N* I! u/ v$ M* q[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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