Board logo

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

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

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
! n3 w! [; Q( j7 d程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=6 l5 Q  t+ C$ T$ O. b% C9 K% q0 z
/**************表达式计算器************/
# c- N+ x% O' n#include <stdio.h>
! e8 B6 h2 K. t4 x: g#include <stdlib.h>4 s" z9 v4 T. |' Z
#include <string.h>
4 q# B6 D" v! i#include <conio.h>/ V* f% u# w: Y& a# X& g4 E4 p
#include <malloc.h>
% q) S. _3 V7 v/ ?: h4 }
  K/ n3 {4 Z: O7 c#define STACK_SIZE 100) n% }3 N, [$ _
#define APPEND_SIZE 10
8 t" c7 Y. V$ m
  n7 O& b+ w2 h) F- N' e, w; estruct SNode{& }" f8 C. U/ P! P: J+ n" {# D
    float data; /*存放操作数或者计算结果*/
  I' q# X4 @" d6 O    char ch; /*存放运算符*/
, n+ U( L; `) ~* u8 D* m' @4 j8 O& h/ O};3 A3 y* C# X: l( }( k

2 S8 F; D& \! qstruct Stack{
) N# l5 L" k% Y- e6 [4 I& ]    SNode *top;5 j9 J3 h/ B3 e2 h7 i
    SNode *base;/ |; ]& J& w+ `! f: a! r: J
    int size;
; ^2 c4 n! a$ ?# p) j$ I};1 `3 k' ]! y5 P4 o2 j' E- B' p( e$ _

- U" H3 {5 [) }/*栈操作函数*/
0 t( E( h1 y+ ~. A; h5 J( r8 Bint InitStack(Stack &S); /*创建栈*/5 E9 L, ^6 J2 u* F& g- M
int DestroyStack(Stack &S); /*销毁栈*/+ F2 ^  D- Y" f( `* Y% u
int ClearStack(Stack &S); /*清空栈*/
6 b. B* G: I7 fint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/' {' q/ c) i5 A# M
int Push(Stack &S,SNode e); /*将结点e压入栈*// j: d8 S! n: J+ ?
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
1 v; B- V( k) D: {  s
4 v: u* w6 r, G2 X# O/*表达式计算器相关函数*/! o$ f" N+ M3 C
char get_precede(char s,char c); /*判断运算符s和c的优先级*/+ ?: h9 Y: S7 ~4 a' y* l) m+ X; |' }9 G
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/& W" D4 }& T$ E( K* K0 x5 n
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/$ j" t- d; C* E# |
float compute(); /*表达式结算器主函数*/
, {6 D$ E$ X. ychar *killzero(float result); /*去掉结果后面的0*/ * S& O7 a0 L9 K* |
3 Q" |# Y* v2 O. F8 Q
int InitStack(Stack &S)& o" B* h( S: G3 m) g
{, H( D9 q: C& `3 y
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));' o/ q3 e0 ~0 w! |
    if(S.base==NULL)
; T" l$ G7 i9 V9 Y* s4 d    {1 g" v% ]9 v% I( G8 p
        printf("动态分配内存失败!");
& W4 D! D$ d' Y5 _, V. p" ]        return -1;" T% O" W7 J; D
    }! a* M1 Z  U  {: r! o
    S.top=S.base;; Z0 S& H, v* V+ p
    S.size=STACK_SIZE;# Z8 F! M) Z  y3 x2 ?
    return 0;
, s* Y) B  o7 z7 B7 p% N1 {2 F}
" ~' i3 k, f& ]
& D4 O! i( L3 d" U4 g9 D8 w! xint DestroyStack(Stack &S)2 u% @% b* p- t, f
{" E3 |7 `; }& Y1 C
    free(S.base);- ]% n8 J4 l% {% ^# N- ]
    return 0;, n% ^/ N  U0 c: F- d* v
}
  T( P) M4 F7 Z9 {' t2 z& \4 b+ C
, N* k9 x4 \1 n4 A8 s$ eint ClearStack(Stack &S)6 ~9 s$ c' ~- F$ |* [
{
) W2 f; \( }6 u# ~  f* u- k# _    S.top=S.base;
7 d' W  j  @+ x2 y: [6 N    return 0;# q& R& Y) W$ X' R; {
}
7 g# i! Q8 |( p/ R% S/ y' I9 f4 X/ t/ x9 d" R: I+ ~0 Z/ S3 |
int GetTop(Stack S,SNode &e)
3 ~) t5 e# ^4 B& d5 C{* J+ I  h- ]8 V) B) X& W. V' v
    if(S.top==S.base)8 l( [, Q; `4 Z3 z2 i
    {) x( j9 q# r- f. M& X! w$ `3 A& P% E
        printf("栈以为空!");
% R5 G& U) w' m( E8 N        return -1;
" s. q: O/ I" C# x$ J8 k    }( m! e3 ~. X) V% r' B$ q7 u
    e=*(S.top-1);
! ]3 T. r( k9 c    return 0;# |( z, J3 y4 K- s
}- y4 y! S) e1 W
/ p6 B" i* S7 n) D
int Push(Stack &S,SNode e)
) W) R% b( h* m: P{' J0 E* G# Z' [- Z4 `
    if(S.top-S.base>=S.size)
2 a4 J' A1 c2 Y  w! M% ?* z/ i) w% T    {* {) x/ r% s: h& ]! {* l1 K
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
* A9 @; s6 d5 S        if(S.base==NULL)
" ]7 a: Y: ?! \" X" D- }) \! J        {9 c( I+ O; t8 ?! u4 E# D! R8 W
            printf("动态分配内存失败!");* I& B# Y! ?+ Y* O5 h0 ?7 `3 d
            return -1;
+ l" D( `$ _" o4 n6 y& _) M( Z3 _        }
2 C# ]; [* R: S% X8 N        S.top=S.base+S.size;
( O( _' F: v9 ~3 `        S.size+=APPEND_SIZE;3 q# [8 d1 ]9 c  k2 E% P
    }
: t2 D/ b1 o9 ~    *S.top=e;
% M" s$ E  d: F0 h" G    S.top++;' ]! U- i9 Z- }" X: N
    return 0;3 O0 @. b3 \7 H+ C, ~5 v3 U# k- A$ L
}/ a: u7 J+ Q1 o3 |

" j9 X( w3 j3 e7 v3 D) k- ?int Pop(Stack &S,SNode &e)
. E& C" s* D5 [0 O5 @' [- r1 s' `{- K) [! ~  C8 m. _' m6 S) A+ n
    if(S.top==S.base)
' ^# [0 u. d9 n! Y! A    {3 q/ w3 v3 n2 }/ Z2 _9 F3 v2 i
        printf("栈为空!");
6 S1 u3 U- Q. T6 H% J: m/ Q, i        return -1;
* E/ E: G! z7 T! f% b5 {) i0 P    }
2 h2 x8 g( T8 R5 t* q( g    e=*(S.top-1);
% M' E2 m1 }  ^. o/ p9 J* R2 n  T    S.top--;- \; N; e5 }  B3 L7 D- Q
    return 0;6 i3 A9 ~6 Y9 W
}
+ A' x7 _8 n( Q2 {. P! u! m5 A! _/ r6 i8 T: f! N! N0 }
char get_precede(char s,char c)
) o1 O8 z8 _8 H3 g3 g/ @{9 W+ K8 o! ~) Q2 G
    switch(s)6 o$ o" P( V6 h0 v) }8 f2 j' p" C
    {
# Q/ O8 w2 P+ \; M/ t7 W        case '+':                 
% l: j2 R1 C3 Y+ T  v9 i        case '-':, t3 q5 G6 v0 c
             if(c=='+'||c=='-')
; ?; l0 E. T9 t+ F* z                 return '>';# @) V% `: I$ O2 s! a6 V
             else if(c=='*'||c=='/')8 q9 @0 a. F0 o1 K; n* k2 l% Q
                 return '<';
: C% ^+ M. d) w: x             else if(c=='(')
0 D4 S. N7 [5 o' T& y& G4 E                 return '<';
* W9 }# B+ ]4 G: _             else if(c==')')
2 i7 S" n) a1 \8 T                 return '>';
5 P3 r) W$ M( u* Y             else
) H& T+ v" \4 L2 p                 return '>';4 w: ]' l) ^- M% e
        case '*':% B, \8 x, f) m# M8 z7 O; _" [
        case '/':8 ^/ w/ ~0 Z2 c2 \8 t* d( d6 @
             if(c=='+'||c=='-')
7 k. Z+ I; A# |6 I                 return '>';, k1 K- U! M8 W: a
             else if(c=='*'||c=='/')
5 }! i) }) {' ?. I# U: F                 return '>';& Y  N7 A& X6 w. y. i
             else if(c=='(')4 t8 i& F. U- g( R4 G3 ^  `
                 return '<';
6 o! d6 _# o& O* u" e. E             else if(c==')')
  n( Z% {3 \. n9 P1 ^" U1 J                 return '>';0 z; ~8 ]4 J  F6 w' [) j
             else
+ \: R- H9 N% H/ z: m, @                 return '>';* j! _0 Z3 X+ g
        case '(':
6 `! R; i1 f5 t4 r0 s. F             if(c=='+'||c=='-')
$ l5 M, G5 x9 m! N" k                 return '<';
- o/ t: N1 ~6 T4 n             else if(c=='*'||c=='/')
2 E- u0 c! y1 Z0 I: S                 return '<';: o3 k; i: h7 k0 p2 W0 Z
             else if(c=='(')
( j9 C8 j7 I$ V9 U$ G                 return '<';
% H, C* Y' P+ j" r: f             else if(c==')')" L( S2 j, ^! k5 _* c, R# V
                 return '=';
& X7 Y" f4 A: M             else
; f4 D( M( b( H0 q5 J3 L! t& Z3 K                 return 'E';+ j0 Z; E2 K& n# Q- p, f2 b
        case ')':
. W. W  Y7 O% i             if(c=='+'||c=='-')
, w) L1 v. m1 W% y# k                 return '>';! a" }" z0 B+ s9 c: I! `) e/ s( [0 I1 X6 _
             else if(c=='*'||c=='/')5 j# k- Y* ?3 @) [' W( q
                 return '>';
6 `  J7 q1 N+ g* }! b# o; X2 r  j             else if(c=='(')" z* w- b  L  n) {! b) T0 M  i
                 return 'E';; r8 n( K* C6 Q& w- e
             else if(c==')')
# J3 ~" Q' a5 I( \5 L  k                 return '>';
" W& J, H$ Q0 J; H0 @! N9 J& d             else
% `; `0 c& y& C+ Y! G4 M! b: D                 return '>';
3 T+ c3 X/ {+ q; p# w8 i5 w& N        case '#':* Q+ k) j: j7 `: g: s
             if(c=='+'||c=='-'): @" s/ G5 k* t% M* h+ Q: H
                 return '<';
- `0 s. P& d( J0 k1 s1 {3 r             else if(c=='*'||c=='/')) i- o$ H0 a. ^5 |: H  u/ c
                 return '<';
0 U1 \. x2 P! v" w( q% s             else if(c=='(')) X3 s5 S' r1 }, V
                 return '<';
( B& B# m& W) R5 z             else if(c==')')& U+ D$ O- \0 L! c0 G
                 return 'E';9 z* l* `' u' Q: E. W/ T6 d* ]' D5 t; }
             else
" D$ f! ]+ H" K1 s                 return '=';) d" I" D& J, h2 `/ `
        default:
( O' A7 S, G' m: |             break;
$ G% V  c5 v. H$ }. j) z    }
+ Q# x3 o, d5 F1 e  C; H4 l    return 0;    9 Q  s% w$ d8 V# X/ o# t
}! }5 B* }1 P; h( V

7 B# K5 b) z) b3 T6 Iint isOpr(char c)
* G% W' q' H- N# W: U* B{1 X3 q& A' }2 Q$ ]: f9 g
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')1 U, C3 n$ d' w9 R2 w: q
        return 0;
4 c9 d( S0 o$ g( |! Q2 n! {, Y& z    else
" q* q1 g4 R. ]5 y  B9 _        return 1;
! f' A  q. D8 a}
, N  y' W4 X. N8 K/ ?; o( `- ]- }& y  v' G' @0 b
float operate(float x, char opr, float y)( R8 j; o% h2 C9 [
{
- P+ L, g0 w2 M6 ?$ [, T    float result;
4 i" B/ L5 U. \/ J8 H    switch (opr)4 D: |6 z& ?3 l. K
    {% e3 Y. f$ j/ c# J- c1 l- X
        case '+':
" M6 T: b: `8 A. [1 N: z! `             result = x + y;
% g' n; C4 M5 ^' k2 j6 S& M1 T             break;5 |6 P: t1 A8 T) w. H
        case '-':
" A0 {3 O, d4 C5 a             result = x - y;
) R8 Y0 {' e4 @/ V             break;3 w' ?& q3 ~" C' w7 n
        case '*':
4 Y! T7 k4 i$ v4 `4 Y6 _2 N! R; Z             result = x * y;
$ J! R' \5 H" x+ O; }. M2 o# [, {             break;: O: }5 s# w7 R* Y8 b* @; u
        case '/': * i9 d+ y) J; E& f2 t
             if (y == 0)
8 t+ O( N2 s- W  [7 \" @  J             {  L. {9 R! B; }% ]
                printf("Divided by zero!\n");$ B5 ?  E) y, G/ X( i! T
                return 0;
  J, @& r; q0 H( F             }% p" P7 ]% J2 c5 m# C" j" G, [
             else5 R: k) E/ L" k* C4 F4 D8 B
             {9 e0 ?3 ?) S+ v" Q
                 result = x / y;
' a# g/ o6 v: O3 n5 q" G                 break;& R; k3 O5 n) s4 F- P
             }
6 y" i8 V# o# \       default:
& |' E4 L* V: n$ K' r4 X             printf("Bad Input.\n");
! j" M! a" d- @8 O2 \4 b% k             return 0;0 x" h; R6 l! B* |% z$ j2 Q4 M% m
    }0 {7 A$ N7 m( I! }2 j" m9 g
    return result;  x. O$ Z/ S! `% Q# H  b( F! f! O
}    3 i# ?3 [/ k3 X) T7 @/ y
" c' O( L! X$ `" U1 Q' X% |; z
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
' g+ a* r3 v- {{
/ {! z; M; m- d% q5 e    Stack optr,opnd;
; [! L7 ?6 J& M8 m! H    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;& }! r" y; c- {( A, U: x
    char c;1 i/ I  Q8 \+ ^/ m/ q$ H
    char buf[16];
  B, S- A0 |5 V2 W9 ~' O. b    int i=0;9 W! U( T& G( M: T, S
    3 t1 D6 h  ^" t- K8 i
    InitStack(optr); /*用于寄存运算符*/
8 }+ z. R0 [  u  M  N    InitStack(opnd); /*用于寄存操作数和计算结果*// J5 K- j' D6 K/ m! N
    memset(buf,0,sizeof(buf));
/ `5 E( q; x, Z( r# n   
8 n) o& u( \. ~' v    printf("Enter your expression:");
5 I& @/ K$ J8 \1 E4 ]$ o. r        
3 V  k9 L1 A7 U9 W. L& r    opr_in.ch='#';7 I: ^7 y2 z; U( z% _  |
    Push(optr,opr_in); /*'#'入栈*/
, E$ x9 `* Y% _1 a9 H+ r    GetTop(optr,opr_top);
5 [2 ~0 I( n( w3 [: n7 Z    c=getchar();" ]! t& n& r' j, t5 B( B
    while(c!='='||opr_top.ch!='#')* P" E$ A+ N0 b3 A' \. I
    {
2 C9 f2 k7 t4 B; N1 z$ R        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
9 l1 t, s8 G8 H) d( i+ V/ C        {: v" q/ }" Q* v0 X
            buf=c;
. a6 i- M  P7 a            i++;
2 D3 B3 H, J+ i6 l9 _            c=getchar();% s( C- w- H) `$ `4 ]
        }4 _2 W5 `: w/ K8 I% A1 E/ b& d
        else /*是运算符*/
; k  _' S0 v/ u7 a        {
) Z5 H7 a: R; L! F/ ~            buf='\0';
- f: V# h) B8 x5 z4 m' D6 f( @            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/, ?9 e) O/ B* E
            {- g6 V0 ]" H9 _1 o; ]/ Q. J
                 opn_in.data=(float)atof(buf);8 k4 H8 N! A& p) n7 z
                 Push(opnd,opn_in);
2 r, A; h# z% b  w/ U* C5 [/ O* B" \. Q                 printf("opnd入栈:[%f]\n",opn_in.data);
% n5 k( g1 b1 M5 F% G- ]* w$ e                 i=0;+ k7 n- V: I" r1 X/ d
                 memset(buf,0,sizeof(buf));
' p; w/ J1 S# V2 A( I/ A+ q            }2 q- ~8 w4 Q/ c0 L1 |
            opr_in.ch=c;
/ l# m6 y. r6 G4 Q            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/, |, T+ c- Z5 z  g( t6 V! C
            {
1 M$ K4 G( f) G( z3 F, v  i                case '<': /*优先级小于栈顶结点,则运算符入栈*/
4 z0 O( e" L3 w                     Push(optr,opr_in);
# V+ J" v+ g) H/ h# F                     printf("optr入栈:[%c]\n",opr_in.ch);' d& Y3 ?$ M2 Q5 M& U
                     c=getchar();
. y& T, j) D" V3 Q7 m                     break;
. V: ]! L0 ^5 Q                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/) A- R& H$ `. ~- `9 ?! X+ S  x
                     Pop(optr,e);$ ~: Q9 E$ M- O9 K6 i
                     printf("optr出栈:去掉括号\n");% E9 S; M: {0 f2 Q
                     c=getchar();; l0 d2 z2 p6 Q- ~9 J& G) m
                     break;- T3 n8 E0 g% }5 J; e' Q9 V2 t( Y
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/4 L  X! W% U+ x: l+ `* E# h5 A
                     Pop(optr,opr_t);0 d  n( B) C$ b. q) n
                     printf("optr出栈:[%c]\n",opr_t.ch);$ c# [) R# \4 ~5 J; I' B5 [
                     if(Pop(opnd,b)<0)
7 U8 N6 B# ~  k& q                     {
% K# N" Z2 y. y- X                         printf("Bad Input!\n");3 R8 d5 g( y/ t: z" n+ N
                         fflush(stdin);
# N# e1 Q4 S8 D& u                         return -1;. \7 L. J: F, q
                     }4 W8 S3 P+ b# K
                     printf("opnd出栈:[%f]\n",b.data);
1 r1 y( J+ x+ W( @% d0 Z                     if(Pop(opnd,a)<0): v8 P. J1 @8 W3 V" l
                     {* w" }# ~. P% f2 L+ F- E1 N! ?
                         printf("Bad Input!\n");
6 _; g) n: {' x# ?5 F* j) Q                         fflush(stdin);
7 s8 ?# ~9 a: a3 Q                         return -1;1 r/ j; }/ U/ r; f5 x
                     }, p# ~9 o' K8 A( f/ ^
                     printf("opnd出栈:[%f]\n",a.data);& O9 v: |# n5 }
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/1 a; _+ _. Q% ~. D) {
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/( S- I" P4 q6 z
                     printf("结果入栈:[%f]\n",opn_tmp.data);
9 ?0 ^2 B' C! p2 s$ w                     break;
# o& C( L3 s' C2 v7 o. h( H" X            }8 C. q& N/ P% h9 R, |& a9 G
        }
& C, {; F# ~- |+ Q        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
. O& h) r) w: j1 q" ?    }1 U/ q3 M, i  M) n6 _+ J2 m3 m
    GetTop(opnd,opn_tmp);
# C1 e' u6 p* `* w" [, W! g    DestroyStack(optr);
& p6 t5 I+ I  R    DestroyStack(opnd);
3 g! c- i$ [; x    return opn_tmp.data;
9 ^9 ?4 \) t7 O$ L" q}0 j0 @0 Z6 j8 i: T7 Y& K5 e
& D1 k8 z& h; O1 T( N6 m
char *killzero(char *res,float result)# c7 s9 H& ~5 g+ y, Z
{9 b2 i% B6 e: i5 G7 V
    int i;
. x2 E# N. Z( C( n& `
0 c% F8 M& w& i; d    sprintf(res,"%f",result);/ \, G9 R/ n9 j, F; L& [
    i=(int)strlen(res)-1;& R# x( p7 H$ b/ E
    while(i&&res=='0')( w# i. x. t3 q0 `% a* G4 d
    {
- W5 b/ V+ t0 Y% T$ |/ g( I) x% M        res='\0';
& d2 h# {4 d7 v( Y0 a        i--;
6 g- W  a. X" ?, J6 Q. e    }! X) x6 X. c! w3 y  c
    if(res=='.')- a7 |9 K' h" o/ R: u
        res='\0';7 V! w+ _  ]' G7 |' l1 ~4 ?. `/ k
    return res;) D- c3 h) E3 ?8 U- d9 j: J
}; K; D9 x% K  r8 u) t

5 \5 u  f5 R% `4 Q; Dint main()
1 w) l4 S5 q. |! O- e" q" R{
& w6 X2 [7 C2 A7 c8 z) |! j    char ch;
8 j6 d6 G, _1 |( M. H, R. ]0 `5 ?* g' `    char res[64];
0 l1 Y4 Y0 |+ Q* u6 a! J    float result;. K( s# p/ O: c/ h
    while(1)
0 p6 v# y/ |6 B    {
1 ~, s" f# l: {5 t' C; J4 {& P7 q        result=compute();- C- Y# J$ k3 ]" [3 W
        printf("\nThe result is:%s\n",killzero(res,result));: U. L: w3 c% }. j; Y0 _) k# K
        printf("Do you want to continue(y/n)?:") ;
( C3 l$ U& {6 ^0 R. V' G8 u        ch=getch();
  x! u% B; p- g& e0 Q6 n/ j        putchar(ch);; H3 L; x" @+ ^4 Q" P
        if(ch=='n'||ch=='N')1 f3 p  n7 U+ V; d. U" T
            break;: n/ a! p1 W+ `2 g# `
        else1 e/ y$ m# k% S2 J, a
            system("cls");
# E6 n- B$ o+ R    }- u% G% e1 G$ J3 O/ H4 D
    return 0;
( Y, w, S' F: J) b* f& B! L2 {! K8 D}
) j( |5 b# r9 }( S
' d% l' o/ q) ^, L0 H& t8 C
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]




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