Board logo

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

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

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
: p# I2 ~* z% \' z% I1 r0 X程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=5 ?$ U5 d, w' H- [( r
/**************表达式计算器************/
$ N+ W% U0 G$ h8 z#include <stdio.h>5 J. z/ F% s3 y/ w9 J9 L5 |
#include <stdlib.h>
5 f7 {- j! M0 H* \; i#include <string.h>
) Y; ~0 I& D9 `#include <conio.h>- L/ b: g: J; C! h0 c  `9 U! ~4 D  O# G5 A
#include <malloc.h>, Q8 g. i5 O! N4 M6 D
: m- a. m- B0 W: q: _! L2 \
#define STACK_SIZE 100& F0 O  a- ~: Q: k  W  \6 `
#define APPEND_SIZE 10
( j& z/ l9 _; B6 B. B
# |1 z0 t4 |" m& b0 Rstruct SNode{1 |5 X' ?* S9 v- r0 M# Y/ `" H# ^
    float data; /*存放操作数或者计算结果*/7 Q' c$ W5 q' U4 ?* O, P- j* x+ w/ [
    char ch; /*存放运算符*// p, Z: f+ H( P$ x" M
};2 e5 j2 ?7 V# ^. m: k
+ p; I) d& b9 H% m. x6 A$ T
struct Stack{
: `3 K" d; t0 T$ K& x1 f! L' Q    SNode *top;0 _4 j6 X" ^/ O) ?
    SNode *base;
9 B+ e1 s1 z# _, s, T1 L    int size;
- T, X7 B' l$ l9 x% n" b( `8 u};9 k/ O; K8 ^$ ^
. b  {, j5 k8 j& Y2 Q
/*栈操作函数*/
+ F, S  M9 p+ e8 Vint InitStack(Stack &S); /*创建栈*/
6 B7 M% V0 x. q7 F4 bint DestroyStack(Stack &S); /*销毁栈*/: K8 ^- v) }  l) J# h0 W
int ClearStack(Stack &S); /*清空栈*/) A1 O- ^# [5 }( }( I# h" V* @' _8 T
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
( H# [4 J: b% x% i* b  F6 Pint Push(Stack &S,SNode e); /*将结点e压入栈*/7 s8 Y* A! q0 O2 W& R: ?. v6 w) [
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/. D1 r# |3 w" v! F+ j
6 x4 c( m* f+ W+ _4 E2 d. n
/*表达式计算器相关函数*/
5 ]" d0 x+ Z& X% y" n  u1 Bchar get_precede(char s,char c); /*判断运算符s和c的优先级*/+ D9 M; T2 j1 W9 k/ x, O$ a2 o
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/7 u4 t* j, f- e2 H' S
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
/ b, Y3 Q+ |  ~0 tfloat compute(); /*表达式结算器主函数*/
. D0 g# g% b6 l( b6 Q5 Rchar *killzero(float result); /*去掉结果后面的0*/ 6 p2 K! P) A  Z# Q6 q
) e8 _! N6 I2 ?8 R, N! Q
int InitStack(Stack &S)0 g. E" d. r, @& @
{+ R8 l6 [/ Y4 Z, A2 _
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));+ w8 g% N2 ?" W% _1 F1 S7 |
    if(S.base==NULL)
+ v. g+ V& u3 `/ j2 K- ]    {: z' H2 t) Y! a' q* L; d/ ~: o
        printf("动态分配内存失败!");
1 T1 z1 q4 ?; h        return -1;- w+ X' `: k7 s- C+ f
    }
8 N8 R; R' h' N4 u, B    S.top=S.base;* S* c0 b$ C& w4 a
    S.size=STACK_SIZE;
7 c* q- g6 J; ?; a  n    return 0;
* }- u; v8 k# O: t}
6 a9 k( o, m! R, C
( u' m9 ~. u) R1 eint DestroyStack(Stack &S)
4 Z2 j2 U7 ^8 P1 S$ P9 Y{: q4 w: P8 `4 a% F( q
    free(S.base);
& ?9 H1 c; g4 z# d& n    return 0;
& H7 v1 M% w. h) d}
1 l, a  [7 ]5 ?% t- U1 x! `$ K+ n3 P, p
int ClearStack(Stack &S)' o6 C7 _$ @( ~* X- F
{; h# W7 j! @) p) S3 P3 c5 A' z
    S.top=S.base;
8 [: Z$ t# d+ `3 i7 W' v    return 0;
- K8 Y  \& L! L* a( O# A1 ^) L}
* o% v* j. O% @& l, a; X9 r+ B, s( J3 @- V5 z$ ?
int GetTop(Stack S,SNode &e)$ d4 P& T7 ~0 m, v- H) {/ A
{" ]0 D8 |9 t% G- J
    if(S.top==S.base)
& b- s9 \3 b. [' a  k) ]- x    {
- C4 ]# k+ Q% C0 l+ p        printf("栈以为空!");
1 a" v3 ~, }  x5 X        return -1;
. Y& g. k$ J0 A    }
0 v! K5 v1 M, Y4 c( M! ]+ A    e=*(S.top-1);
$ l& O2 {0 k% O( P5 I+ H    return 0;' i% R/ [7 N, S6 ^/ ?
}
+ N' L4 Y2 ^4 k& A' r
& n0 J( R# S2 Eint Push(Stack &S,SNode e)$ k9 y# C1 O% {9 C  ~
{
5 ?# n0 L6 }, y6 T- @! _  a    if(S.top-S.base>=S.size)8 ?  \6 t9 D- a% R
    {
. F" }- q9 H$ d3 _9 y; k# @9 ^+ w        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
% r( Q7 t; P; F+ p        if(S.base==NULL)
. ?; x) }! c# O0 K. J3 P        {
* u' X' ^# \" F            printf("动态分配内存失败!");
% @3 E/ S/ O# [9 M            return -1;3 A: @! X8 ^: }9 B& k
        }
( J$ a# R0 B; w, d, Y# K+ o0 W        S.top=S.base+S.size;+ m6 V5 n* @! r3 k+ [" z
        S.size+=APPEND_SIZE;
  C4 z; n5 Y2 c0 j9 v0 J    }+ l( g/ H# |& x1 I2 H
    *S.top=e;5 z8 b& r/ E5 ]3 s7 i0 e4 Y
    S.top++;
" N3 J( ~1 w2 U  Z: _+ r    return 0;
6 R. b$ J9 h3 l" s% L: F}
+ ~( U2 u! o/ k+ u$ S" H7 y  U, w" Y# d' |( \6 `+ E7 H" _
int Pop(Stack &S,SNode &e)
. w7 C1 ^/ N. C* z, G; v{8 T8 Y0 b6 [% w
    if(S.top==S.base)
3 _9 R4 m6 E' P. I. g! v    {1 a' v3 L" B! ]" w" ]  a* k
        printf("栈为空!");! P: g# l+ P! U* |- @* C
        return -1;2 M! r) `1 b# \3 A* b
    }
+ v# X5 ~. Y& w' A( T" J    e=*(S.top-1);
$ s' b! g+ r# {3 G    S.top--;
. I; M9 S8 u9 Q0 ~7 ~    return 0;  n! M( W5 m) I' X0 e
}6 B( c+ i  w4 g& u1 }

! v* z  s3 W' L5 @char get_precede(char s,char c)' c7 \- O- N$ Y$ m9 M' z$ f
{
4 @/ m8 S) W; U4 ~    switch(s)
6 f; ~' R, |: E: i1 J+ L6 ?    {5 @4 y* G2 Q9 o$ s4 Y
        case '+':                 
- b0 D" Q' u- r# U$ _$ p        case '-':
/ |6 H* }: w$ f             if(c=='+'||c=='-')
  q6 ~% e% l# N  h" K) U7 E                 return '>';, O) ]) E1 Q9 n0 Z( v+ t# F
             else if(c=='*'||c=='/')
1 A5 C7 Z& e, Z4 Z* e+ b                 return '<';
, r) O% G2 e6 h1 A" Z             else if(c=='(')
5 N0 R, Z6 R5 U6 h2 V6 O7 L; q                 return '<';2 e6 ?9 @" f1 ?1 P; ~$ R2 O" }
             else if(c==')')3 C. y+ W/ s$ M0 I
                 return '>';
  z5 `9 n7 i. F5 u* ^/ K             else / k: m. r! f& w$ `2 s
                 return '>';
. `  C4 }1 B7 z! }$ L! b        case '*':
8 L# i( b$ b- A- f/ ~7 h        case '/':
6 V, f- o& B" N* Z: l8 Y! j8 H             if(c=='+'||c=='-')
8 T3 |- a. H4 A' ]! T2 G% \                 return '>';+ I8 s( e) {8 O% ?
             else if(c=='*'||c=='/')3 S% `! e; d: d2 j
                 return '>';( L: ~# u7 K2 [* D# t
             else if(c=='(')7 c1 D0 N' w+ B; i" W
                 return '<';
2 u4 }& P0 i4 ^+ j, L  o- \             else if(c==')')# N% M+ q8 [& b* b2 G" ^+ k
                 return '>';! ]0 i+ v& ^! H; h6 q3 m$ X* G* j
             else/ }5 O8 x0 d) O
                 return '>';
: W2 N0 Q; R0 }+ t        case '(':* N( r$ Q+ N2 J9 F& {' U) v
             if(c=='+'||c=='-')
) s4 U* [0 ]6 k. o  u/ m7 ?6 [8 d                 return '<';/ J( [( P8 m$ A) d" r- l
             else if(c=='*'||c=='/')
; n# @" U' ?/ F1 }: u' [                 return '<';
- Z1 s6 o6 s' q+ ?! E& E             else if(c=='('). H; M. C2 h) Q) m4 q( U$ ^, F
                 return '<';. f# a! J( b4 t$ a' s+ u
             else if(c==')')
( g: c4 ?0 K' h& Y3 H& l) s                 return '=';5 C$ u% G* _: |
             else9 s* E- T4 L1 `! F' x9 n1 {
                 return 'E';
7 z& d$ b- ^* `- s6 w( e        case ')':
# {+ m, j. x. x1 N, U9 h3 A             if(c=='+'||c=='-')
% W' g( p; X' T' p& u2 R) c, W. L! _                 return '>';
9 |# m- T: x+ {             else if(c=='*'||c=='/')) h$ U- F) ?( S' k: _$ E
                 return '>';
6 \2 h* U7 a3 R, K             else if(c=='(')
5 x) p4 \/ A& g5 a4 o                 return 'E';0 U. c4 U+ w6 P
             else if(c==')')
! R$ \4 Q" v- B! `0 l                 return '>';
: Z* R4 }/ Q1 C; j             else+ }( S* ~8 T* J, P7 D
                 return '>';
/ @6 O9 l* J2 l" R3 o" ?        case '#':
+ n6 F, A) y+ ?             if(c=='+'||c=='-'): x8 R" A9 v- E
                 return '<';
  P  E! O0 B. W4 X             else if(c=='*'||c=='/')6 A1 C. p  |. f. ^  [9 @1 x
                 return '<';5 p3 D! C8 g- f5 ?" J* ]
             else if(c=='(')
) \1 F3 e( z2 p  n3 K2 P& t                 return '<';) r1 T8 ]5 \) I& X' C( M. f
             else if(c==')')# t' ?0 Q. N! d* n9 i( Y
                 return 'E';
/ ]( M; o0 j6 n             else
/ p. Z+ w: F+ V8 }8 ^% y  `                 return '=';
# q, o. t) K5 p  g, b0 L        default:
  }0 g: o2 b: {+ B             break;0 J. q( p. Q# ~) o7 P
    }) e1 k" {: e. E- m! n) M
    return 0;   
9 S$ f. C. c1 f' N! `/ |1 z# r, Z}
) j7 x  y9 d4 E" V7 d$ F. z3 D3 k: s
int isOpr(char c)
% C. J) c* A0 r0 y: H. n. d. d+ K6 W{+ H1 |/ V6 @7 [
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')# W& P( r0 K+ S; e. x, }( L
        return 0;
. j/ _# c! r0 j! e  s    else 2 h8 c+ j0 n% v2 S  e% \' M" P/ I
        return 1;+ i. s  W3 [% x7 ]  F3 F
}
% h9 \1 B% ?& y8 h2 t- O- B  }) W5 J7 h$ m. X2 v/ B" w
float operate(float x, char opr, float y)
1 N, V) S: }1 |' A4 m5 e' e% q; [{) n, G5 V$ X% a' F
    float result;# H6 D) J/ H$ x3 G: M% {% Q; Z
    switch (opr)1 \. B) p, x" e0 Y  X6 V
    {
# J# ~) }, I0 _3 a, O% ?; ?9 j4 Z' G        case '+':
) |8 \% b. {$ h; E; U; |             result = x + y;
6 E: G. M0 H! A: h$ S6 c) O1 p! m             break;. f! I% e$ L- m
        case '-': - W7 _. W2 x2 r8 h, ^% h" a! _
             result = x - y;
$ h' {8 ~* h) n             break;7 e- N1 j9 [/ T+ s' y$ N) F
        case '*': 3 b+ ?: ~9 E! i% ?% ]; _6 c2 n
             result = x * y;$ h4 D) v4 X8 f" ~
             break;
- q& t! m  P; S) h1 |        case '/': " [+ D) V; q* ^4 s6 n; W
             if (y == 0)9 d8 c/ d- x8 U: l3 W% x; a4 Q
             {# B9 S. f9 V  T; f2 C/ {  R
                printf("Divided by zero!\n");) A+ C# C, h( X# w# z& T
                return 0;
8 x! g- d7 e/ c. }/ V* o. T8 X             }
8 V0 W1 x4 K8 H             else$ ^3 H; m3 q# C  ~+ J8 a/ t# P
             {) W, k3 p8 u, ]+ M+ U6 d- s
                 result = x / y;
* \$ B! B6 `% N# m                 break;
1 Z; o! C2 I# j8 k$ w             }
/ }+ @4 }2 {, \4 B  ~2 x; E' T8 K       default:
/ v  N7 s: g5 I             printf("Bad Input.\n");
6 B- P2 L' w. I' k0 Y             return 0;* k) v! v( {) i$ I1 x
    }% i4 m! g% N- [/ ~/ T
    return result;2 y4 R0 v1 N3 C' t5 a. f6 R
}    $ t6 n3 K, `3 d1 A

  Q( G* o+ \2 j' Lfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
5 [% U6 [  c7 i4 D& Q, Y{
# J, Y' o6 A. |    Stack optr,opnd;& ~) p5 [# b. H% ]& C; D+ H
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;1 l& x$ f1 p; [6 S
    char c;1 o6 T1 H! @6 p: M
    char buf[16];
5 w: v8 s1 n7 n: q$ L# N' y    int i=0;
2 l1 \! F, V; r3 M' P) \7 o    / l* m. Z. l0 e& ^( u. |
    InitStack(optr); /*用于寄存运算符*/! d5 N( r+ B6 s+ B3 F; z
    InitStack(opnd); /*用于寄存操作数和计算结果*/
! ?9 e2 ]2 _. k" z    memset(buf,0,sizeof(buf));
1 M1 o" Q: K* P) t   
5 }& \1 e# w: r    printf("Enter your expression:");, B; X" D% T9 I" [4 a$ m
        
) v0 F8 U" Q. q  w4 L    opr_in.ch='#';2 v  u7 L: T: Z9 w5 t, I% ~
    Push(optr,opr_in); /*'#'入栈*/
/ p# `1 C% g9 V& C8 f    GetTop(optr,opr_top);
- X+ D4 q$ {1 `4 L" F. t/ u7 ~    c=getchar();" d' e2 W5 i& W
    while(c!='='||opr_top.ch!='#')
5 T5 A* K1 [( f7 r    {
3 g" Q, k: Y3 D        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
! I5 B" p8 o8 T        {
0 l+ T( Q2 Z9 R: o. x+ e* @            buf=c;
* U4 }  P; R  I% Y7 L, X            i++;
2 h4 ?$ W6 {& K1 f4 d            c=getchar();, |* p0 |( @" \
        }
& U+ s& W! @  J3 u8 X        else /*是运算符*/
) i, ]% R4 T4 B: D; b        {
" f5 I9 o5 @; K( p0 e8 \            buf='\0';& F7 Q/ E3 `* ?' Y4 h4 _' e. e% X
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/: w+ q4 ?4 h* `$ R' Q) A5 q
            {
8 N5 b& L6 W1 W                 opn_in.data=(float)atof(buf);
4 _5 W  v0 G8 X5 ]% C                 Push(opnd,opn_in);9 s% d1 O6 k7 C, R
                 printf("opnd入栈:[%f]\n",opn_in.data);( ^' f  F; C# Q; Z: I3 f7 `
                 i=0;/ s: S2 |- E& `+ N2 i9 V* C7 L  ^
                 memset(buf,0,sizeof(buf));
4 q' b4 z6 K+ e% r  O            }
" |; Y* M& i5 C  ]! u6 a            opr_in.ch=c;
8 ?: B8 W' b( Y4 P2 l            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
: `; c# w* c% b% b  B$ n            {4 t% X- [0 l* F7 E& w
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
& t+ Y7 u- D  C4 D                     Push(optr,opr_in);
: X% v' j: \2 G1 h3 H0 v                     printf("optr入栈:[%c]\n",opr_in.ch);& F  I1 ?& V# P" b
                     c=getchar();
  N) T# ^9 T* ?6 l                     break;
/ u- d7 e3 r& O5 A& r; |                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/. v- f' F, N) z3 t7 b% n0 M
                     Pop(optr,e);
8 e! J" j* N, v7 e( S                     printf("optr出栈:去掉括号\n");
- s: B# _: w; \2 G+ p                     c=getchar();7 m. _$ I6 [2 H8 L) \8 m6 Y. C
                     break;  V6 T$ D0 I8 ~7 Q3 v# k" X, G
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/5 e, h) v: r. L' X7 |
                     Pop(optr,opr_t);
" W, q+ e' ~  Y& y$ N; H                     printf("optr出栈:[%c]\n",opr_t.ch);
6 \8 A. l6 n; t1 @; W- P                     if(Pop(opnd,b)<0)9 z* m+ m% W1 y9 V* u" r4 H- o
                     {
$ V6 m$ ~. Q0 n$ B0 b, r                         printf("Bad Input!\n");& `& @; S3 s9 }
                         fflush(stdin);5 X7 p' u+ x# D! b) R9 ?5 X& A
                         return -1;, @- X/ ~6 W9 H1 P
                     }* R" j1 q, }9 J; B  _
                     printf("opnd出栈:[%f]\n",b.data);! e( d8 {" i6 W- ]+ p7 p
                     if(Pop(opnd,a)<0)
% @$ s5 b% c+ k                     {$ c. }1 U9 E( p2 L" F' |
                         printf("Bad Input!\n");5 C# A, i  e$ M. j
                         fflush(stdin);
/ E' `2 n" y! b( x  q* R                         return -1;
9 a; {& m/ ^6 P5 G+ Y4 Y                     }
! U7 a8 V" E) h& _2 v                     printf("opnd出栈:[%f]\n",a.data);
7 W" _7 P( v3 d! ]7 \/ S8 p                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/. ~; M/ b# z2 h, H4 f( }9 A
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/1 C" E8 @7 b; ~& M! M
                     printf("结果入栈:[%f]\n",opn_tmp.data);
- o$ Z$ ~6 S* E7 ?% i7 G                     break;0 h3 C; b2 x# y
            }
/ e  l9 t( h$ M        }! D$ d! f$ a9 z; o" I0 `4 _
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ( W7 _* K5 |7 i  ]- \6 \- l+ c. s" \
    }6 v( a$ w9 B) a& T2 G8 s1 l
    GetTop(opnd,opn_tmp);
( Z+ Q1 z) n  w    DestroyStack(optr);
, S5 k7 ~; H9 s# \1 ?. v* l; z    DestroyStack(opnd);
/ q6 `8 ~( B# |/ F% c" v9 n    return opn_tmp.data;! |1 q) ?+ r2 x, q
}2 b) s% S, e/ p- s8 S  M7 b1 m* O
' K& m  s' V& b2 F
char *killzero(char *res,float result)
  e! A5 P4 b5 p, I. R2 i{: n  d/ C! F# w- u" z
    int i;
: r7 T8 V# W2 j7 f
% {% K" R6 u4 d/ k/ t+ J& }& Q, Z    sprintf(res,"%f",result);
- a  ]7 h6 _* u) F* j8 m* A) u    i=(int)strlen(res)-1;3 ]4 f& I1 C0 _; i2 H: M4 H
    while(i&&res=='0')
+ ^) ~4 ?, ^: L' J    {7 E: D5 d7 ~0 `5 j
        res='\0';* c8 b) C: `; d2 |4 o
        i--;; {- m( V+ G7 }' [+ ]: m# d
    }4 N: |( Y$ x0 {' x: q
    if(res=='.')3 _7 ]# }* t! G6 u
        res='\0';
  y4 C1 k, Q/ `    return res;# L, a0 x4 h* `/ y# J, {
}+ v; j. W; d& N/ \6 }/ S' D

7 k  c2 ?- E6 N6 b4 {int main()
! u9 {1 K' W# g' W7 k9 b8 A9 a{7 S5 L: @; t9 Z+ C' e$ h6 k
    char ch;
; _* B6 `& u" w- ?; u: Q# e    char res[64];$ P5 G" T2 i' D. N8 t) t: Z6 U) s
    float result;/ ]/ N6 j7 J; G! v2 e" [0 _" C
    while(1)
0 V: v" |" o8 j+ Q, o% z& K    {
8 q, z- O0 {2 W4 \" g$ a$ d        result=compute();
1 _6 Y& E  \; ]) f: F* L, k+ e0 H7 O        printf("\nThe result is:%s\n",killzero(res,result));8 L' B( X8 _) V' j$ c* _+ v
        printf("Do you want to continue(y/n)?:") ;* e6 q* l1 A( y$ M# v0 o, V) u1 ~! l
        ch=getch();  V, D4 D, z; k) w5 B. c- I
        putchar(ch);/ x2 b7 P$ C2 L' |3 m* [
        if(ch=='n'||ch=='N')
; \0 I5 [6 Z' s+ b( W            break;7 z1 B; ^* j: [
        else8 o4 _( x; g6 D9 A5 U0 P! v, M
            system("cls");
5 W$ n8 ~# s) K/ U1 w; }0 u    }
' n" ~* B. U! H4 {" O    return 0;
% |4 z9 Q- k9 p* V2 K- g9 _, B}
2 ^9 v( Y$ G* n' M* O9 P* I0 `
/ B5 y# R8 O4 h# J
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]




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