Board logo

标题: C语言表达式计算器 [打印本页]

作者: zw2004    时间: 2008-1-21 17:17     标题: C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
/ ~$ J4 L1 G5 ^' x& m: `程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=/ @$ |+ h: D! @2 K/ d, U
/**************表达式计算器************/
) _: j  R/ p/ b4 v" K$ k" n4 L#include <stdio.h>: ]0 b1 h2 |. X# ~8 h+ L- r
#include <stdlib.h>2 u% l. V+ {" K' p/ n7 |
#include <string.h>
% c, Y, R2 Y. Q& C' Y  ]5 R5 }#include <conio.h>4 g1 b( s# t! K
#include <malloc.h>
; y0 k- b; `- o0 |" J# P  ]8 p$ R0 d
#define STACK_SIZE 100
+ ?1 s- M/ j' ]# k$ v; T#define APPEND_SIZE 10
. K+ _5 s$ x" N" o) q# K6 f1 M& @! p! _7 n9 b) C6 ^& i' {
struct SNode{% G& G  o* }7 r& W; M! X2 s( x
    float data; /*存放操作数或者计算结果*/' k; L9 l  b7 p$ y$ C
    char ch; /*存放运算符*/
; y/ B3 X# q3 \( S0 W};
! U) o9 s* [7 ?6 \# U% s" c8 w* z; `+ P* r) z. q* M9 J
struct Stack{" V* l# z! P7 ~. C
    SNode *top;
6 v9 K$ i( `9 o- |    SNode *base;
# V" N' F8 d9 S' p    int size;
! y& ]: z8 Q. T. x5 V" s};% R( |/ D4 F9 P+ x
1 k$ N5 L1 G3 u5 y" R; [+ J
/*栈操作函数*/
7 b0 @4 ^; Z6 Eint InitStack(Stack &S); /*创建栈*/- ^/ D7 A8 ~: V, m
int DestroyStack(Stack &S); /*销毁栈*/
( ^1 M- r7 D  nint ClearStack(Stack &S); /*清空栈*/
% \' C3 R, a3 Q4 B1 m8 c8 J9 pint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/7 Z  L) _9 A; [8 X
int Push(Stack &S,SNode e); /*将结点e压入栈*/' r* B5 }/ [  o  K6 h' M' L5 F
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/& S. V2 k2 k5 d6 n* p( [7 o. N

. j- O- {" z" d& K6 B2 g- i/*表达式计算器相关函数*/
6 E* S. P( l3 r: J& G, Pchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
' u- P1 S1 K) u& K$ tint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
( Q+ j( k; N# m/ X. W9 F$ O: Yfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/: s$ e8 d5 r9 T# f4 `
float compute(); /*表达式结算器主函数*/2 @1 F  G7 C7 h5 e) E) _8 U0 t
char *killzero(float result); /*去掉结果后面的0*/ ) s- ^& P2 n$ @$ l
" F4 ^- I, B0 B+ y8 n4 i
int InitStack(Stack &S)* K! y6 t2 p9 h: |% j8 ]
{3 `" e! h! v% U2 x
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));8 V! s0 ?+ q+ G- l. k6 X+ C
    if(S.base==NULL)
0 B+ k; Z- n) e( C& N% i    {: P) f" E" \, D: t2 ]( F, e( ?
        printf("动态分配内存失败!");
$ G* K' x4 t  k( u7 z0 h0 Q1 k) S; p. ^        return -1;1 u8 H+ f' y/ H9 E
    }+ Q1 E- s( e4 ^; f! y
    S.top=S.base;$ L5 \: F8 X9 L6 `9 ^
    S.size=STACK_SIZE;
5 V6 Y) f7 l2 E& l1 `- R7 y4 ?    return 0;
3 e: @% w8 E% O2 Y3 D0 N* Q% D* O}8 e0 B4 {+ k+ Q
$ |+ |- U2 F: ~1 X( d+ l% O5 r
int DestroyStack(Stack &S)
0 t. R) o4 v3 ]{% s% h2 h/ A7 B( ?& J: X5 [& G
    free(S.base);7 N" ?3 x* ^+ g5 e0 l$ s$ Z# }  Q* R
    return 0;: L3 k3 k: ^/ T! @
}
) p) O2 b/ `& }7 F; x" I, J9 q- F: w2 {4 s- W7 {+ G
int ClearStack(Stack &S)
2 D0 X+ z5 z: z, [% W  s{- n) b4 w! M7 M6 ~2 R& Y
    S.top=S.base;
+ w) u: s' R5 e" e) d2 F; ~; I    return 0;
3 H; k9 P1 M1 K) u' Q}
9 Y) z4 b& v+ h7 C3 C0 Y
, N& J' t; Y2 S0 o- c" A( Kint GetTop(Stack S,SNode &e)
  J& r. x) p& m  [; p0 c0 e; ^{. e$ A! a, Z4 Y
    if(S.top==S.base)# I5 v7 f/ L" B- j
    {' r, d. `3 l/ `& m* D
        printf("栈以为空!");( ?* D; \9 U- r2 E, M4 w6 ^
        return -1;
8 {3 W$ o" q) \- b% b5 ?# w    }
7 m6 ^% t$ p4 U- Q* u    e=*(S.top-1);
! y: k- ?7 L9 ?! Z8 W: x% L    return 0;) c0 v" K" _5 {4 T  A) |
}  k* \6 n) ^5 p' V0 i
- a4 c6 y, g0 d6 Y
int Push(Stack &S,SNode e)( Y5 W! [  I5 }7 n4 Y
{
4 l1 ?& M! ~- V! s! V) S& D    if(S.top-S.base>=S.size)+ y' [2 e3 X9 _% G
    {9 v8 z- [7 p  g6 |
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));/ G, M" u" z, X2 j
        if(S.base==NULL)3 S1 x! @" X" s
        {7 j7 [7 {2 z2 g
            printf("动态分配内存失败!");
+ v. n: k8 S) g+ }# M3 }' _* Q            return -1;5 @$ ~  B4 \; A. x% n5 _# t; M. T
        }# F. @0 i! K; k6 i+ _2 U* ?% U
        S.top=S.base+S.size;$ m+ z% p, ]) @+ [/ Y
        S.size+=APPEND_SIZE;% Y" {; }. l$ W! k
    }* b1 z: l* v% T( c% \
    *S.top=e;
1 p4 G% O8 f7 y; M  F    S.top++;
; ^2 o7 t6 B" y% |3 J: a+ b: h    return 0;) Q3 W% o6 L! m. x1 o( w
}! f1 S4 y+ [/ ~2 ?7 U: y
. m  c; L9 N" ~0 c
int Pop(Stack &S,SNode &e)
) K) y- v( g+ o. g9 t+ B{" x% `1 G' z- l
    if(S.top==S.base)
+ M3 R/ R" O% K+ x1 a    {, J; m- {- G! a( L, }" Z
        printf("栈为空!");
& @# V8 ?, i9 W% v6 T        return -1;8 O0 B% g  @3 O3 t1 W1 H0 q
    }
* p! P1 ~  q* s. `/ I! T  k    e=*(S.top-1);4 [$ `2 m% t. a4 l+ }8 X$ M& Z
    S.top--;7 i/ u3 W: _3 O* A
    return 0;7 }/ c% K1 W4 i! j" l
}9 e8 ^( \8 {4 S, _5 H% b4 r
' H4 u8 o1 p- l5 a% N
char get_precede(char s,char c)
3 I, q/ |" C4 L/ p2 K* Q; A{
* [0 e) u3 y9 p# A% g    switch(s)% c+ h2 R3 Y% ~: t4 o
    {
6 O  R% s% S1 ]* y4 }        case '+':                 
; E) M# d8 P8 D  @) D# q        case '-':
0 ^) v0 z& _6 C+ |/ g( b8 @8 m             if(c=='+'||c=='-')9 o. q/ Z& t; Z: k0 C3 I/ ^
                 return '>';
5 t+ l/ G7 ]. L2 U& {- ^6 B             else if(c=='*'||c=='/')1 H' a1 A8 y: @8 Q6 ^! k) \! A& O
                 return '<';  z1 T; T% G/ C4 y7 r
             else if(c=='(')+ s& S- m: r2 {' w, F2 S4 Y
                 return '<';, _# F6 n) l& a
             else if(c==')')
' R6 [/ u- S$ A' j! u) C2 G                 return '>';. b% \! r9 o6 z1 S8 r4 |6 g- b
             else
" n" N7 F+ ~- ], ~2 q2 p                 return '>';  K3 _( n% s% g) D
        case '*':
( N3 g% [" V# P        case '/':
; L" g0 F6 P# r5 ?' b             if(c=='+'||c=='-')
0 F$ U8 O) h( h+ t8 W6 O                 return '>';( {3 ^& k: A% R6 c- d
             else if(c=='*'||c=='/')- K% T3 h9 z, {3 S5 U3 O( x8 x: W
                 return '>';! f. j2 t. ~# w. c& \) D
             else if(c=='(')) M; O% k; {" c3 s4 a- ?
                 return '<';) d# q2 u3 i/ A4 k" [$ c
             else if(c==')')4 W, d% V9 j$ z8 H! f3 U+ p2 _' x2 E
                 return '>';
% N3 Z) d, E- @9 ?/ o             else: |( d% Z3 a8 ?) x  G0 u
                 return '>';
2 Y9 N4 U6 X/ M2 G        case '(':; h/ O6 z/ s: S1 r) A
             if(c=='+'||c=='-')) b* Q5 @) o2 a# V  t
                 return '<';
1 q" r+ M8 v7 _             else if(c=='*'||c=='/'); O7 s& N- H; z
                 return '<';
; v8 k# q1 G, ]) L             else if(c=='(')
7 @5 j2 y. J( {& V! a                 return '<';1 z( i0 ]4 m3 D- Z4 Y  j
             else if(c==')')
' Z! e* X2 v' a) }. R                 return '=';* \3 z. C8 D/ Y/ V, ?
             else
2 }+ u' J. W3 g' j8 }                 return 'E';
& o8 L" b7 q# F+ s; Z        case ')':6 c1 y# [; k8 F* a5 u* z. v
             if(c=='+'||c=='-')
+ |8 ^. d0 R/ t+ I% O  c9 y2 A2 H                 return '>';$ \" g) Z# r/ {; B4 y% \# A8 t
             else if(c=='*'||c=='/')4 M5 K9 _+ y3 W& F; {8 X% Y
                 return '>';
( K3 T' I8 i, @; Z, }% i             else if(c=='(')
% `! k, l8 p9 O5 Z& R                 return 'E';4 N5 L* H  r! Z$ ]2 S% W
             else if(c==')')
3 ~( C$ Q% X; R1 p( Y                 return '>';
7 B+ D4 c0 n& K& X8 @             else
) u' F+ e- `) c; V2 c1 {  J                 return '>';
" B$ [" U# B- y9 G  R- z$ l/ q        case '#':. ?8 ?+ |' W' G0 p
             if(c=='+'||c=='-')
/ ^) s3 o; a- @% T) F7 }                 return '<';
! o4 m! x* _3 \% N             else if(c=='*'||c=='/')3 f3 K4 `- V# ?  w
                 return '<';
- o! J* m( _  a2 O1 x* s1 H             else if(c=='(')
' |) K! Q, b" y5 U) y; p                 return '<';) ~- G$ V* I# H# c' N( X! y1 Z' {
             else if(c==')')
6 b; A7 P. l4 e( n6 K7 g9 L                 return 'E';
$ {* C, W% y4 i, T3 t% ~             else
- b7 m* o) ]/ j( _) N1 o- k# _                 return '=';
2 x" X# I1 L- R4 R9 r        default:
' \9 Y( @$ o; S* G             break;
1 u8 g9 Z2 o$ r" D6 V; X0 @: f. H; B    }8 `+ m' }, n/ S  T+ u( ]  O6 P
    return 0;   
8 ^0 B. d. D+ W+ v}
$ f/ r# T  `) [* B4 M( {& J, ?. e# h) }% J
int isOpr(char c)+ e2 k" J- v4 R: ]2 Q, b6 t: D6 ~
{5 v- K) F# O8 c2 D/ i" T" _- Q* C
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')& ?! M/ |* A2 o5 W# X2 K
        return 0;
0 `# l/ E+ _1 V9 l. J" y    else - `( O& N5 ^  K( E
        return 1;$ E8 n0 I0 L: I2 L1 O( N) \. A3 m
}4 x# o7 h5 ]' |" [$ M- b% M) }0 c
0 Q+ n! S5 s) X/ r: O/ h
float operate(float x, char opr, float y)0 j) T& E: X+ j  t+ c. m, u+ O
{( x. r6 |) ~  I: O, n
    float result;
) x0 K" f" E3 D( b    switch (opr)
' s8 O7 ]. w( I! D' S    {
( L0 l$ X& w7 t# X8 V9 B, Y) U        case '+': / Z7 @' L) x8 |1 x" O
             result = x + y;
$ o  e9 b! G7 U, f  `( Y             break;& @5 i! H$ ~) w# {( Y: d& a$ h$ c) \% ]
        case '-': 5 I' ~; m1 o- J/ f' Z
             result = x - y;
0 L* v- \+ l8 W, Q1 M4 _" L             break;
2 F( c3 j# P+ u8 r% m. j+ H5 G        case '*': 7 Z" b$ {# f" y
             result = x * y;
# N3 j# h4 Q4 O             break;3 w6 K8 y7 m8 l" j' k
        case '/': 1 f+ v1 _, O4 g( h! D- [' H
             if (y == 0)
7 z6 d; m+ o$ G             {" `$ R5 H+ u2 u; Y
                printf("Divided by zero!\n");
1 u+ ]( `" {4 L' ?: Q" W) C                return 0;5 x, h4 C5 a+ l- J
             }
) E' O5 Z! u( f0 D: _$ {9 m             else* B% H1 Y& k) w; k6 ?* R" ?0 ]
             {
* J- Q. n6 k, b                 result = x / y;
0 @3 m% }! e( p0 j* O                 break;
7 g" n  F5 v5 G0 b8 H- Z2 T             }
* I% I& K4 D& J3 ?       default: 2 O: a* q0 P* u' F
             printf("Bad Input.\n");   O( P1 f2 b! e; L4 p3 P. B3 f
             return 0;
8 f( V2 d8 S) ]' t' s$ m    }
2 V/ ~7 H9 f% m" I6 Q4 B    return result;
8 e0 ]; y6 \) P' A- B; g}    $ m: P% y7 X0 G0 {" ]

) D4 y5 c" R/ _float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
7 |3 c0 |3 Y- O5 b' |. Q{
8 E" U$ u6 W( J9 E8 M    Stack optr,opnd;3 s% @9 r6 w' c+ Q: _7 I! J
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;  O' g( ~( z; I, d' E7 `
    char c;7 U" {2 G3 T- D5 `" s# |- |0 C
    char buf[16];
7 G% }+ u6 w& W& A3 \    int i=0;
8 z- T2 Y, W7 E  b; `; A   
& G3 O8 m9 r  L8 q( j5 f( Q) `    InitStack(optr); /*用于寄存运算符*/
9 P* R" A) }) }6 V7 g; u# {% T3 }    InitStack(opnd); /*用于寄存操作数和计算结果*/
* {! @: Q8 E2 ^$ Y8 o' H    memset(buf,0,sizeof(buf));
/ K( E5 O4 I, L4 o$ I  p   
" _; G) l0 M9 X' `6 k    printf("Enter your expression:");
8 ?9 q5 C) v8 z9 u& C* p        3 p) B/ K8 b5 h5 z* U
    opr_in.ch='#';
, u7 a  r/ C1 g. ~    Push(optr,opr_in); /*'#'入栈*/+ P/ C5 G% l  ^
    GetTop(optr,opr_top);" L" _& J2 {" e: H/ w' [
    c=getchar();
- L. r2 x9 {1 c* x  C3 o/ m8 B    while(c!='='||opr_top.ch!='#')
0 f" X5 k; _1 E% y; A0 h    {  w# k; w! u2 Q" M# Q/ y' _; u
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/6 D* Y6 a# Z. C7 D
        {7 ^; `" j" Q/ g4 ^) X( v
            buf=c;- O# k* h5 V* X; o% ~$ ]2 U
            i++;7 C9 E) F' T% y" @' }( [' P
            c=getchar();' L, P) _1 }2 d; @/ q
        }
+ U) r5 w# x  \3 P+ p/ U- Q        else /*是运算符*/
. v  w2 n7 i9 t7 j  H        {
6 @+ Q, t- b* z, {            buf='\0';0 X" e; J, I+ `- m1 o3 _, A+ Z
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
9 a$ x: E+ y, D) g* n; Y& I2 A6 M            {
' x3 r9 P- E7 A- w                 opn_in.data=(float)atof(buf);1 V7 r) b, p# p! B+ K3 Q$ P
                 Push(opnd,opn_in);$ W* R3 Q9 e- @0 ?1 \
                 printf("opnd入栈:[%f]\n",opn_in.data);
8 s3 q$ D2 |) X+ w# z) I                 i=0;
" L6 X* @( \+ d4 u                 memset(buf,0,sizeof(buf));
) v; y" B' M8 @1 T6 k& A" o            }7 L$ U" g7 e! x+ I. T+ f6 X
            opr_in.ch=c;
& y% y. [5 E4 d- M: W5 F+ ~/ |& B            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
5 J; l, P; m/ @6 e1 j            {
# B, ?9 T. t  ]! ?* t0 F; Z                case '<': /*优先级小于栈顶结点,则运算符入栈*/
" l# m) `9 ~/ w6 r* ]                     Push(optr,opr_in);
. n& |& \6 n% u% j% }0 M; D                     printf("optr入栈:[%c]\n",opr_in.ch);8 H3 \! r# D" c7 c9 h
                     c=getchar();
, u( s" s4 q+ C- n6 n                     break;
2 z, |+ S$ _. _% E0 w' k$ `9 N  J                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/" V' [0 s3 S4 j
                     Pop(optr,e);% U7 H. ~" P. [  W
                     printf("optr出栈:去掉括号\n");
, k" y1 d9 L/ `: V: \: i/ U' l# {                     c=getchar();9 I4 t% l1 g( @3 \
                     break;8 q) H) n/ z+ ^) u( _# K% Z
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
/ X, j. e' Z5 M. H0 s$ h# A/ \: }                     Pop(optr,opr_t);
( e. S+ Y3 E8 P( {3 S                     printf("optr出栈:[%c]\n",opr_t.ch);
8 p2 z% s: B. d$ R9 r$ F% [                     if(Pop(opnd,b)<0)
8 d9 v3 P& ~' I( [5 J( c% a! W                     {
& J0 p) ?/ [) W0 ~0 g                         printf("Bad Input!\n");
$ P+ f+ \3 U: ]- x4 {7 B                         fflush(stdin);
- @1 z2 @$ y1 e% k8 h  k; l                         return -1;
! _, F$ u6 G& T9 P/ p/ b; y+ ^                     }5 P9 z* z" p0 D' @; S( i+ P' e
                     printf("opnd出栈:[%f]\n",b.data);( k8 K4 U0 U8 V2 M: S/ q
                     if(Pop(opnd,a)<0)4 P+ Q6 }* @# E: `/ B
                     {
) k- `% s+ i9 I6 X                         printf("Bad Input!\n");
  A& D8 K* t6 O- `3 _# I! a' g                         fflush(stdin);
- D; e0 \# F( m* s0 }                         return -1;/ {. V( _- d6 b) v* E( K
                     }
, B5 v& Y" w/ }                     printf("opnd出栈:[%f]\n",a.data);
% Q3 x6 L5 l9 t2 ~, w7 N                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/$ Z" U1 c5 i, H: |/ S
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/. y+ D; ^+ o( j4 l8 M& l
                     printf("结果入栈:[%f]\n",opn_tmp.data);
4 g7 f2 i8 b. S; H# X                     break;0 }8 Z0 d2 }+ F
            }
( `  B& }: j0 x6 i  y" g' Z        }6 B6 w; U. j" @% |
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
$ L) w- ~& R! ]8 j1 c    }
8 y; k3 u4 R: }) D1 x    GetTop(opnd,opn_tmp);. m  P& f7 G2 e3 T. i7 o. |4 k4 S/ b( a
    DestroyStack(optr);
; C& `$ s& w% y/ @- c    DestroyStack(opnd);
7 ?& f2 {/ J+ `. h8 m8 T; {    return opn_tmp.data;
+ `$ y$ Z& V. G' j}6 N# B" y  D+ K& S( t# a: Z$ d

8 D7 c* V; V5 H) Lchar *killzero(char *res,float result)
, M  e( \: Q7 P2 S{7 l3 A6 [0 U1 C+ J0 [  `" Z- _3 q
    int i;2 T( R' h! q) e4 n" b1 a
0 w$ i' y+ I6 y' O
    sprintf(res,"%f",result);- G9 n1 \6 z& h2 w. w
    i=(int)strlen(res)-1;" G9 \: Z. f: H" R$ U
    while(i&&res=='0')& S) B# v3 |1 Y. P
    {6 K# K% w" |: o1 u) R; A( B
        res='\0';' B5 F) j0 ]3 a$ z
        i--;
7 _' ~! A# N. L* ^    }/ J+ }$ j- c. J3 K# Z
    if(res=='.')6 c. |0 [' ^/ T+ C& L
        res='\0';
: {7 A) A5 Q( E0 x9 F4 t2 g* ]: {    return res;5 ?! I9 [$ p: s
}- y" E" ?- \9 {( D* ]2 P

; o4 E0 C: j2 ~- i* a0 Eint main()
% g, @& M1 X; Z# q6 i: G{# s  R' Q/ W5 D7 S" |$ [6 I: V
    char ch;! }7 Z9 s/ W7 d& U4 A# ~$ h
    char res[64];3 x3 @7 S+ D( u5 L$ L
    float result;
: r; i0 ^6 L3 S( E& ^    while(1)# R" a" T% F- s. q0 O/ w
    {2 c/ I9 \5 Q6 A, C( q$ F. G
        result=compute();
9 w8 n6 W* k7 C, A) h        printf("\nThe result is:%s\n",killzero(res,result));4 ?) w3 f5 S: e, G3 Z+ ~8 y  M, [
        printf("Do you want to continue(y/n)?:") ;
/ E9 A1 L& m) @# `- v        ch=getch();, j% |( {  T6 C% f; G. \8 `0 G
        putchar(ch);
- R3 @1 ^$ C0 W        if(ch=='n'||ch=='N')
6 k) j3 |- b) W            break;
( j' y# `8 t, T$ c        else
# B, @& k! e' p1 }2 E            system("cls");
; i8 }2 l2 L+ \! \- i+ a# }5 I    }) j& h. g7 c+ }# s! y
    return 0;* o  d# w% T  t  y& p
}
1 s2 E$ V% ?' }* o- t

: Y5 |5 w  H% ]- A+ o$ b: m[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]




欢迎光临 捌玖网络工作室 (http://www.89w.org/) Powered by Discuz! 7.2