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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.+ b, ?9 C3 o) M4 J
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=( ]4 ?% R; [& C* D% v
/**************表达式计算器************/
. b& D# G# n/ F* @& Z. j2 S#include <stdio.h>
9 `  F2 H, X' @1 l  G# ~) v$ D% p/ {#include <stdlib.h>* Y: R- o' X# }
#include <string.h>) `! W$ h6 \4 {3 J4 n$ ~$ M
#include <conio.h>; W  R0 I8 }: N. O4 r, T# n! z
#include <malloc.h>
& V: W" o. l# ?) g% K% O. X2 e: R' M' \8 ^2 n
#define STACK_SIZE 1002 J/ |9 b1 L& i# |) \( b' R0 I
#define APPEND_SIZE 10
( a: t5 y1 W0 U5 f7 ]9 z6 K3 M$ s
struct SNode{& g# E( u/ }/ x7 b8 K
    float data; /*存放操作数或者计算结果*/
# _: M$ i+ n/ f+ Q6 m) _/ O$ U    char ch; /*存放运算符*/
/ ^8 A% I  ?2 x7 P};; |/ p4 D2 p' b" ^; X& Q4 p
+ }; b. ?9 }2 D* j4 r; a: L
struct Stack{1 G& F; j9 F3 y
    SNode *top;& [; w# B- b* a, |3 z6 ~
    SNode *base;. j# i) z3 K6 `+ ^
    int size;
5 f4 j' q* @8 w* w3 J};$ ^  t  J  R2 {3 ?
9 s- S" B2 B1 n% F4 I+ J0 ^' r& y
/*栈操作函数*/
1 \* v! a* M" X% P# @- |; t8 L% bint InitStack(Stack &S); /*创建栈*/6 S! m% k; p+ @4 e8 g  h) i3 F
int DestroyStack(Stack &S); /*销毁栈*/& c3 H) _7 |7 p; h9 P) q
int ClearStack(Stack &S); /*清空栈*/. F6 [) \+ u" d/ s
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/4 D' x, c, z' Y
int Push(Stack &S,SNode e); /*将结点e压入栈*/
9 i- d) O- Z) @- D, M% E8 y( aint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
6 B% S6 M1 K9 x* }. Y
# T% f( H7 g  P+ `/*表达式计算器相关函数*/
  u& E, g* ]" b$ _8 Dchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
$ x. P' z$ p7 k4 f. e9 \3 vint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
! O( l" b2 _0 Y9 \- Dfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/. n6 x7 \, j4 k. z' C
float compute(); /*表达式结算器主函数*/# _8 u3 D- x9 R6 `
char *killzero(float result); /*去掉结果后面的0*/
8 Q" U) ?, |+ r" h/ x2 v( N/ ]9 G* B4 M& ?  R% C. q* r
int InitStack(Stack &S)7 K9 T: G. b" J" @( f
{: M! V* U. d$ n# k
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));9 }, [+ \( C3 G
    if(S.base==NULL), Y; u( c; f9 u% @
    {) X2 h% V; p/ f3 s$ q% N
        printf("动态分配内存失败!");
- n6 G( `6 D  K; A        return -1;* ~# ^5 P, l$ m8 O& e  V
    }
4 a4 u4 ?1 @, j! l3 U0 {7 b5 v6 v3 e    S.top=S.base;
) t/ p% u4 g& e. d" a. U    S.size=STACK_SIZE;
: c2 G4 @5 I9 s# e0 v0 m5 F    return 0;
3 F: D  h5 x& e* |3 g% e; n}4 X' {3 |0 o: G$ P

) H% W6 m2 @& H" d) H0 U1 W2 y- Qint DestroyStack(Stack &S)$ ^) l, X! D' G2 B
{
) x" {, t$ Z5 Z/ I; N! w; p    free(S.base);
% ~- _5 c( J5 ~. e* e    return 0;
" l) H/ g9 M( r, [2 |1 D}) C5 J7 K$ F. z5 w
. v; ^* P& @" n
int ClearStack(Stack &S)
. V  n8 B0 H2 X; t6 r- P{
& G( Z* ]! T$ I0 q/ X    S.top=S.base;6 G* o" Y& x3 \% C+ r$ h
    return 0;
" E0 N; W  C, q5 [: k# L- t" t0 |}; o, y9 z3 l4 N0 B: Q' D

" M0 |) @  y" ~, g5 J' [+ bint GetTop(Stack S,SNode &e)
3 K3 k& w  _& ^{0 K" B; }5 M/ m) w- n
    if(S.top==S.base)
9 a" d; M1 t0 W! T+ |% o    {$ R5 i' t( I' B8 [5 j
        printf("栈以为空!");
, T0 J1 x5 ^( K6 E9 V  _( {- w% r        return -1;& @" I3 A% R9 z' M
    }
9 K6 T5 F4 }0 i6 |# z    e=*(S.top-1);
8 P/ M; ^: V& ~( x    return 0;
. K. E! F, y9 M: q}, e1 W; b0 l+ z

' G" z! k6 P0 yint Push(Stack &S,SNode e)# X  b, a7 z! E; a
{
4 Z1 F9 P: b" X1 ]8 W( A    if(S.top-S.base>=S.size)
+ s" K1 m6 G$ R. m, z( T9 T    {0 F+ O  m) l6 x7 N* M& b
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
3 r! z) i( j8 ]% S        if(S.base==NULL)" e9 ]5 K; `2 P) d  U/ f0 z
        {
" [# }- h; @9 J% F2 y" h            printf("动态分配内存失败!");( W. ~5 y- T7 m! @; g
            return -1;
! U* p, V$ Z( O. v2 h- s        }
4 r( I& A( `) @        S.top=S.base+S.size;
! n! |9 H5 ~) r, }- k9 ]& c        S.size+=APPEND_SIZE;
- Z7 R, i* b$ N9 w3 h6 n    }% w7 [$ B6 [4 T( q1 |
    *S.top=e;3 w) N' C' v4 m) m1 n+ \) f
    S.top++;( p" j/ j8 {. ?) `* G. [
    return 0;
1 u) Y) Y8 A0 j3 T8 E}
+ u, p. }2 b2 h. Z8 F" ~# w/ x( M& W/ C/ A6 A; b& S
int Pop(Stack &S,SNode &e)
1 ~2 v/ L. [: D* C- _{, a3 R0 u* j- j2 H7 `. P
    if(S.top==S.base)! I% v8 K1 P0 P& A3 K& G+ Y8 d
    {; w+ \1 @; k7 G% w! C, F  |# J
        printf("栈为空!");$ g5 v1 v2 m, L
        return -1;* _; B0 L% h6 u8 a# k, s6 I$ q5 {
    }
, {! c. J2 t4 |    e=*(S.top-1);" K, k; S+ H; Q. x, G
    S.top--;  D* I0 `3 y8 f3 e
    return 0;
9 v4 z3 }$ W) {: R}
! }1 B; D2 Q6 Y. t7 V& m  o* s0 q% O, y  A# i) ?
char get_precede(char s,char c)4 X$ J# K- ]! g. |
{
% ^& ]$ N# b! W, F' I  s% X$ d    switch(s)
; d/ J: v& r/ \5 C    {
4 A2 @8 f0 q7 O0 H5 ]) H" m5 ^        case '+':                 
" \4 D9 Z# ~3 i1 \" ^        case '-':5 k, L5 B4 b1 d& q1 Q  L- T) @5 t9 g
             if(c=='+'||c=='-')
1 ?$ ?) e- v0 k) [                 return '>';
" c5 ^4 Z, K2 r& J' C7 {             else if(c=='*'||c=='/')
3 ?! I3 ^, e' L" m# m+ S5 \( ?                 return '<';
4 u, V. {! S0 \2 t  n. Q0 ^             else if(c=='(')
$ V9 X; @4 K; c8 e# W' M                 return '<';" F4 Y# k0 y+ ~9 p
             else if(c==')')
' d$ O4 [$ y6 k1 T; x3 \6 E                 return '>';
+ v' v) R: U2 R4 u# y8 |             else
  w6 d& o; S" \& \8 M3 l: b* J1 H5 \                 return '>';) V# k8 e4 H7 k, j" w# b( n- S2 g
        case '*':
- J3 |8 L/ w: Q! x3 X, y* z8 q        case '/':
8 W. G  G5 b- N: d* p+ Y             if(c=='+'||c=='-')8 j7 \! \& K+ w, n7 e& F% O
                 return '>';
( A/ k3 M3 [: v7 s             else if(c=='*'||c=='/')  [- D5 L: t9 p5 X' m; G
                 return '>';2 J( z& y+ }8 k
             else if(c=='(')
- m/ o: U  P2 u% {3 t9 `# r                 return '<';
# `& F# `' w; a; [1 q             else if(c==')')% i: @% y  t4 @( s
                 return '>';% j/ S; h7 Y+ h& G! o7 ^4 m4 m8 E. a
             else4 Z' ^0 R: m" Y# [  k0 f+ z- s* m
                 return '>';5 Y. p0 ?; O7 c: C$ c% H
        case '(':
0 h) o$ m8 m, H) ]             if(c=='+'||c=='-')  w" X9 z) k% B9 ?" ]1 ~2 I
                 return '<';
9 O7 O1 ^/ u) [3 @' v; M9 [4 K             else if(c=='*'||c=='/')
) N6 x' B7 m" c$ j                 return '<';; k9 u; g; V: Y& e" E
             else if(c=='('). c! P8 T+ r5 `* o3 W4 B
                 return '<';
& }+ s1 D$ g. z             else if(c==')')# |1 X0 T3 z2 a
                 return '=';
+ R9 z  e# p& m( D1 J( Y7 X             else3 k, [5 K' v( l* V. c4 O8 ~
                 return 'E';8 X1 M( X3 x' ~9 [# N; M0 j# |" M
        case ')':
( b  f/ B0 e4 z- D4 k6 D3 b             if(c=='+'||c=='-')2 U# I( f; y8 a0 n) k( h$ Q
                 return '>';! P+ N( N  |0 k  g$ a  z1 U
             else if(c=='*'||c=='/')
' t5 l8 E8 o% s, G0 P! Z. c                 return '>';; I) Z6 n3 ?% a
             else if(c=='(')4 M/ X2 O" W( y) e
                 return 'E';; F$ o  @# C6 e6 l3 [1 O$ q
             else if(c==')')7 L. ^, y- L9 i5 n/ S
                 return '>';
# K, S( B; O: B: F; W0 ~9 [             else
: i# i, T6 p" V6 r1 Z% t  e                 return '>';
7 b+ P6 r2 X, \. z' F        case '#':
) F& S/ v2 v; m5 q             if(c=='+'||c=='-')2 V9 r$ U2 i& O5 l7 D1 f# ^
                 return '<';
+ K; z2 D. E0 {8 |( ?             else if(c=='*'||c=='/')
5 j1 l% i" P( p4 O. s4 R- _                 return '<';- ?2 ~: C& i. |0 g) g
             else if(c=='(')4 z  j9 @4 u3 C- [
                 return '<';1 @" \/ u6 X/ ~; Q/ D
             else if(c==')')
& z9 w7 T  {& g" q( V                 return 'E';
1 H6 r; D5 A+ v" H/ P             else
3 s8 j2 ]4 M. s5 a+ ]  l8 N+ S+ ?                 return '=';, l& h8 l: e9 x+ d* [0 B, P' I& \
        default:5 P( w" e  h1 e5 Y6 h
             break;
; ]' _$ l+ ^& X2 n1 V& V    }( r1 b7 |/ W6 ^+ m/ q8 B* X: q. @- P
    return 0;   
/ N9 v& Z0 H; W) J- H}
! @: R1 ?4 N: @3 O
" F6 b* L" b% a) F2 uint isOpr(char c)" p( T; S6 j0 O1 {1 x+ B3 \+ ~
{
3 [* ]) j0 R: U( M    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')' l( _9 D+ o1 g- _* D* M
        return 0;
5 F6 r0 x5 E+ ^* T    else ' M: L* }* B3 v" ^3 M5 b
        return 1;+ h. H8 Y2 L5 J5 H8 K
}
. t1 N2 i3 b& Q+ Z6 j7 B: F+ P
/ Z8 X  S: H( L" Q6 J+ _; C# G+ m2 q; m# |float operate(float x, char opr, float y)! P4 P% E. o! `$ q- |3 q6 }; T. d
{2 Y$ q4 Z3 k! m
    float result;
+ j1 n/ [  C% \" m& J( U    switch (opr)
9 T4 x. {, N( j; x% [: L8 T) M    {
( y4 n) p- [. |1 k1 k        case '+':   t/ X0 F* T. h# T9 ^/ R
             result = x + y;& F& Q: n+ y6 z
             break;# d) K: d; R: i7 K# p
        case '-': & o2 R+ H6 W8 t# G& K- v
             result = x - y;
) \2 l1 Y" M/ t, E0 ]             break;
# X, Y8 N* l% q3 l- d2 d+ g" x! S        case '*':
- W  D! G/ S3 Y: _( A- P$ J             result = x * y;! \) F" X/ n( e( K& \! ?
             break;. J* A0 ^8 W+ y
        case '/':
. p; T. C9 u, y& i# \1 Q             if (y == 0)
# [0 m$ z6 E( ]+ g1 _             {5 d0 @" i& w0 K3 m: e
                printf("Divided by zero!\n");
% p0 M( b1 E- ^& q& f* R9 X) P( M                return 0;
7 J* u" A6 Y! z( I/ O5 i             }( i! y+ o2 b4 \' x) J9 [5 P, q4 S7 x
             else
% w4 u; D) F4 _" ~$ M/ T             {3 E3 D# c" T% u% _& C
                 result = x / y;
8 M7 D9 p: K0 @7 _, ^" G                 break;
% w: n& c# c: D+ u* n             }# c9 ]: q6 Z. }! ^
       default:   F! Q9 S1 C1 i! t# u
             printf("Bad Input.\n");
, y4 N. Y+ N2 h% `5 u             return 0;
; m+ {7 W% c( v7 s" @) z$ A    }
- @+ C2 u" A0 i1 C  i1 B    return result;# ^7 W, f" s6 D+ _$ N9 U
}    8 u( Z4 a* U( S$ o
8 a0 }/ V2 R. V3 Y
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/4 |  q6 }1 y( C
{, k/ u$ `9 p$ K
    Stack optr,opnd;* m0 d& N, S4 S& x
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
4 ?' [& V, U! N  h6 N" d( T    char c;2 Y+ M: m" D2 ~" i
    char buf[16];
9 a8 Z% X' j" C# _6 O    int i=0;
* U- `. M3 W* W$ W+ e8 S9 j: T    $ A& j( F$ i' d7 D2 v6 Z1 o
    InitStack(optr); /*用于寄存运算符*/
7 e# Q$ R+ D/ g+ ^- Q% g$ ?    InitStack(opnd); /*用于寄存操作数和计算结果*/
: Y4 Y! X' ~2 P( J+ V    memset(buf,0,sizeof(buf));: u$ F$ T3 r8 {! l4 i2 L1 _
   
: L7 m* R* y% U. _* ~0 T0 w    printf("Enter your expression:");
1 X, L7 f' O" T! v        
. k; n! R' m, p4 ~% b    opr_in.ch='#';: y) z! |( d. M, @" m# Y. W
    Push(optr,opr_in); /*'#'入栈*/! \* c2 w' i2 l  t
    GetTop(optr,opr_top);5 E; c6 K  s* j
    c=getchar();
! O) p* [1 }/ S; A9 J    while(c!='='||opr_top.ch!='#')9 W$ P! c, M( Q: v# F# X3 h
    {
8 D- y; o/ x; T: v        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
' {( U- u; c7 W4 |/ k        {
& a$ }! q- G# [+ U4 Q            buf=c;
  B0 A# u5 X4 d5 M  @* M            i++;
" @+ P5 X0 S' {% S+ ?$ M& x            c=getchar();# b; |( c# {$ h* W  F! s* _
        }* N( K  K4 v, P3 U
        else /*是运算符*/, Z, Y+ [! y$ a* j6 k# l. g, n
        {
' {$ C, m' R) r/ ^  E" W: I/ \            buf='\0';
- F* ?+ H( q" o. T- ~            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
2 ?* f. b7 x. [  @8 |) \1 g            {
4 t+ T; G0 \( v  t6 \                 opn_in.data=(float)atof(buf);0 X0 m/ a* A7 ?# I* |. L2 N6 b
                 Push(opnd,opn_in);1 K7 w) f' W  c- R! S
                 printf("opnd入栈:[%f]\n",opn_in.data);. V9 c  S+ l  B# D+ {% }3 n/ v8 T
                 i=0;/ W9 V, i- N7 O6 t7 W4 b1 N/ W% M
                 memset(buf,0,sizeof(buf));# O  ?$ H' T% W9 i. K1 G4 W
            }
3 Q* N; T, F  R! }            opr_in.ch=c;$ H, E- s- K! j1 i8 t
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/. Z7 |6 Q$ d& V* W9 A
            {
0 Q0 }2 O* U3 U                case '<': /*优先级小于栈顶结点,则运算符入栈*/
6 ^) h, t2 a6 G" \                     Push(optr,opr_in);, K. _+ h  @1 T* R
                     printf("optr入栈:[%c]\n",opr_in.ch);5 \6 y9 k* S' n; `: q# L" ]
                     c=getchar();. S7 D1 |: y' ?1 I7 T" j5 O1 A$ N$ |2 y
                     break;4 f4 U/ |1 i; r4 e
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
1 F: {/ G% Y/ Q+ G                     Pop(optr,e);
$ _! M+ Q7 [/ I* g  e                     printf("optr出栈:去掉括号\n");
! w. m; x* U2 ^                     c=getchar();1 V2 X& J; I9 r( w
                     break;7 D; c: R5 b% H- @2 m
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
+ T" r( Z( \, z4 [" n                     Pop(optr,opr_t);7 v) N7 k+ @+ c8 m
                     printf("optr出栈:[%c]\n",opr_t.ch);$ s; B1 U% I, r, p# |7 U0 B
                     if(Pop(opnd,b)<0)
$ H- S( `, m0 Y' J) ~; }  u                     {3 `# v9 ^( f1 t6 r5 V/ v1 F
                         printf("Bad Input!\n");
5 ]6 t- V) j0 O5 {9 @* f4 c! ^: I                         fflush(stdin);$ x$ C! M+ t- ]
                         return -1;: o5 I- j) j% C& z6 H( l
                     }
1 @0 ~$ h! N5 m4 L" P                     printf("opnd出栈:[%f]\n",b.data);
3 l# u8 |# C9 r; J! Q                     if(Pop(opnd,a)<0)
; P, U4 F9 M, |+ P" `* d# S                     {
+ L" {' w! \6 y7 P                         printf("Bad Input!\n");
. m! F( A2 y  N: ~1 k# y! j                         fflush(stdin);
" ?7 H' N$ m# _9 z                         return -1;: k0 z+ y0 q& ?
                     }
; b! |* t, Z& }; P                     printf("opnd出栈:[%f]\n",a.data);
. b. R/ T. f  W( N& y/ l1 B# Q                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
! E3 W$ H) F/ y4 ?                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
, {6 V$ r: F; `4 b- N) ?                     printf("结果入栈:[%f]\n",opn_tmp.data);) l8 M+ z/ v* ]" s! S3 ^" d! D
                     break;
- J7 u9 b4 I: T* N3 F            }
2 S3 x: i! U3 x3 Z8 ?( Z2 T; S5 y        }
% ^9 H3 H" x2 H2 I$ H        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
. n0 `3 e. S, d; A+ T    }
0 `# L+ c5 B/ X! C9 i8 ~  g    GetTop(opnd,opn_tmp);+ p) M1 f9 }6 l2 ?1 `4 o
    DestroyStack(optr);
4 I0 |/ n5 F  P0 I, z    DestroyStack(opnd);! e2 Y  s5 \! w/ E
    return opn_tmp.data;0 o; {2 u4 \7 L6 e  I
}
" v4 ?5 i! C9 N
5 p9 r* D3 C3 H+ d; Ychar *killzero(char *res,float result)
$ P! w6 @, h& Y5 W8 Z{" `+ V% B# g0 A( o% r
    int i;2 e% [) Z; c6 T  v& n" y
7 L3 i& A8 L6 b2 h
    sprintf(res,"%f",result);# ~/ J+ j& ]% k6 |
    i=(int)strlen(res)-1;
- l( _* m6 U$ b    while(i&&res=='0')* y8 z: X$ M% y% K. e5 j
    {
; {; |& {5 {8 Q  Y# ^$ Q. B& ~; o        res='\0';. c8 D; V0 R' o3 m: m- I% l
        i--;% T* J! z: f  a7 s8 w2 I4 C* B
    }
1 \& J! G$ Q9 n5 _) ^    if(res=='.')
1 `, K5 A* ^5 ?# H" A. w! L! p        res='\0';
# [. ?6 @) W: H, f    return res;
' a7 _( ]4 P( Q5 y: \/ N& G$ p8 l}2 N1 Y' {) K+ z4 w( y- n4 ~
) h1 |) M3 h& t5 W  O1 x2 x' K
int main()8 y6 V+ B& Q$ R! y0 r
{% B: c! d7 A4 A6 v+ z# B# J- c" c' s4 t
    char ch;/ i, J3 _+ C5 e8 Y9 _
    char res[64];0 L6 W& `5 y! Y
    float result;$ J3 Q. ~, Q# J1 b
    while(1)8 K% x2 b0 S% ~) O$ O) g6 V
    {
. |4 u% C& G- M% |        result=compute();
1 I2 [  a8 {9 t$ Y1 U/ X        printf("\nThe result is:%s\n",killzero(res,result));
4 b: g# F. k, Q) \        printf("Do you want to continue(y/n)?:") ;
5 ^2 Y/ ?5 @' k/ q        ch=getch();: T/ ^. N, n  ^1 r0 ~7 F  f; a( K
        putchar(ch);! B* \" `2 l$ `$ I  w# x
        if(ch=='n'||ch=='N')
5 S) g, ~! n9 w' ?$ h& h) y            break;
. \) p6 o- w' K4 R/ Q7 @' M        else
' s* d0 z+ g3 c6 V) R+ \            system("cls");
9 h6 M7 i- ~# G9 M; u    }7 l( @/ r" }$ W# F* L
    return 0;9 g$ g6 \+ }7 V
}

- L9 U* c) ^8 ^, Z
0 C5 m! a& V* T, [5 e3 u[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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