返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
2 m$ B. u) b" x( E6 N程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
7 E7 `) j, L& N6 ^7 o! i  `% _/**************表达式计算器************/
2 ?9 ]' O; s) A! Q4 l& f! f#include <stdio.h>  k& b6 i3 Y) }  f( Z
#include <stdlib.h>! G# o5 N! t1 u$ S, ~
#include <string.h>
/ T! ^% w/ o* T  U. B: [; [  y/ r#include <conio.h>
' u/ w# h2 E1 p8 y+ w7 ^#include <malloc.h>
2 g/ o" T4 U' r7 e5 ]
$ [0 ^  ^+ g/ r) Y! C( y3 i#define STACK_SIZE 1002 c; H* d( q" p' G/ G1 Q
#define APPEND_SIZE 10
$ [7 p# t% O- o- q- p* j% i* v% B& [' f: a- m
struct SNode{
8 L3 m4 r6 R5 |# C; n    float data; /*存放操作数或者计算结果*/
' w1 Y) T, u; y5 f5 [( p( d    char ch; /*存放运算符*/6 C+ [- k0 d% T! W
};
: B2 E. T5 K, Y6 |& G3 r; V/ p- `2 p. D# O0 I. S" ?( U
struct Stack{: |: p/ @$ f+ V8 f6 T" P/ R4 e6 k
    SNode *top;
1 X! w% h, u, q% b    SNode *base;
. a1 u/ k2 ]- [; ^  I! x3 F/ W    int size;
2 Q5 Y: b$ ^4 q7 x  I( \' @& p};
* t7 i% F" C% b1 I0 O  b
8 e/ d$ V& h, B/*栈操作函数*/
/ V9 n; I* w! V* U* R0 y/ r" Nint InitStack(Stack &S); /*创建栈*/
* o( x! t$ R4 p( l. [2 gint DestroyStack(Stack &S); /*销毁栈*/
6 J% T; [$ O& ^9 R; k+ Eint ClearStack(Stack &S); /*清空栈*/+ C! G. {  o: `# q8 Q. w6 l  F. a
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
9 b# U" P* u% d+ G: Gint Push(Stack &S,SNode e); /*将结点e压入栈*/2 P! i7 q( K) h# q; R( F
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/, u. y- o3 V8 O2 s4 r1 i

8 ~/ ?$ [. Y6 |5 i7 f4 }6 O/*表达式计算器相关函数*/
6 L) w2 L, Z3 z! i* \char get_precede(char s,char c); /*判断运算符s和c的优先级*/
& @" I8 i2 v7 ~/ Lint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/! Z, l. @" P7 R- A( f
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/# q+ @0 {; q* I
float compute(); /*表达式结算器主函数*/
+ x& d- A' T9 Z% t4 t7 V' g2 pchar *killzero(float result); /*去掉结果后面的0*/
4 A" R) p- E5 G* F+ D) ?9 d4 ~
' g: j/ I8 p3 I, j/ P% c5 Rint InitStack(Stack &S)
& U/ L3 x# j2 [/ r) t$ Q{0 R1 t  \3 B- u
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));& |- b  C' K- m6 l6 @, X0 m
    if(S.base==NULL)
; O) ^7 {& v" o    {
: i( c4 H9 Z" t1 h2 {  o        printf("动态分配内存失败!");
9 X+ Z) D* P$ I        return -1;6 V. k# [3 |- A
    }
0 V0 H& m' D6 M  y; A    S.top=S.base;
4 z. U9 C2 q* s    S.size=STACK_SIZE;2 w" p% z, M2 ~; ^) n( C
    return 0;
: g, ]. ?0 l# X: |}0 [7 G0 l: y( W: _2 Y( x! S

% Q# J2 h6 I. w0 B1 vint DestroyStack(Stack &S)0 b7 [! Z/ ?8 c* a
{/ v* X" b! j' V8 S; |; _) H) G
    free(S.base);
- G( N+ C4 {7 D& w2 M    return 0;& d4 g0 v* R# @5 [
}. Q) _! O( q, N& N
/ F+ b5 ]+ ~0 b; i4 V2 ~+ ~3 X7 v. A
int ClearStack(Stack &S), j, m& d# w, F; B* U9 {
{3 X. i3 \. l  M! L, I( I; W
    S.top=S.base;
: t! @. C: }2 [    return 0;' v5 \: d# S* J  r' e; V5 ?' P+ D* g
}% W$ E# ~6 g# {2 J8 }1 C

. X3 @. T" W5 b/ A  K# h' |int GetTop(Stack S,SNode &e)& L% H: ^8 s7 k, N% u+ \; T1 O: ~
{( B% G  L7 V! h
    if(S.top==S.base)" k* S2 V7 T* K' r4 x
    {4 r  T" x4 i! k" R. j2 ^* P
        printf("栈以为空!");  D' ?+ H8 `' c0 m2 p- n# [2 b
        return -1;, g) o- G$ k- m( L. J
    }
8 y; `. F; F9 z" ]; a) Z    e=*(S.top-1);
$ I, l( Y% M* }0 j    return 0;
( G( z8 g8 i: l& @2 Q}) x: c! q9 S' ]

& j3 s2 u2 l. a/ ?0 X) W4 m) l3 x& tint Push(Stack &S,SNode e)
2 J7 P( f& C6 u% p5 R{
7 B0 |: t$ p  I8 I, r    if(S.top-S.base>=S.size)
' l! v$ n- a+ P) `4 b    {
  w! t) [, X$ t% C; U4 \        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));8 V2 p0 z& ^! ^& W! h
        if(S.base==NULL)
" ?! J% b) @3 v' Z; u, f        {: g3 m/ }  i) V; z' _" `2 Q
            printf("动态分配内存失败!");
) Q, c* e; _4 f# L" Z* c; s: A            return -1;7 C% M4 c, F; }$ F+ T9 [* a
        }
' d9 V/ n( G. z3 i1 `8 F        S.top=S.base+S.size;
1 _9 l# I) m& ~4 ?0 s0 `        S.size+=APPEND_SIZE;
/ K6 P$ W( @4 f; i% Q    }5 x- s3 ?9 z% b; l* g2 o8 @
    *S.top=e;
+ B0 ?( n0 ~, H6 U+ r5 Z    S.top++;+ x: G$ t: n4 F7 b% K; e. I2 J9 s
    return 0;2 f& e0 j, s7 S/ w& X& B' z8 i
}
% A! n4 J2 `7 V: B1 E1 J* J# T& E2 r8 o3 W& v/ L8 u- c3 R0 s
int Pop(Stack &S,SNode &e)7 h: v2 c6 E6 w" S
{
/ I0 q  h: D1 V8 O- b% Y+ j    if(S.top==S.base)2 j! g1 p5 r/ W: F5 s" j7 G
    {
* G- Y& q+ W! r) W: N) r+ Z        printf("栈为空!");
& Y/ h/ H" _, p; y& N4 `& D7 f        return -1;
" a0 c6 K8 ]* c- L" U( g/ x    }
$ X: L& E$ O; A/ N6 y) @1 P5 Y' \    e=*(S.top-1);
+ E2 h, E3 H3 I, L! ^+ c/ @9 J    S.top--;9 j$ l* L+ S) D6 K# m
    return 0;- L# z( k: h* N9 r; H
}
/ C( F/ c" Q! O' S" c! s
, X( }$ q9 r  E0 J" i. w- H. Vchar get_precede(char s,char c)$ a& H  ^: U+ r' b4 ]) P# ~% t
{! ~1 t( U) x0 I6 _
    switch(s)$ n( I) |! k0 [+ }/ ?
    {+ F3 T" ~& Y. ~8 e" z0 l
        case '+':                 
- ?& {+ T' P, q# K        case '-':* w; y) ?- f/ R; ^3 Y7 @$ @
             if(c=='+'||c=='-')
. z2 @( a# m! l3 d                 return '>';4 e! u2 @/ I/ Q* c" w
             else if(c=='*'||c=='/')' J5 a3 a9 e. S* N% R* T+ N6 h0 c
                 return '<';
( N# j9 d# j  Y. w             else if(c=='(')
9 W" E7 z, F9 C                 return '<';
( j8 j2 v# l( s- a  }2 ?; w             else if(c==')')' M8 n' g, O( b8 B; d+ Z7 X0 q
                 return '>';
  `% s- {/ o: B: m% i             else 6 L# i1 ?1 m* o0 `1 M  U0 n) l3 f
                 return '>';
# ^- |2 O) V' w; l6 T        case '*':  }" o$ y, Z- u. }1 ]2 @+ S/ C
        case '/':$ ?1 }' N  S4 w5 ?% y/ m5 ~; C
             if(c=='+'||c=='-')
8 [* j0 I0 M- B- }( d% w! j                 return '>';
2 o+ A+ Q# P7 k/ x* M4 A7 L* q             else if(c=='*'||c=='/')4 p9 d* J7 h+ s; z& ]# I& H8 U, H) ~
                 return '>';. T5 b' v8 G: ^% u
             else if(c=='(')
- h8 E# o! \7 p* \9 D+ [2 K, t                 return '<';
# ^3 ]/ K7 R/ f+ ^( K* M5 Z             else if(c==')')( O6 b5 S% q2 c
                 return '>';
! _% I# j9 U/ v9 F4 [) x. V  X             else6 R: ^% B/ j$ a& e0 ~
                 return '>';
: l# j* v2 z4 M/ ^/ F        case '(':
/ f. m' Q+ c, O* ]/ ^) C' h+ ]             if(c=='+'||c=='-')# I" Y2 O( t# j* |
                 return '<';5 [) Y7 e* a, P* w8 a
             else if(c=='*'||c=='/')
1 {" ^6 ]5 M) q                 return '<';
& e1 g! j% v& n: c             else if(c=='(')+ t4 D$ [' a6 F/ D+ ~& c
                 return '<';
+ J* q; [2 h7 x5 O) q             else if(c==')')/ g: Y" Q- `# Y/ y. j9 G# a9 a
                 return '=';) v5 S0 [, B6 R4 K
             else
$ ^' B3 P+ i" T! ?9 V; T                 return 'E';
6 ?" v5 j- S( h1 _5 Q1 D- C9 R        case ')':0 L* d$ _, X: v. n/ c
             if(c=='+'||c=='-')" s" c/ u) W0 M/ F! K
                 return '>';
6 e6 w6 I8 z6 t9 `; Y             else if(c=='*'||c=='/')
4 L3 c/ \, V( G0 Q                 return '>';+ z( A; G% o# u9 L6 s
             else if(c=='(')
( A9 Q) I/ y' p$ i                 return 'E';1 B1 l% U/ p8 l' [. p  o
             else if(c==')')
1 p' V& C3 q5 g9 Y# s                 return '>';
8 _$ r+ H& N. _& I  ^% H$ }             else
9 N* w% d3 d4 Q7 e: |                 return '>';5 X$ r, S. u& @6 S
        case '#':0 x+ w. W8 a1 p8 D& a7 Z6 |, d2 q
             if(c=='+'||c=='-')7 M+ `; {" ?) W5 j( E( o+ S
                 return '<';
  |) q2 d2 ^+ ?3 m3 v9 d# f  F             else if(c=='*'||c=='/')
* Z; C( N1 t  N/ a# ^& V                 return '<';1 A! N0 z/ S! x# j5 e0 Z3 t0 w+ U
             else if(c=='(')$ U, E; ]1 d. D" j; _
                 return '<';
9 u8 O" Z+ E( ~8 b! R             else if(c==')')3 T2 ~2 M7 ~8 p: A
                 return 'E';" P. e7 `8 ?) y9 s7 N( [
             else' ?8 L/ s( F9 g% x3 {$ Y
                 return '=';
# B$ R. v$ _' }/ M        default:
$ h, b" l7 V4 H$ p9 V: z1 M8 @             break;
2 M' c; N: K; F    }' K3 W4 a! w( b
    return 0;    & H0 p3 M0 ~4 q7 R2 }. Z6 c
}
  C9 ?/ \- I; O7 T0 i8 n+ a) A
1 k6 P$ B! B7 Z3 P! mint isOpr(char c)0 R  d7 m* m& m6 A% T7 G- L
{; o1 u  D# F  S
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
- u' e& y1 a) [# I4 j2 h        return 0;
/ G& I& Z/ V2 E6 E9 H8 b  c' j& J    else
5 A: d* ~5 e3 e6 A, [9 s" l        return 1;  d& G; }, M6 D, X; `
}
1 p& f/ ?; `. |& M; y( a! ?. K& k
" I6 D% b/ Q- U5 N$ ^float operate(float x, char opr, float y)
* N1 s3 M; g, B{
5 S8 o- t4 ~3 x    float result;$ B& A9 m  ~8 h# m
    switch (opr)
8 \4 J3 f) O" j* `6 w" G    {9 j  f& y! T; W0 j% |, D, I
        case '+':
: `8 C& O* {+ o, \             result = x + y;5 d6 p& \, ~+ a8 ]
             break;
1 q/ F: e" ]4 }2 Q; x  G        case '-':
1 I- e  [6 @$ r$ U! A             result = x - y;
1 `: ^) }! l# `             break;
! n6 o+ D1 a. m' W* u        case '*':
* q3 V! X* @- j+ C  \; G             result = x * y;
# K; d/ G& u' e) C# H             break;
- ~7 O  y; |8 y( U+ `        case '/':
* j" R" h6 m% k7 ^' }& G             if (y == 0)* M! Z. Y9 y/ X4 {1 b
             {) q; X7 }; ?% L% F* H/ k' Z
                printf("Divided by zero!\n");
) c6 ^9 H% B+ ~, o( k9 z' z  I                return 0;- l% n- x& A* P' r
             }
7 `) n4 y; c/ g' D) G0 h             else. [$ w% ]' o% N8 q  i8 |) Z6 o$ v
             {
! _8 |% W1 f7 |                 result = x / y;
) @% ]2 _# h! [0 C' z                 break;8 l: V/ D8 j! _2 B/ p+ F9 L
             }1 W7 i( T- D( [/ F5 j* W3 ~- U& M
       default:
8 y4 g- h% G6 U$ O+ ]5 G( J             printf("Bad Input.\n"); 8 x) u2 \3 E" W6 F: l% x" s7 q. @) g8 O
             return 0;
5 ?0 ^  i9 ?& x: J$ {* Z    }
5 w/ y( j* |4 {8 c    return result;
5 f& R: K+ I# C- H8 G}    ( o. o: z  d' m

8 R5 c$ Q: B8 ]& X8 J# ?float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/% a, t4 Y, s& S% k$ A$ s- I
{( u9 r: T% v( j# [+ y- F3 p+ d
    Stack optr,opnd;  N) O! Z- T6 p- Z3 D. v% G" S
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
* o; H; N8 T# H3 `    char c;
# v. B  f/ I. _0 |! ~2 s8 V    char buf[16];
$ M& ^( ~( |6 p% H/ ?    int i=0;3 m0 M) ]  ]8 Z' a: v
   
. i% I& v6 H+ ~    InitStack(optr); /*用于寄存运算符*/
: A" c/ \( m  q! m  |, T& w4 }    InitStack(opnd); /*用于寄存操作数和计算结果*/% w8 d" k; S' x2 @/ q) w
    memset(buf,0,sizeof(buf));
) a6 Z; ]1 F! q4 ^   
! J- Y6 B5 O$ h3 ]6 h    printf("Enter your expression:");# \; \( D7 _+ i, N6 J7 W/ ?
        
0 B  [  e/ q3 q    opr_in.ch='#';
$ O+ A" f- @3 v& a$ t) n+ ~    Push(optr,opr_in); /*'#'入栈*/. v6 d% Q5 O2 V4 U6 m; s
    GetTop(optr,opr_top);
6 w3 x/ U# U) {) b7 k8 ~    c=getchar();) A# O) X% o& |$ a2 P) \
    while(c!='='||opr_top.ch!='#'). ]2 B6 U9 J: D2 z! z9 h
    {1 T  @! @; b+ ]6 L/ M! U; e/ L8 I+ a
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
8 T7 K7 m( h% b. ^  l7 {8 z        {) P, _$ e6 s- j
            buf=c;7 i& D' w+ p) Y$ q
            i++;
4 L# _. X+ v% ~            c=getchar();4 l. q+ O1 E9 R! p) f
        }
% \$ c. D% D& t: y        else /*是运算符*/& _% ?, g2 A3 ~) t0 C
        {
3 e  T7 q: L3 O" B( Q. W, o, ]3 u1 b            buf='\0';
0 }# T& z$ |. g$ [0 k5 J            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/2 d2 g2 X- x. z* K: }' x
            {4 b6 F2 Z3 y( m5 _
                 opn_in.data=(float)atof(buf);0 d, D+ G) b( Q% y8 i
                 Push(opnd,opn_in);
- M; ?  r  x4 L( [, s                 printf("opnd入栈:[%f]\n",opn_in.data);
( m! H( r. g, G. q, _0 b) x2 J/ @                 i=0;1 E; e- @% V5 B1 b2 B$ d
                 memset(buf,0,sizeof(buf));+ f- [. M$ j4 ?
            }. O% x2 P2 @/ e% L9 p
            opr_in.ch=c;& c$ ?) D2 s7 |$ O
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
0 S4 o/ v  Y( F# K# R/ g' i2 T* F            {7 C& ]: o6 I( C! n4 w( r9 a
                case '<': /*优先级小于栈顶结点,则运算符入栈*/2 H( O1 i# g4 d7 ^& _
                     Push(optr,opr_in);
) |! @: r3 K9 X0 i0 _1 q- F                     printf("optr入栈:[%c]\n",opr_in.ch);
; q# F3 e( a9 r/ A7 `" B                     c=getchar();
$ J: R) l+ C2 |                     break;$ l4 E/ O' A- C6 t. Y8 s) ^
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
; X; K  D+ e9 F& u: a- L. |0 p1 `                     Pop(optr,e);
3 _( i! D: v3 t$ ]! z                     printf("optr出栈:去掉括号\n");3 y7 B; H0 v# t5 I" [6 \$ f
                     c=getchar();
* }& h- g1 X* o8 b& ?3 p% A  I0 |                     break;5 ~) F! m( s. W5 G
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
* r: s+ c8 t, M! S% B& d/ \                     Pop(optr,opr_t);
  O/ R: q4 d8 |5 r" }1 I) C- {  {  j                     printf("optr出栈:[%c]\n",opr_t.ch);
1 o7 B; N% N# J5 @5 @; d                     if(Pop(opnd,b)<0)
: V/ x' T9 g  `& v& ~+ a                     {" G& ]; [( E- S, K* K& _  w
                         printf("Bad Input!\n");* ~0 Y1 o- m, i7 P4 ~, A9 S! X. [
                         fflush(stdin);
3 v2 ?4 ]8 {) j% W; q" W                         return -1;+ ?) f9 G5 f* W9 g5 W
                     }2 V% B# _3 M( b, i2 O$ O
                     printf("opnd出栈:[%f]\n",b.data);3 W6 u7 w: W+ E; i
                     if(Pop(opnd,a)<0). z, R" ^' j2 V
                     {
, ?4 b+ J8 W0 Z9 ?                         printf("Bad Input!\n");
, E0 z% |; Z( R1 n7 \- E3 _+ \$ \, G                         fflush(stdin);8 s* ^7 N2 f0 J; @& Y
                         return -1;
0 F  s" f5 [0 L                     }5 l5 ~3 F' }2 G% U
                     printf("opnd出栈:[%f]\n",a.data);2 y: S8 N% E( p4 u' Y) F0 [
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/5 H4 ?2 J9 e6 a, ^$ ~  X1 t% R) n
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/1 C( v3 {* b7 @) H* I; t) O
                     printf("结果入栈:[%f]\n",opn_tmp.data);) `8 g8 u3 x% Q. X
                     break;
5 Q- P& b1 T7 o  u! o            }
7 \' R$ u/ m5 L; ^        }4 S( u$ q; u6 f8 _6 V# B
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
( L4 V! t& j, r! U0 X    }
! h' ^1 E" p1 B3 J    GetTop(opnd,opn_tmp);) m6 y7 w$ Q5 F" Y% D
    DestroyStack(optr);
" a8 R. ?, e7 u% A    DestroyStack(opnd);
7 K4 t/ `/ J' E; ~: o    return opn_tmp.data;
9 ?* q5 Y4 c- }5 L4 E' O1 t  M}
) u2 ]7 y; y6 |6 m% h5 h: E& D' q9 N0 W0 N
char *killzero(char *res,float result)
0 u0 ~& W5 w7 }) I{
' P7 g# N9 Y% \+ J* A5 d" G    int i;5 Q; Q! u9 |  S: s. k
* }5 i& `  z+ x1 [( r
    sprintf(res,"%f",result);
2 ^8 _8 I) g/ G    i=(int)strlen(res)-1;- j2 |2 y$ L. h: @- K* f& J
    while(i&&res=='0')# P. D. q. |6 g! u9 Z
    {
. v) V) B4 K( ^3 u* t8 c& d        res='\0';
- M( p$ S, Z5 w        i--;
6 K& ~& ~1 l( ]7 O1 f# A    }
$ Q& s$ l  n6 _( ^' P1 s% }! r6 \    if(res=='.')$ i+ n+ P9 e' E; a* N- a. C" y6 O
        res='\0';8 r/ w' \  e  B$ v4 n6 F. f1 g
    return res;
& P. e+ O" E6 x! n* f3 B}
& G7 E3 j' k/ T! `' x
/ C; Y) ?  u: j( `* k, b# [int main()' v* E  @; E  {# ]" z/ k8 n
{
% b7 J( j  n! r+ _$ P7 e8 Z    char ch;8 n6 l! X5 Y2 D! A
    char res[64];
. S% x3 c+ K) L' x9 T, N    float result;. ~7 {; ^* m0 _, a" s  E% C
    while(1)
/ l' n8 d( `2 A$ p    {$ }8 t# r/ m, H2 h( G
        result=compute();1 T" T+ R$ Z7 `/ D0 S6 a# d8 k
        printf("\nThe result is:%s\n",killzero(res,result));
7 i2 U* r" k% ]        printf("Do you want to continue(y/n)?:") ;7 h9 d( d& G+ n/ c, m
        ch=getch();
9 o# x! L: F& l3 _' R( z; ^        putchar(ch);# q: ?5 S! X0 x! H9 H. y5 y
        if(ch=='n'||ch=='N')
7 r+ H/ J9 N2 ~( t5 t            break;
4 x) _7 v6 z' L7 ^+ g) u        else. z+ U4 \& L$ d- s7 E/ e
            system("cls");: _5 E- Z' f7 h0 V7 r7 S
    }6 W3 j: j+ f+ L4 v
    return 0;
+ W* E" w+ i) A' S" e+ A) A5 q}

. x' S/ D2 ?* G
8 x  ~$ m  g# J! \. ~8 E& c8 e[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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