Board logo

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

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

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
, ]" q4 r! X. G% R5 U4 {程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=: S  C+ S2 s" `
/**************表达式计算器************/
0 T7 x  `9 Q9 N4 s: B5 i#include <stdio.h>* t, P. c0 p, M" T2 q0 \
#include <stdlib.h>0 n; B& W- h+ |
#include <string.h>
3 T# u' i$ ]) z) p. k% c% d#include <conio.h>( X: J  }% o: v& v9 T
#include <malloc.h>
& S2 b- k. A' ]' {0 e( Z* D* {7 w* B7 A0 e; I  L& w
#define STACK_SIZE 100
! y& O& T% E9 W7 ]* \#define APPEND_SIZE 10
) w$ z% D4 q8 i9 P' J# A6 `5 d0 q2 M& Q$ ~1 C
struct SNode{
% o. U. |0 `1 t4 c0 J# U    float data; /*存放操作数或者计算结果*/8 o2 e8 y% b. b/ y  A$ v
    char ch; /*存放运算符*/$ i/ e0 r8 i& t9 [: X
};
: C1 g, o3 X0 c3 M( t) \3 \  b2 w* _0 E
struct Stack{9 Q4 g% J) n: v7 v8 C. m
    SNode *top;  S( e9 Q- R& \  f2 Q( ], i
    SNode *base;0 K5 {8 {2 n8 a' J! U" h
    int size;4 @- d: U# S( g1 w! [& ?- k4 F0 K% d
};
. E3 k# @7 D  `
1 M. q8 }, q+ ]$ N) n/*栈操作函数*/
& x& J* T8 N' h" L* jint InitStack(Stack &S); /*创建栈*/; O2 |; i3 \5 o1 k7 r8 X) X
int DestroyStack(Stack &S); /*销毁栈*/
) M9 Q  Z2 h9 @int ClearStack(Stack &S); /*清空栈*/
' x! R4 N+ k- ], t6 Y1 B6 wint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
; n- r% a: R8 X+ Z; H9 y3 r- I' r# Lint Push(Stack &S,SNode e); /*将结点e压入栈*/
! N# r/ E* h. _0 q7 x0 bint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
6 Z/ k# c% ~0 s0 N
; s9 \$ ]6 i/ p1 C/*表达式计算器相关函数*/* B; C6 P! S! U- S1 Y' b
char get_precede(char s,char c); /*判断运算符s和c的优先级*/7 }! {) v8 N' p) W+ R
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/( m" N$ ?: _# s. U! {* m. g) R
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/5 ~) c4 y; h* y  j( V
float compute(); /*表达式结算器主函数*/
3 b9 V) u; O3 tchar *killzero(float result); /*去掉结果后面的0*/
( k% a: @) `0 L1 `1 D2 c  ~# e" |1 P: ~, M; m5 y( q& c
int InitStack(Stack &S)* n5 K) [, w% j/ ]0 W
{
7 h% L" K$ s& X' |3 W    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));) R1 Y1 [" a, P
    if(S.base==NULL)
3 N$ c7 Z* k- e& S, B4 w    {
/ t- g  p' U8 W$ t        printf("动态分配内存失败!");
( K2 D. `8 K  o2 P8 _        return -1;9 W; q  c7 J9 I$ ]8 N2 f/ D7 `: }& n
    }
& f  V( h6 a! G5 `4 x# w    S.top=S.base;
6 Y8 x8 ^( Z) F6 W. [' L& u    S.size=STACK_SIZE;9 P3 W* w, I/ A0 N) i# }* P& J
    return 0;
+ a5 R. F8 d# M9 E}
& U% F  w1 s4 V2 `1 V7 g6 m) W" C1 \2 f2 {: L
int DestroyStack(Stack &S)8 [5 q3 @, `! ~3 v
{
: C4 l( q2 ]2 @9 H    free(S.base);
$ W0 f: h' n+ x    return 0;' A/ P* ^$ x4 x" `! p& `1 V
}
* a2 ~6 i1 @0 p8 d  d1 W8 S) V0 G, }: c3 V
int ClearStack(Stack &S)
  N6 B6 V  W" Z" T) C, j8 C{* d" [  L" m; b. y/ u  r( c
    S.top=S.base;4 k& t, m/ a4 _. m, }- S$ J
    return 0;2 _1 b  @% c8 D: c% @1 m" e
}
1 e* q% a; N; q) G( o8 `+ I% m2 m; t8 _
int GetTop(Stack S,SNode &e)
% D0 C, X+ ?- r2 ]* C$ V{4 {2 O* s# }* i, a: x0 c1 e
    if(S.top==S.base)
" L3 X3 b0 h' N/ H" N; d; T0 S. @    {- M( g! s- ^, Q: B
        printf("栈以为空!");
" N  ]: }/ B+ g  U2 _7 a$ p        return -1;
, ?5 @5 o. k* g    }' {6 d2 s/ z& n1 Q! E8 T
    e=*(S.top-1);
$ I" b: L6 ^( ^" x' r    return 0;6 E1 j; Y$ f% l5 J+ w. H
}0 j& Z9 L" ^/ N" s3 i# ^+ @
' c0 ^1 w8 M+ `$ l2 p
int Push(Stack &S,SNode e); S7 Q! U% y, o7 O
{( T5 _/ ~+ l. M7 ^7 |1 U1 g$ V7 G
    if(S.top-S.base>=S.size)
: Z  [/ ?9 q. l  W    {7 ]3 u7 z/ Z- k/ b8 J
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
* o; I8 S& ]* I+ H- \0 ~/ j. o        if(S.base==NULL)( E* c# J/ W% l
        {) r/ j) ]9 z4 m' x! l+ U2 j0 A
            printf("动态分配内存失败!");. L, M2 G$ a  Q. a# a  N4 u
            return -1;
8 W& q: o7 p4 P/ i  l4 n$ Z% s6 R        }6 w1 T) `7 ^  E5 o. u! E! s9 B
        S.top=S.base+S.size;
3 F3 s/ G) e" c  K; v, @        S.size+=APPEND_SIZE;
5 |) [  T3 T' ~, F9 l    }
8 [0 Z0 ~2 B. J    *S.top=e;
7 n9 W' V! E; v4 J3 U/ ~. C* c    S.top++;( u9 t8 P1 u0 \  H/ q( @+ L" H
    return 0;
8 j- i' M  ]6 [% @}
# g, c( @* Z  Z5 i1 m( j0 S
7 K6 r( C  Q4 X# e' N0 Zint Pop(Stack &S,SNode &e)6 e! e) \; `1 ]# @, @3 |
{6 i# i2 p9 C% v; i3 m3 z
    if(S.top==S.base)
  u/ [: B* a) k0 I    {
' T# O) `+ `9 ]2 H4 R9 k& |( o        printf("栈为空!");
4 L# i# i- K( }% z+ X4 j- e: E" {2 y        return -1;
: l! [. L" p+ F0 E5 H+ T    }
3 o* m+ \. q7 ?. G7 t: c    e=*(S.top-1);
' E1 H! O, U8 k+ F2 o  f2 x    S.top--;
# d4 `) R) I/ U% E. Z# D4 K    return 0;
& ?* o" E. u, y# ]5 ^; I& Y}5 a: S0 i4 H3 T- j8 W$ \" @1 S! }
2 i: c0 r$ i! p# Q2 F
char get_precede(char s,char c)7 J2 J* k+ G! {' I
{; G) h' D( _9 w" x) u( n
    switch(s)+ x4 p" ]! Q$ f! U8 u
    {
8 K5 _" N* U* S' |; N7 C7 S/ K        case '+':                 - G) ?7 d0 [' y$ S9 x1 _* p
        case '-':7 s) E- [5 J4 R/ c: M* W2 R  F+ d
             if(c=='+'||c=='-')
/ C8 V( D" D, J                 return '>';0 G( S$ ?: l% |) Y- C7 v3 \
             else if(c=='*'||c=='/')
4 a1 w/ c# m3 j5 F  A0 {2 g                 return '<';
4 d# H( X3 f. D. x5 I# ?* d6 A             else if(c=='(')  Q( r5 f7 P5 f* W
                 return '<';
% Y0 k4 e7 \1 ]; o( q" Q2 a7 w             else if(c==')')4 h+ I" P( H- w2 q& |
                 return '>';
' r2 D$ V/ O# i* e* U; Q( T             else
$ {& \3 X' @0 n5 }0 H8 z                 return '>';. h. G5 k) P) a7 B/ N- G- {
        case '*':
! C0 e6 ~3 H- v3 N        case '/':
6 W2 N; F" v$ _1 S( H             if(c=='+'||c=='-')6 Q3 O5 n$ R, x# A
                 return '>';) n$ I* F$ t  i$ u: S
             else if(c=='*'||c=='/')1 _* @  I/ w+ B
                 return '>';
0 H5 H$ S, ]/ x6 _             else if(c=='(')
$ i& T9 e. G7 C: b                 return '<';
; V, y, \6 @" ?7 V9 w6 X, j             else if(c==')')
- S- y- ~# D3 l( D$ \                 return '>';
" N0 @1 I2 `+ _             else2 s2 N' \4 j9 k
                 return '>';% I. b& N( u0 M  v7 ]
        case '(':
. G7 u# B. O0 |- E6 \. Z" r             if(c=='+'||c=='-')
" q) o6 b  }% K) n# o5 k, X% r' z                 return '<';5 K0 r# K; N5 L6 j3 x. x8 v
             else if(c=='*'||c=='/')5 P& n9 @' Y2 ^' x
                 return '<';' k  A* h* o+ o
             else if(c=='('), A9 j" O; E. W  w6 K: J2 ]
                 return '<';) Q' C, a0 _3 D* m6 w. c* R9 u
             else if(c==')')3 u: u! I5 `% N& {9 ?
                 return '=';
# u* a. _5 {9 c# s             else
; s) v# `! t# r/ a                 return 'E';
. u# a2 m* U; _" K1 v* |        case ')':
* O& e" q% X3 I2 @% i& g2 F             if(c=='+'||c=='-')2 _& \1 K2 X$ }. ^+ E1 j
                 return '>';2 {6 G6 X% C8 W. S- |; z7 T2 `
             else if(c=='*'||c=='/')
0 n8 t* V2 m, \0 X  \. K                 return '>';3 ^8 A8 h; I+ o1 g  R/ g
             else if(c=='(')" f$ f' u) `3 T9 {- x  [
                 return 'E';0 T0 t2 I) i& Y  a) R
             else if(c==')')) V4 \( r% a) K  [0 `6 u
                 return '>';7 D3 x  ]$ N1 f4 J2 }6 w5 ]. w
             else% b) x- s- r7 o* k, X. _
                 return '>';+ m3 ~; k' F9 O) t7 S) l
        case '#':& M0 a( P: X/ p# ?
             if(c=='+'||c=='-')1 i! m3 N$ i: D* n( I3 q- Y
                 return '<';3 G# Q) l; ?8 r7 O
             else if(c=='*'||c=='/')( k0 ~" _; q- @& U
                 return '<';
; Z: f+ G6 f7 g7 X6 w* e% E! t             else if(c=='(')
8 a; m+ F* F  X  p5 q( }4 y& v                 return '<';
0 s' R9 P. O) k# @1 ~$ j7 D             else if(c==')')7 {% ~0 X* |/ R3 B! B. b
                 return 'E';
4 q) \* _+ p# e4 F+ H0 X% J             else
# ?$ h( Y( N- k# k; A                 return '=';
9 l- g! p( E# h% ?: p4 S3 [        default:5 n; z7 v8 T0 H
             break;
1 [" T9 q+ n' \" s3 }    }* d/ s( [& k3 c4 K6 G* H
    return 0;   
7 r% F8 }/ E% t( |6 L# r}
2 w, S5 n( s5 H* k
( K! O4 _' {6 r; q' ?! D' G& n) Hint isOpr(char c)$ E4 ?: x) k' K; D: A# o: [
{3 t9 Q6 v- h4 _! W+ l5 t  L9 P$ s( G
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
  W; T$ k; b9 J( h! A: ~8 l6 V  Q        return 0;" |. J/ F. e0 a1 T7 ]
    else
/ \8 F3 j' M9 P6 p: G, y        return 1;
1 ~+ |: T: Y- Y( X4 U2 L: L* r# _}
' d' x; Q+ _$ g3 p! T3 S5 \3 d9 X, c8 X& k& v: n$ @
float operate(float x, char opr, float y)/ U; p3 b$ [; c
{
, i: D* F' p5 E1 l" Y: s    float result;5 [. h8 J3 R. d: J1 F6 t
    switch (opr)
: q( W' K" A: f( m5 w5 r    {" v$ O/ u( X0 y! Q
        case '+':
& `. n  b! ?; z) b; J% o             result = x + y;' D3 P) g% x  B) f  x+ V6 S4 V
             break;/ @2 W3 \' c$ ]2 A& ]' l, y4 D: Z7 P
        case '-':
# ^: o# H/ @: @, L: I! l+ \8 J/ Q             result = x - y;
3 f8 m& r: p/ o             break;) N7 I0 c9 r4 X! w! ]
        case '*': 2 _( {$ R& K$ z8 B# q
             result = x * y;" E* e; i1 ]' c5 L5 E) D/ ~; A5 r, K
             break;
1 w5 V4 w- j6 V% k7 D        case '/':
  |! m7 N3 @1 r* ?% `             if (y == 0)& W6 ^& S7 d7 K' G
             {
/ o. _7 o& c% l* b( u                printf("Divided by zero!\n");
4 K: a3 m+ b0 \' ]9 U8 o9 J                return 0;& i  \; R9 f) Y! s; _1 T$ j2 b
             }
5 D5 x! S9 I+ G; V' O             else' r: s) N* P; L6 ^( s
             {
9 t9 r! ^! s2 k7 F  J1 g7 E                 result = x / y;8 z* {7 g5 N, v  e0 y
                 break;
9 C2 S$ w7 v: k: d9 N- n             }% A) u# x" s+ `9 o" ^- ]. A! P
       default:
( J' E* [" J, V) I( X5 D             printf("Bad Input.\n"); 1 @$ k! Q5 {7 W) n5 x# k3 I
             return 0;9 _1 r9 L* g+ S3 s: l5 \6 ~5 Z
    }
( z7 M) X: f; h4 ^* E1 I    return result;
) a# D. C5 x8 Y( E1 ^( K- ]}    # C, j4 b3 E# I# v5 [' O

2 [- N4 J7 L/ g" H+ Yfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/6 F1 ^# ?* m5 g9 T
{
$ |- U6 L1 A( x" P& i    Stack optr,opnd;
' M/ f9 j0 ^2 l' L* {4 H& n6 c    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;7 l2 x, X  w) L. x1 v' w; C
    char c;
7 @" }  G$ `' R( [& x  I7 Q    char buf[16];
8 w% g6 {* k) N3 r1 _; ]    int i=0;! Y; K2 B7 t- j: {$ @5 E
   
6 u( T2 z7 P4 |$ r% r* }    InitStack(optr); /*用于寄存运算符*/
5 ~# I2 W  j8 [* K1 x9 p0 k    InitStack(opnd); /*用于寄存操作数和计算结果*/
; I5 t$ o; f# b    memset(buf,0,sizeof(buf));" T% f, M; b/ E" k# t6 c3 C1 L2 x$ K
    ) Z  W8 p4 N  z. G% X
    printf("Enter your expression:");; Q4 K( \& u0 h" F: V& H* R5 e- J
        
( r# r1 M9 b" ?. e4 t$ a: ]    opr_in.ch='#';; x0 L& A) L1 w; \
    Push(optr,opr_in); /*'#'入栈*/2 K& D( {% k, V" C: f5 M
    GetTop(optr,opr_top);% X8 ?! i5 y/ e: n6 A) w. X
    c=getchar();
/ n1 `1 r/ N% Y: S9 G  H; I    while(c!='='||opr_top.ch!='#')
" f0 z3 d$ G/ L9 o- `    {
9 O) P0 F& I3 w5 Z0 `; E% Y        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/  C7 m% _6 `( b7 e1 c7 ^+ v; P; b* s5 v
        {
; t0 x  m; j: \. b            buf=c;& ^! Y' U* O* I. K' ?3 F! j7 g
            i++;2 J. C" `: s( Q) x' q4 I+ N4 z
            c=getchar();: u3 a6 `, X( x. V$ X% L, Q
        }
+ T, v. _: `" `) D        else /*是运算符*/
: H8 ]" W4 N9 o% U        {
6 ], h/ r% q* }; i6 W7 C            buf='\0';
6 M- |; W" h  r% u            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*// C( u4 X: S. [. B2 j
            {
# \# [1 |( p) C9 k/ e                 opn_in.data=(float)atof(buf);
+ s: \8 l5 W8 q1 `: A: p2 s                 Push(opnd,opn_in);
$ P# o- P# s+ M                 printf("opnd入栈:[%f]\n",opn_in.data);9 }6 s0 }) \" j( \
                 i=0;
7 u9 h$ B! {5 C* N/ W& y                 memset(buf,0,sizeof(buf));
2 n: H5 c/ z( u, T* ]% z8 z            }. v" y+ U7 y- N1 }4 D5 Q
            opr_in.ch=c;
9 ?9 [* D% L1 f0 X' O            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/! a* A$ j1 k" Z# l
            {9 d: o( _$ B1 P4 U* Z
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
: O% O8 v" ?) x3 I1 a% |                     Push(optr,opr_in);0 X" |% }5 j. [9 m- V
                     printf("optr入栈:[%c]\n",opr_in.ch);  s' {/ A1 d) Z) e& x- f
                     c=getchar();
- U  p$ |, {3 a: Q! a" G3 f                     break;" N+ u; G( Z# y- o8 S, Q
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
: ^! B1 ^8 S3 c" O/ v                     Pop(optr,e);5 ?' G- d4 F! Y7 \, L
                     printf("optr出栈:去掉括号\n");# x0 f' f* O5 }4 M% ^% Z
                     c=getchar();
9 l! T6 ~# z  ]! w1 S+ o; H$ z                     break;: Z+ A+ S7 q) J% g
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
, \$ P: V, ?" z                     Pop(optr,opr_t);
4 e4 V1 P) I9 S* {                     printf("optr出栈:[%c]\n",opr_t.ch);" O$ D. Z: c/ O# A
                     if(Pop(opnd,b)<0)1 Q; ^: s7 `' B6 Q( [3 h
                     {
! w/ L. E8 b/ W8 O6 Z                         printf("Bad Input!\n");% R7 B! s$ F  {! v7 ?! K8 b
                         fflush(stdin);* ~. i  {2 p% B
                         return -1;  g; U. P( e; ?) i0 ]
                     }. n; |' T7 ]$ m" t- N+ G7 F$ R; ]
                     printf("opnd出栈:[%f]\n",b.data);
+ u5 j2 B1 p5 q! Z3 a: }                     if(Pop(opnd,a)<0)& c+ t/ }' v. o& ^
                     {2 D! v/ m* @9 {( i# c0 E8 O& L& ]
                         printf("Bad Input!\n");. \$ }  a5 ?# b; L" C# K
                         fflush(stdin);' N/ Z9 B. Q0 T/ E& g; y
                         return -1;3 \3 `5 `. ^6 l
                     }
" \5 D3 e4 _& G) _2 B                     printf("opnd出栈:[%f]\n",a.data);- M- C" w7 E( N: G/ s$ _
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/4 S+ ^6 V" f9 v& }/ ~- u
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/( o0 J1 j& E' y; f) J
                     printf("结果入栈:[%f]\n",opn_tmp.data);
2 g. a; f" r. l8 X7 U* L                     break;
) u: T7 W& V8 `- W1 o, r4 i6 Q  r            }5 d/ }. s! |# s  C6 _" r
        }
3 \0 t( o0 A/ B9 z0 \! a        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                - t) B  Q8 y0 j( R: z0 B$ W
    }. c; B8 P$ W* _4 {  g1 n
    GetTop(opnd,opn_tmp);' [+ t: R, O% }7 C7 H3 u. a; Z
    DestroyStack(optr);3 O# T( x2 Y0 u3 ^& I( K2 w
    DestroyStack(opnd);
; M; C7 l& D2 @. d: b    return opn_tmp.data;& K# ~+ Y* r+ E" t
}* c" u+ Z' }, \9 p: o4 Y3 |1 U
" n0 t/ E9 r* d* S- o
char *killzero(char *res,float result)) A+ C5 y: f6 M8 s. q* V
{
$ o1 v0 e, a& _8 ]# u5 S    int i;& d1 E) m& S- R: z2 C* V
8 k1 q& w- V$ U# t/ T( Z
    sprintf(res,"%f",result);& U- ]& @$ ]5 g% r! J& N
    i=(int)strlen(res)-1;
- F, h+ n/ k; K+ `6 }    while(i&&res=='0')7 E; d7 [$ ~' b8 Y  w# A
    {
! t# {- h# U0 k8 g; L( B        res='\0';
- X+ [; b# h) W0 t        i--;! V( Z; P" k- \& R' E
    }. D" G8 W2 j" g1 z& A5 X
    if(res=='.')
6 m: L8 K& S5 G        res='\0';
: j; J6 ^& U2 S3 G$ w' }    return res;3 t/ {  C; O8 G. X0 T
}
8 _  ~0 i$ i0 t& ?: J$ d" k. Y. c. D
int main()
, ~: ]3 b$ {& k3 n{
' I9 E) L+ D& v- [& C4 ]    char ch;. S. ~" U. @; D/ x
    char res[64];) j# x  p# ]( D+ v
    float result;2 A! D( h% q  \/ M! z% B
    while(1)3 V+ L+ ^# J4 n. @9 d) m
    {
3 p+ b; y# z' S9 \/ D9 ^; i        result=compute();
- j2 f3 i9 ?0 f) d6 @% _) O" x        printf("\nThe result is:%s\n",killzero(res,result));
; B0 [8 X# {) p" W% n. c        printf("Do you want to continue(y/n)?:") ;
  v  U# t& \( ]* D        ch=getch();
5 ~; ^3 M/ [. Z3 y        putchar(ch);
5 o& t# {- Y1 M' c9 k' D        if(ch=='n'||ch=='N')
% I; k) g; d- t/ f& p4 M( V4 X            break;- S+ g# u9 ~* X4 u
        else
, [7 x! M" n) j2 _0 ^, U            system("cls");
9 R2 a# d& }* x/ X5 s    }
% S5 W2 N. y  M, M5 a    return 0;
( f2 e) }9 W, o, }! _. E; A}
( y% F! ]1 h6 s% O; {' _1 n, q5 l' `

" Q4 L1 g$ x4 N9 z* A4 F2 I[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]




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