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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
1 r7 @; e9 ^* U% P% m2 O+ {3 V程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=" i9 V* n0 |$ x0 |2 P  P, V- ~* C
/**************表达式计算器************/6 {7 _# ^- [) _# v( ~
#include <stdio.h>
7 Y. J% Y. C' X/ H" F6 m#include <stdlib.h>! _: e2 J  f; h: O  T
#include <string.h>$ \1 Z7 I2 [% J5 ~$ K1 G
#include <conio.h>
- |6 V% }$ ]8 ?; S0 G$ e; @0 x- ]#include <malloc.h>; ~% g# O0 D+ O$ @% J% O

$ \- u" D- U8 ]#define STACK_SIZE 100
5 q# M2 Z5 [, R# P) `, C# U, Z8 k#define APPEND_SIZE 10
& ]5 `9 L, g' o9 X# [9 e2 b
# ~( I5 K, x% o( Astruct SNode{' i& L% w% _  U4 P) v
    float data; /*存放操作数或者计算结果*/+ @; @2 S: x  T  x. C$ k
    char ch; /*存放运算符*/
( {' G. \% c% z% S3 e8 ^1 t};( u+ B! J7 X9 s  C, k% J5 p9 G* `8 A. Z

7 n% @2 O; h# A6 j" |2 r4 a3 L" qstruct Stack{
4 l4 ^, N4 q3 J5 i    SNode *top;
1 n# I/ q1 o6 c, b$ n    SNode *base;
9 |0 Y. l' K- S4 f5 A3 V: l    int size;
; ]% |4 |5 U+ n% q};
3 f; n/ \! `+ W3 O# D/ F/ L/ I& P2 N
/*栈操作函数*/
' @7 N+ q% g6 F0 ^0 g2 F. h: Rint InitStack(Stack &S); /*创建栈*/
& I5 p4 B# o0 @" j! B! |int DestroyStack(Stack &S); /*销毁栈*/; g/ u( c& D( I' N4 O2 Y
int ClearStack(Stack &S); /*清空栈*/
" }/ ~( y) y- C( I. o6 q9 |/ B, wint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
8 }4 h0 F7 r5 j) P: ^( Eint Push(Stack &S,SNode e); /*将结点e压入栈*/( s6 e& @' Q( Y# H
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/3 `. S! @# G7 c

( F! Z$ {' S+ d1 a2 b" y! E0 p/*表达式计算器相关函数*/
9 c" a& o+ ]( }+ echar get_precede(char s,char c); /*判断运算符s和c的优先级*/
6 I4 _$ P" m5 \1 o- aint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/6 e3 ?' M9 @2 J. S* A+ W- V! L
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/- ?8 M5 z3 I, l/ f
float compute(); /*表达式结算器主函数*/5 Q! l4 {, {8 A, |" e: b
char *killzero(float result); /*去掉结果后面的0*/   Q$ C) n; d' B5 Z/ f9 {# E

& c2 G  O4 J7 h" a) x1 F2 jint InitStack(Stack &S)
, \% R+ I8 E3 B* ^( j3 [{
3 ?# M7 ?! V; t6 `9 a- C- _, d7 r    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
' w4 k, a3 b% J# q3 Q/ Q5 X    if(S.base==NULL)4 w2 M+ z! k4 W% n0 @- H
    {6 N% \- Q# r# F; P
        printf("动态分配内存失败!");
/ @/ f: {% @+ [' l" I$ B        return -1;( V: h/ F. r$ u( m
    }
) l1 S+ P9 F. B* h$ c    S.top=S.base;
- r2 a8 B' D8 c1 [    S.size=STACK_SIZE;
9 E5 L4 X) M1 m- e    return 0;
1 Z+ t% ?$ I1 I4 J5 }}
8 Q* x0 v. X& k) f- N% L- q1 T$ M
int DestroyStack(Stack &S)
5 i! `2 u( @+ S7 b{& P2 u' e0 Q( I8 |0 O% R$ \1 s9 {  |
    free(S.base);5 F8 g5 Q/ C! c& L
    return 0;
0 f# O, m) [2 L}
3 d" ~; }5 _. t/ H3 T) e  ^1 o
" u( {7 ]/ `5 z& }int ClearStack(Stack &S)+ \! s' Q# X" M7 o
{
& Z  S4 e6 x2 h4 c2 x; p    S.top=S.base;
# m! Z% A) a& ~  ]) ]9 \    return 0;
; b8 a9 }+ d+ o: o1 R}
9 z; ^4 d  _  [$ \$ v  v0 x
: e+ \, r, U7 \. K4 mint GetTop(Stack S,SNode &e)
1 W; a7 g) m- J7 z{
2 o% t+ w) O8 u; U) A8 f6 _    if(S.top==S.base)
  r0 }' g5 W- d  b) G. M    {1 ~6 p1 }' x9 f% d
        printf("栈以为空!");* k7 N& u4 k- p& }5 G
        return -1;
( \. p- w& ?$ v2 n4 X4 F    }! R  H7 k8 s' P4 c! U
    e=*(S.top-1);# t2 C7 M% S- w  Y6 V! @' |) L
    return 0;& H4 L: X1 V# T
}9 ~! S$ b. W8 @; ^  ~6 S. c

9 J- I7 i  ~5 d5 ^: K: pint Push(Stack &S,SNode e)
- F: E+ n* b: c" [{
* l) H4 U; U8 M    if(S.top-S.base>=S.size)
/ B% }- U( N9 t1 j% C+ Q) O    {& U7 d$ @6 X! S: U  \- T# X/ g
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
' ~" P. Z) [) V' o+ Y# l        if(S.base==NULL)4 V! h" y/ I" \" c
        {4 z2 V# s9 j4 Q, q4 L$ e( ]
            printf("动态分配内存失败!");
3 N; @. [; c& [! W            return -1;
5 v6 |6 E; R) d$ B; ~) o8 [) A5 t        }$ x; B" [9 P) Q3 e+ @( \
        S.top=S.base+S.size;; }3 V9 ?3 i6 I9 L3 o
        S.size+=APPEND_SIZE;  @- o. j+ T% h1 D
    }
' U5 d+ |6 k0 g$ c4 N9 J; V    *S.top=e;$ }9 O5 V# b' R  g2 s$ y2 G( S/ a
    S.top++;
. o4 a4 D, Q" d. z    return 0;
8 k8 f# I: B) C}  ~/ h3 F8 v3 }5 t7 |& ?

, }: G( E- C( Vint Pop(Stack &S,SNode &e)
0 G; P+ k2 Q+ `) X3 H, ?; \% p5 ^{
2 f  s# Z4 c5 ?" q' N- g  l/ w    if(S.top==S.base)/ n6 g- k, x5 l2 G6 h- u
    {
) t7 `+ u: O, o% [1 m        printf("栈为空!");7 P  u! V+ Z2 Z% Z4 i( C8 w( `
        return -1;
7 `: j5 M# u' i) K" N% s, I. c    }
$ R( t) P; _/ J: F7 A6 }0 p    e=*(S.top-1);
# H, X- m* b, |9 t: S$ x    S.top--;
0 s4 H/ P! S6 {. n  V: t. \* p8 g1 D    return 0;8 Q. o& k) A0 ?+ ^- l
}
3 O( B5 X6 A) M% A& G# q: H8 m
6 f3 ~9 N: d6 ]) W4 `: }char get_precede(char s,char c)
6 k, I( z' i+ O0 E0 W: M' u{6 b+ o- i/ |( }# K5 F/ e
    switch(s)/ ?) \; l+ z5 _
    {: y" b- W: c% y- a) K) L3 l
        case '+':                 
0 X( a1 D; O/ `$ d1 N        case '-':% X" G) }- v1 N2 J  o# H& W" S, |
             if(c=='+'||c=='-')$ l, I% a9 [4 u7 A8 }1 `4 ?
                 return '>';/ i9 u, s! J& V% x
             else if(c=='*'||c=='/')" W8 H/ ~+ u4 e0 w, Q
                 return '<';
; c- P' U- f% R( G             else if(c=='(')
3 i8 L$ U( Y! t* Q% l                 return '<';
" K; H3 e2 {9 `, k: L             else if(c==')')4 E- u' ^( p' r6 D7 c
                 return '>';: n* x& t: X3 f; C2 ~& `2 ]' X0 {& R
             else
9 x( [5 Z7 O: f# |1 D1 a  I( R8 d7 N1 \                 return '>';. Z/ |+ V  G3 f$ P
        case '*':9 O9 Z3 U$ B: ^% @/ Z1 m
        case '/':
7 R6 Q/ z/ \) g& r8 D8 i             if(c=='+'||c=='-')) ?0 W3 S: N: J+ b3 E; T, J' d' A* B# ]
                 return '>';! I( r) ~6 J7 O' A" A
             else if(c=='*'||c=='/')5 l, ^% I2 W, [3 t
                 return '>';
" ?& F8 y+ d+ l- _$ P4 ~0 e             else if(c=='(')
# O0 Q( o% N5 A) ?4 T                 return '<';
+ a$ p& n6 X. t$ `             else if(c==')')
! \, S: L2 Z5 Q, i/ G                 return '>';9 _7 F0 F( U1 d, I% H  ?
             else: ?) @, K8 Y! g' M- j: Q. C
                 return '>';
9 A# N+ L1 f/ f4 g        case '(':
& }' \5 l6 [& v# n2 m: O1 V3 U             if(c=='+'||c=='-')0 H! \& Q- r8 p& n3 S1 a/ @
                 return '<';# j& R1 ]  z3 O( O
             else if(c=='*'||c=='/'), A  z4 h8 k) y+ c- X. t0 M* E
                 return '<';8 S  u: b0 s2 Q3 d( Z0 _# d! v" z
             else if(c=='(')
: A% V. @- r" y                 return '<';+ b" J, b, E% w$ S; I
             else if(c==')')
6 P/ r  @. y9 H3 P                 return '=';4 G9 m' \: L: \+ t" }7 |
             else
, {7 d4 E1 @* }3 W% X. l9 i                 return 'E';8 [* H( U6 y/ X
        case ')':1 z0 z2 H$ Z8 U; t7 y* i4 N. g! K
             if(c=='+'||c=='-')
  U3 \, R* k" M* i) T6 n                 return '>';
4 N: M- B/ U- [4 b             else if(c=='*'||c=='/')' m+ w$ y. N# j7 E( J5 ]6 b. ~' K
                 return '>';6 d% U* o: f: ?, {
             else if(c=='(')
0 E! K/ G' J- d! o, q2 g                 return 'E';
. m3 j5 V. n. T2 R# N* R& @8 A             else if(c==')')
1 L8 [0 g  w9 `5 `. f- l                 return '>';2 r1 p/ o0 X, n' u8 @
             else- I5 s8 R3 K# d  i; P: J3 X
                 return '>';
- S. a, }6 ?* Y; X0 h& `6 y- c        case '#':# \- s; o# ^5 [' S. v& l6 p" _
             if(c=='+'||c=='-')# L% \. ]: n; n0 _! Q$ O
                 return '<';
9 N) k/ K+ K7 q$ \  U  b* t6 |5 R             else if(c=='*'||c=='/')0 m6 @, c- P6 o( U5 B
                 return '<';7 r: _8 E* a+ W
             else if(c=='('). \5 f" F7 U1 Y
                 return '<';
! l2 f2 `, i# |3 V             else if(c==')')
6 |1 A! Z+ Q) k- o" f* Z                 return 'E';
* }) k5 Z$ U- l! \8 V             else
9 |! b( g2 }  k1 P                 return '=';
3 f/ ]- n- o1 o& ~3 B5 C2 c        default:
* }+ l' b; a' D" V" n0 h6 {; n6 V             break;: E% l" d, W3 n/ O! \
    }
; O. i3 d; a  ?" L; N    return 0;   
; V. U( F% {/ a$ s# {/ Z6 W}- c* ~0 [- |& l$ H- O  E. q

6 o, O/ b. x! t0 d) j9 v4 Y# Vint isOpr(char c)  \" k5 s9 @! P/ g
{
$ Z1 F1 M/ l4 V$ m1 c  U8 w    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
; |" F: x( u4 o7 ^! C6 [) q+ e        return 0;2 f& }  E. B/ K2 O+ Z
    else   E9 }0 W7 ^- k; w% N/ F
        return 1;
' `4 x+ J, r" [" m; {}& B2 c, o! z1 l" ^

# x" N* h0 |" u6 Y( j5 Hfloat operate(float x, char opr, float y)
1 {8 J  |, z+ {6 D{0 H; X6 m9 m$ _0 d3 a
    float result;$ g- |& k! r' x$ Q+ t7 @9 U
    switch (opr)5 U1 e" ], h$ j
    {
. O" w9 J5 V% t8 q% [        case '+': $ L: F* j4 T- N( p3 {
             result = x + y;
6 F* A- B9 r  e0 \6 u             break;
8 L. l* T; V9 |# T3 v* a3 v        case '-':
4 j9 X5 J1 y! V5 ]. h/ F; u             result = x - y;
6 \0 H+ n3 H) x7 c             break;
, E. M9 a+ F- {* _+ z8 o        case '*':
! ~, M* }2 O* H* E! l' i             result = x * y;
2 }5 `" V! Q( f3 g1 K5 y% a             break;
3 I: J7 U$ q: o, A        case '/': ' d5 J5 i. o& _! C8 g0 {/ j  d, B
             if (y == 0)
8 y0 m: e) F" Y: t' r/ X9 @' t             {
1 G: {6 t. t7 J' }& i' I                printf("Divided by zero!\n");& }+ E6 W- a4 P4 K' O
                return 0;
8 g5 p5 i$ o  }7 f4 }             }
3 z/ E7 A0 \/ J* z! m8 m             else
; ?" b6 U3 j' W0 D7 t( l  F             {; @# R0 a) P7 \" V  a' _% Q
                 result = x / y;
# o8 g4 P, ]5 p+ O0 @$ E                 break;1 h& X6 U0 `7 v: ^5 b& u
             }
; E5 v1 g' F; s3 V9 c       default:   h; e6 }- q' N9 C
             printf("Bad Input.\n");
0 m8 g. i" a* U2 k$ a             return 0;
3 X$ x3 ~5 t& `& N    }
* i6 V. }0 s3 t8 o& W    return result;& i8 o( Y4 U( F% X* ^3 }; P( U# d
}    : c* U. m" x3 X- O

( n' D# U3 ?: ], Z: f1 Z2 vfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
3 E8 T% G4 ?- `% X{6 M1 S  r% o) y0 ?- e" X$ K5 X2 x
    Stack optr,opnd;& G) u/ m+ r( z; Z" j0 j1 R
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;8 u2 Y( B# O: [8 Z' `
    char c;
  h2 T" u/ z+ r4 ?+ e    char buf[16];
# ?3 S  _; u8 c3 G" d    int i=0;/ S6 t2 a: T& I' T
   
- U, L% V$ E& F" d    InitStack(optr); /*用于寄存运算符*/
( T5 h& W  W/ ~, C9 t1 ]    InitStack(opnd); /*用于寄存操作数和计算结果*/
) u& g1 k) ^. \* g% Y9 g; s    memset(buf,0,sizeof(buf));
  Q4 O" n* e* M6 q/ M7 c    0 |: d1 f) z, U
    printf("Enter your expression:");
/ {; w$ H: ~/ Y$ E" N        
- j6 s9 K3 p" ], _0 C    opr_in.ch='#';% s9 [- Y1 T! d" @( `0 M% E* R* s
    Push(optr,opr_in); /*'#'入栈*/
" L0 O9 B/ I) K    GetTop(optr,opr_top);
& d" \7 R! S  g5 B8 g    c=getchar();# s! w" N3 c+ @# N+ a
    while(c!='='||opr_top.ch!='#')
0 a7 r3 `1 c$ }) E    {3 q# B6 L( W* H# n
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/# e7 c4 L7 u6 M3 q' s
        {5 r. `& F6 T0 ^: i0 D7 h# [' U
            buf=c;
6 j) i/ Q: b- T7 r            i++;
' q9 F! b, {1 R5 e& M            c=getchar();9 C' ^8 Y$ q. }8 t$ U2 j
        }
4 K, y/ n' h/ U        else /*是运算符*/* X# ?, z6 K. X2 |9 E4 n. R
        {* r# ?$ o' f; g- U$ N* Y
            buf='\0';5 D2 W8 k1 G- p0 [9 l( j1 x
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/) r0 J  `  Y7 O! A% D& ]( t
            {
0 i$ S0 r& V+ ~4 F! a                 opn_in.data=(float)atof(buf);
( c" ~4 S6 C' X; V" M                 Push(opnd,opn_in);7 V) J( o+ s. }, q0 O
                 printf("opnd入栈:[%f]\n",opn_in.data);2 ^: c: e4 w5 n( R. C+ `
                 i=0;
1 S! X( W2 x; k* j* c                 memset(buf,0,sizeof(buf));
" L9 W* w" K# E0 u; z& i6 u            }
! P5 N, X; j0 Z: O+ u2 i2 f            opr_in.ch=c;
( ~: ^9 `1 X1 E, C* w            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/: ~. x; h/ ]- ?
            {
) A1 i* ^6 \4 }  x2 ^2 L5 I  a                case '<': /*优先级小于栈顶结点,则运算符入栈*/
; ~; j$ N( i4 M7 e& s5 [                     Push(optr,opr_in);
* n! D- m2 }8 R. \% ]7 e! h                     printf("optr入栈:[%c]\n",opr_in.ch);
/ [: a; a, f% v                     c=getchar();! x- r# m: w( l' P  v; ^) n
                     break;
% I: `0 j" P  z7 `+ M# B% x" ?; b                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
) O9 K+ o2 g; j( G& u5 l                     Pop(optr,e);* J1 F: ^' O& n! a& j$ B1 ]
                     printf("optr出栈:去掉括号\n");
" X) y9 t/ ^9 P                     c=getchar();
9 r6 z  e0 m; U9 V5 k0 T                     break;
5 T8 B0 W2 Z* A$ ]) u                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
- U% y2 q5 _) v  p                     Pop(optr,opr_t);% d' u- U' A  d8 c* ?2 K
                     printf("optr出栈:[%c]\n",opr_t.ch);
7 ^9 \2 J( |2 P                     if(Pop(opnd,b)<0)$ `2 n& X! U( J) N1 L7 r9 a
                     {( e+ h9 A& b3 e) C0 b
                         printf("Bad Input!\n");
3 l/ V+ M8 v* C& {9 z% }                         fflush(stdin);) b' P7 s! @  T
                         return -1;
7 |6 a  S5 ]: n0 f& p                     }2 q- b' F9 S4 O7 P
                     printf("opnd出栈:[%f]\n",b.data);
& ?, a: x. @7 ~7 D2 |# U. A8 s                     if(Pop(opnd,a)<0)9 F: ?' t( ]0 g$ g
                     {4 y* i. T  \1 w7 S
                         printf("Bad Input!\n");
" Y9 o: b/ \, j# C3 D) K                         fflush(stdin);. ]( b6 q% l6 K& `
                         return -1;
6 P3 M- h0 S6 |9 J2 H1 A- i                     }9 i6 S4 D4 @. a1 U$ ]5 T- L% x
                     printf("opnd出栈:[%f]\n",a.data);7 F; l/ ?" V+ [3 h
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
) h+ }+ b4 E/ l                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
2 o6 m; T6 d' {' L0 ~/ k, t                     printf("结果入栈:[%f]\n",opn_tmp.data);0 x+ R2 Y% k; @% ~, q7 }0 u
                     break;
7 v& |& h+ N: I/ U- C& t            }* P" _# L' \' u$ V
        }# B6 K! V- g$ L  ^- J" j3 N
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                / Y. d% h# j8 L+ }# q
    }
( r8 a+ Q( y9 c9 T$ e    GetTop(opnd,opn_tmp);" l. `$ F" C# ?, A
    DestroyStack(optr);
) ^9 g& w& q4 w  c" X$ L    DestroyStack(opnd);
2 ^+ U7 U, ]% f    return opn_tmp.data;& m4 L* t9 Q8 M  G3 J1 o9 `
}
! I8 u! s: g+ J( h& Y1 S# R+ x: z# x% [% ~
char *killzero(char *res,float result)
8 c* M. F6 W5 G. L) m& g* A) @4 T{: J* M. T; [0 w: T" T* K. ]" O" P
    int i;' |' e9 ^2 c+ ^" x- Q, `, ]: v9 z

) E+ m# \& y9 t& o$ S1 v" B    sprintf(res,"%f",result);# [* u* b  \/ p/ M0 |- e  X2 P
    i=(int)strlen(res)-1;  J# G4 E) O0 V9 f1 Y5 S2 ~
    while(i&&res=='0')2 W. r$ D. C) V' }8 t, \' d2 t
    {
. q* j) R4 t/ k; f: N        res='\0';
  U  K, Q) a3 H: Y3 n! v0 M        i--;, ]9 M4 g' W5 H0 @4 M0 }
    }
! {# T0 {4 H4 m( t1 ?; w6 c    if(res=='.')( m6 g8 p7 U5 ^( R  f8 s' B
        res='\0';2 g' I  @2 n, u3 G2 a3 S; h
    return res;
2 _1 O3 w4 j2 s}* M& Q/ r% z# l8 _( b
5 C) s' r. x! V/ N% ?( `8 `$ K
int main()) F) r) o/ P0 x+ t% R+ W
{! l) u# E3 ^2 m
    char ch;: R4 N1 ]6 j+ O. ?1 r$ [
    char res[64];6 R$ r& W0 d# t5 t  H+ K% b
    float result;
; K! S- l9 P( Q    while(1)
" k! K( o" T, x: _    {6 H2 P5 U% o8 Z8 K5 H3 j9 ?
        result=compute();
( G: P9 D# l# F5 @: Z  Y        printf("\nThe result is:%s\n",killzero(res,result));1 i3 M" x& m) ?! D
        printf("Do you want to continue(y/n)?:") ;  g+ F3 g: ^* x, F; r
        ch=getch();
) l0 @) n/ J: w: G. B" P- `        putchar(ch);
& l! Q0 b- P1 a9 c+ ?$ F        if(ch=='n'||ch=='N')
! [; M+ _% H2 X0 G) O            break;: d" ^# q) h% l) k  Y
        else
' U. Y/ {: i6 V6 ~/ U            system("cls");
* l! G9 p" }3 A, O# A- L3 a    }
% @$ q7 U. E! A3 P    return 0;
1 E5 C3 k$ N4 L: I6 h}

) x$ M! n, [" a  I( k# V% D7 k# s: w5 l  R6 f: }+ ^
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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