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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.! T5 y0 w/ s3 e1 M5 ]
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=7 W2 j5 E# V* c5 G$ d/ k
/**************表达式计算器************/
6 D4 }9 |, d' }" V4 O& t" f6 f+ w( i#include <stdio.h>0 O- d! }. f$ l- i, }) ]
#include <stdlib.h>6 o) h# C* |1 R, d9 o$ e  j. ?
#include <string.h>0 J+ ?# A$ u; e1 u2 x  a- j  v3 s# z6 i
#include <conio.h>; f& B8 G* E, P
#include <malloc.h>6 l+ M2 L7 l6 w5 }
7 V+ [7 y+ M8 a8 U
#define STACK_SIZE 100+ O6 T+ M; `% b
#define APPEND_SIZE 10& \: l5 Z) f- s4 z3 M4 ]
/ W2 B- e# G9 ?* Q6 b4 t4 L
struct SNode{4 B8 b; _# v$ ?) d! a& y! s6 l
    float data; /*存放操作数或者计算结果*/, w- k  \. J, t! V/ h5 D
    char ch; /*存放运算符*/
" r$ k, y' p" z6 b; z' S};" z( z/ x! T( H+ n

# m$ y9 O& U8 W8 z' f- _struct Stack{
! {2 |% A6 ^8 d, @    SNode *top;* D8 |' Z3 \; m. `9 F% Z
    SNode *base;5 h( }! p. m1 h1 X- ?, O* o3 M
    int size;
9 T. h4 Z" j; m- f4 }) Q};) r# W1 V: C7 P! g9 `) i6 w+ D2 U
+ O" E$ }* k# y' m. _
/*栈操作函数*/  T4 n7 Z- n/ }' n- B% b
int InitStack(Stack &S); /*创建栈*/
% j) V5 J* I" r2 Q0 L; K! ?int DestroyStack(Stack &S); /*销毁栈*/
3 ~+ W8 h9 L  ?. o4 q: [5 fint ClearStack(Stack &S); /*清空栈*/2 e* F) Y5 u1 Z6 l! a
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
/ t9 N0 ^' w  L, Y1 p  h9 `int Push(Stack &S,SNode e); /*将结点e压入栈*/9 g' Y  @2 z3 K( ?3 U
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/% L) a3 m+ i' O
5 r7 N8 _( }6 S% R5 Q5 T7 P
/*表达式计算器相关函数*/2 o6 L9 B: A9 ?0 S; b  D! X; b+ ]/ t
char get_precede(char s,char c); /*判断运算符s和c的优先级*/" A& M( d+ e6 E, M
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
% c. ?/ M1 q( }8 N/ Afloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/0 m+ j& C! T$ I- R2 S  }
float compute(); /*表达式结算器主函数*/
: P& P& m& H: rchar *killzero(float result); /*去掉结果后面的0*/
- O. i5 L: `1 i- U
$ H7 p4 q- J( f% q+ h8 E8 t: A( Aint InitStack(Stack &S)% l" F1 S; t) e
{
5 t. g/ s7 s- S# p$ X6 R4 E    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));0 O5 u: s' h/ N: w
    if(S.base==NULL)0 `$ h7 x2 E9 q
    {+ |$ l# x$ }+ ~6 J$ Q
        printf("动态分配内存失败!");' _# H( U7 a1 v1 j# E$ n8 y
        return -1;
" ~4 ?; \$ {8 j& q* ?    }1 x+ r! x! q2 `, _
    S.top=S.base;
& d& r: Z( F* y7 i0 ?  \    S.size=STACK_SIZE;" n# E% X# S2 z, a
    return 0;* {1 z& f6 W, D. U
}
* b+ y( U/ [) G) x- P' M9 X' _
/ ~4 S+ O  n1 Kint DestroyStack(Stack &S)
6 [% Q. G6 B0 h5 ^3 n{! g" ~3 M( n4 O) r
    free(S.base);
  X5 _" @) e; c" x( ]+ F) y    return 0;% V. P' c: ]% m
}
! k1 d0 C: b% z. m, @; n! I2 t; P; X, S
int ClearStack(Stack &S)
1 c/ Q$ a( ]2 v7 w# Q% H{1 Q7 N9 W2 {) D  W) V
    S.top=S.base;
0 V) {$ ^3 u9 _4 l- L    return 0;9 J+ z* Q+ d* S
}
0 F$ ^- b/ K, p) W5 ]$ m. N8 |; L
int GetTop(Stack S,SNode &e)2 C0 q0 g& ^( m' J! ^( U8 t
{' Q! h! ?" {; v% Y4 M6 c
    if(S.top==S.base)3 u* e( C7 q. a7 J, B+ z6 [+ G
    {- ?/ E" B) Y: I) L9 s) s* P
        printf("栈以为空!");6 w) q% Y, K/ A
        return -1;9 Q- a- N* b- P* Q7 t, O. s+ M
    }
* u7 Z1 H2 E3 W1 }  c) F: Y    e=*(S.top-1);$ ]7 A. t" A. G' y; o
    return 0;2 J, F) x0 I+ _' b) z  ?( [+ k
}# z! Z7 `/ ^( E) ^* H! S! \6 a
( P$ S7 Z1 b" a3 |; F9 {
int Push(Stack &S,SNode e)# ^8 S( f& t4 G* v0 i$ e
{
8 H' ~+ o& B' i+ l3 O( e0 R: c" J    if(S.top-S.base>=S.size)
  ?. k8 @, `! S# M/ d    {% W- N# `% o+ s- x: _- D$ c2 G
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
4 h2 z1 [. n9 T# A  \        if(S.base==NULL)3 z5 Z" k' }2 ?! @8 q+ C
        {
0 I9 X; E$ T$ u3 E: |            printf("动态分配内存失败!");
7 i* \2 O) b+ J* w* F8 N8 A3 i+ V            return -1;* h6 D* D& ~% [5 D$ Y% K; `
        }
) N/ Y6 \$ J! g9 `% |! R, n        S.top=S.base+S.size;
2 x1 U9 M3 B, H! U        S.size+=APPEND_SIZE;
* G2 t. {+ e  W0 r' v    }
4 a$ r& p& G- f2 v: j& p    *S.top=e;
- c% J0 A1 e; N    S.top++;
  c6 m' u: R+ d. S    return 0;
) N1 E6 q% C: H; g, y}( z: }6 |6 L! t7 Q* C- b
5 ?7 V( I; Y  [& t$ v
int Pop(Stack &S,SNode &e)
5 s" x. D7 B7 ?- e# s{
% B. g1 J+ y& N    if(S.top==S.base)
2 u2 f( [* k; z0 j/ q) [, O    {% Q6 M& U$ B6 h+ Q! _1 w2 _
        printf("栈为空!");. q3 C+ x% Q/ k  P4 G0 q
        return -1;2 J) _  \6 k# b6 g
    }( ], {- n8 u3 v! S3 B% L
    e=*(S.top-1);* O: R$ l- g6 k  A8 t
    S.top--;. C# D$ L% ]( J9 P0 m
    return 0;1 `0 q# J& A" q
}: J8 @/ \" o3 U: o' O& s; w$ l; k  M

* M/ S* A$ T0 |7 S, r# ]char get_precede(char s,char c)
* }1 m  B. B( x( [4 S{/ ]& ^, g+ u. N; r! K
    switch(s)# K! s" V: K. m4 m6 O& ?8 p
    {
6 e4 [$ I* K# N3 w6 b) U3 c        case '+':                 3 ]$ n9 W7 U3 ^, ^; N" k! Y6 D
        case '-':
  ^; j; U' u' g4 C2 ]             if(c=='+'||c=='-')0 O, q( a1 N) P) R" D, D' D5 a
                 return '>';
! Y; r+ {+ D2 s& r             else if(c=='*'||c=='/')/ y- `# B- Z- b3 ^
                 return '<';5 L5 |# A9 N: p8 x. V1 Y8 u
             else if(c=='(')
7 y9 b. i) v/ D/ l. p: a                 return '<';
  z& M4 [: d3 Z- k- ]7 F# x) W, Q9 z             else if(c==')')# c6 Y9 y# ^! B8 h
                 return '>';
/ F9 @! @5 p+ s) x; m3 _             else
+ y& J1 V" t9 l% k0 S                 return '>';
+ U) }" {. D% y        case '*':4 t' r  ~0 C- F  d' y& ]4 K& I
        case '/':
: D0 c; ~- B1 L" K9 ^: C* v4 u  ~             if(c=='+'||c=='-')
1 s7 e" g% G8 f! U                 return '>';
- j+ \0 ^+ d( X; d( n5 ^4 ]; n             else if(c=='*'||c=='/')* `8 c; M- R3 p" `/ p
                 return '>';- A' ?3 q: g+ r7 ?+ a
             else if(c=='(')9 o# a- h/ M* w$ \6 I' U
                 return '<';' I* r( c# e1 o! R5 \; R; E
             else if(c==')')9 M1 }+ d- h* j9 _
                 return '>';
$ e+ P8 M+ l& s; A4 [8 Z% W             else
  D6 z+ X& K" z" y' W$ b! h                 return '>';
4 J) h- V! ]/ i3 h        case '(':
9 g/ P1 J6 t. G  I# o' W' V4 ?             if(c=='+'||c=='-')  i- o. ^' J% P* E
                 return '<';
% i4 j/ u5 f4 D/ }             else if(c=='*'||c=='/')
( n* [& m9 [, a- S1 q! s' x% @: y) d, G                 return '<';6 `: p* M1 d* U9 G
             else if(c=='(')2 S$ O1 \5 r* Y1 I5 A* j8 @
                 return '<';
" K0 y; P: d. }& T& O             else if(c==')')0 J1 M8 V4 [2 W# L. K, M0 E
                 return '=';
3 B4 w) K0 D6 B' T+ y" G             else6 ]2 z9 S9 @1 j- s
                 return 'E';/ [  p( q# G+ r
        case ')':" o4 ?* w" k# x* r" r
             if(c=='+'||c=='-')
% P3 D* d8 R. o                 return '>';# I6 i: B. d0 i& o
             else if(c=='*'||c=='/')2 s1 ?2 S+ u, z; d
                 return '>';/ z7 W  W5 ]3 @0 r- W5 B
             else if(c=='(')$ C: ?2 d! U% ]' S1 k
                 return 'E';1 v% t# R/ R  ^* z% [, j) r$ Z
             else if(c==')')* b$ U& w! x9 Y2 D* d1 W7 B* V, t! c
                 return '>';! {$ a' z8 h5 W! m6 Q9 t$ B  K
             else
6 `8 s4 i6 ]& i. f, s                 return '>';
% Z& i/ l$ I. E# ~' j3 ]7 M, p        case '#':
; P8 t6 G% s) g) W: f* _& Y* o             if(c=='+'||c=='-')
1 \1 f9 d# `& L" Z- j7 t1 N                 return '<';% |$ _& q: f- F% S# T3 w, c
             else if(c=='*'||c=='/')* S* x1 Y( H( e8 N  o) `
                 return '<';
) q7 W. W; ]( o             else if(c=='(')
  h; O; s+ T0 n                 return '<';4 _! O/ {0 j; H% G
             else if(c==')')& W0 U" y" Y. u2 h0 j
                 return 'E';
- w. E- @. i; ?" T8 W             else: d" T( v9 y; g! _! f# t2 ]3 a' l2 I
                 return '=';
/ ?7 L' A0 i% R! c        default:
/ G3 A5 k  d3 x9 l1 x: Y- t- F9 c             break;- n: Q0 x$ T# }1 g0 M# `1 U
    }
) {2 j. {6 F# q& H0 P/ x    return 0;    ) A+ {) }& ^" B. w
}
7 ^8 J1 c/ d- }
4 U5 G& t. V. \4 ]* w$ }' kint isOpr(char c)
4 u6 O4 `1 J/ W# j{
, e% y" J  l+ c6 m! m% e1 @    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')# U/ g' C; Z& }  _
        return 0;
4 P& C- M0 U& j4 \$ P! x    else
+ ~: @9 Z. W, S6 E5 H& }8 ]  h        return 1;
' ~) o5 n- i) g+ S! m3 d}
. E7 @3 d2 C, Q9 \. W
  ~1 c$ \0 d3 Qfloat operate(float x, char opr, float y)$ U- w. K4 |4 W( e
{! j  i2 u5 x; M+ Y3 ]. r- Z
    float result;: M) B1 m9 a2 P" m! @0 B
    switch (opr)
. S0 c! C0 b2 o: `9 [6 ^    {
  C' P+ ^2 h, a2 f0 ^        case '+': 5 z7 j* b8 f. p) N1 b- W3 i4 a. o
             result = x + y;
; f9 F* y# ]8 m5 ~             break;4 I: [( {4 p! s. ^" G  S& X# Y
        case '-':
6 ^7 h; {( j; A6 b             result = x - y;
# s( g9 }0 [* f' ^* Q             break;6 S0 B9 w$ s4 j( d2 T& A
        case '*':   g5 P; p# \* n( W$ z) Q5 W# `& T1 C
             result = x * y;
( }( M, q# [- p             break;6 d: u0 ~. v1 w2 v3 K' u
        case '/': - D" E1 |& C) U  ^6 q" J5 a
             if (y == 0)
8 }/ s% f/ J6 o. o, M# p1 `             {0 M1 U4 T6 f- F$ g
                printf("Divided by zero!\n");+ c4 c) G- X+ a
                return 0;
3 R3 d: x& w! j1 V, J6 F             }
+ \* v, a- T0 u+ y             else
9 B7 B9 u9 ?0 u0 P! F             {
& a6 Z, Y/ A/ u                 result = x / y;1 g2 h+ z! {) p( f$ z5 t- ]# y
                 break;2 y! h3 Q4 B6 l& K
             }; B5 U( Y# q2 J3 i# m4 g$ s; p- a
       default: 3 ^: U8 Q. M$ `
             printf("Bad Input.\n"); % s+ K: [: P  S9 |; T4 {
             return 0;2 N5 {% _7 ~5 C/ A9 j0 B
    }) F( r4 }  C( I# f9 M7 E- E; W$ J
    return result;6 p& L; P" x9 o6 _6 o7 ?
}   
# j; u3 ]$ R+ x' O% s, \) {; I
, `: c; L* S9 w# Lfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/8 ~6 Z- D& H; l  V6 @
{6 P1 M1 N- \, j$ |* ^5 @- k* \
    Stack optr,opnd;6 U9 P' t7 \' K0 O/ P" A4 Q
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
# l3 [3 d: D8 f* J) K2 I! x    char c;
  U: h( K* P% ?    char buf[16];0 H" t" @% D( C6 }
    int i=0;
* D: U5 x  r; T   
- c, c9 [/ a+ q2 G* x$ J    InitStack(optr); /*用于寄存运算符*/
# r/ |/ Q8 C3 s: H0 a2 d% F- [    InitStack(opnd); /*用于寄存操作数和计算结果*/
6 H. q6 e, n: A6 v& u1 e    memset(buf,0,sizeof(buf));, A( f2 w7 P! b4 c' `5 P
    + i0 Y/ k* h/ }( |
    printf("Enter your expression:");! a$ C1 N! ~7 g7 b! I
        
- ?! a( \7 T' H( P    opr_in.ch='#';# z* _( t3 i0 L5 @, I
    Push(optr,opr_in); /*'#'入栈*/" l% }8 Y" I- E8 D
    GetTop(optr,opr_top);
: D3 s6 k) j& V; M    c=getchar();
- K+ y8 Z8 f. S  n8 t/ F    while(c!='='||opr_top.ch!='#')" X% x0 K' `! z% ~! C2 H( |
    {% N) T/ h; U; m  E1 g$ e
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/5 h7 ^) Z' G1 w4 ~2 S
        {! R( a# H4 y8 z% Y+ o! k5 \; a
            buf=c;8 p; T  ~2 s* S  x
            i++;
2 r0 e8 h* O# W3 J9 L9 l            c=getchar();
' A+ o  D5 d, W* C        }) [, Z: {8 q2 n
        else /*是运算符*/* ?0 V9 T$ ]$ e: @6 l
        {: Y7 I' _& e  C) v' O, s& \( Z
            buf='\0';3 c: P+ M7 S/ r: G! ^$ X# K, T
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/% I9 Z4 Z# o' g. e" \# s
            {/ i3 h) K+ K* G) i8 {
                 opn_in.data=(float)atof(buf);
. ~4 z* J* u' c" c" U                 Push(opnd,opn_in);. e! \6 R# @" e4 \  K
                 printf("opnd入栈:[%f]\n",opn_in.data);% L( b7 O- U1 w( [" U8 ?
                 i=0;
$ v4 U! ]8 Y" j                 memset(buf,0,sizeof(buf));3 u3 c; U4 F! h6 v  r9 s, o
            }% `  d7 a6 z8 Q% S# c: r
            opr_in.ch=c;1 _) O! v' C- W$ p2 H2 K& n
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
# ?5 I. u6 [3 D& A' t" ^% p            {
9 e8 G3 ]5 V. U2 K: L# h3 c4 G$ f                case '<': /*优先级小于栈顶结点,则运算符入栈*/2 [2 T0 g1 l7 x- v
                     Push(optr,opr_in);) S0 [7 a( X$ @; @
                     printf("optr入栈:[%c]\n",opr_in.ch);1 i% ]  Z. O5 {& E) p
                     c=getchar();
1 ]/ }9 F% |7 ?' }0 t0 c1 o                     break;
0 ^$ `! E% i: K6 J- \                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/+ s4 U  D" A# K" H
                     Pop(optr,e);1 o- X5 V4 v8 z" Y' q4 N* T' l+ L
                     printf("optr出栈:去掉括号\n");) l+ X0 ~# `0 l" _/ F  N- i
                     c=getchar();
5 I* B3 N& L0 d( u0 s                     break;# B( x, x% ~$ m- D% O( U' w5 v1 q& D% O
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
" i% i3 H1 G7 Y                     Pop(optr,opr_t);9 U7 t  [+ M. a( p+ q$ }
                     printf("optr出栈:[%c]\n",opr_t.ch);9 r, b( g  [9 ?( C7 q
                     if(Pop(opnd,b)<0)
7 ?4 L" B( W" K. @% t0 m8 f$ X6 I                     {
' [+ A7 }: U8 m- A2 m# a$ S" _                         printf("Bad Input!\n");; t: s2 T4 z3 _5 j+ O
                         fflush(stdin);
5 t  k/ ^" G) x; M4 e( B                         return -1;7 O- ]9 e( H. g) h7 s, ^' O
                     }, E4 x9 Z$ k  G! k  v! z
                     printf("opnd出栈:[%f]\n",b.data);
' j. H- A6 o/ h! i* `                     if(Pop(opnd,a)<0)
) {& l9 t7 S$ i- b                     {
4 o$ `1 d0 W9 C  h& L* R/ U                         printf("Bad Input!\n");
* \7 x; M2 T' Y                         fflush(stdin);
% J5 F! \% I8 j                         return -1;
/ {& Y+ ]. y2 Y2 f                     }% l' K' L' B0 J+ {! {
                     printf("opnd出栈:[%f]\n",a.data);
9 F7 F1 D- f* f9 H, Y0 \4 f  h                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/( l- R" C; c2 B2 }, F
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*// {) p1 C6 Y/ Y0 }' I" J7 {
                     printf("结果入栈:[%f]\n",opn_tmp.data);( p" E! q8 f  c" W% z* i
                     break;
  }% V; t+ ^9 U/ v: E/ O& N) W/ v            }
0 Q! B% _% G' t" C        }
1 j" I/ L1 q+ _( G" y6 E        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ) A# n/ T0 u* w# E2 k
    }" q: ^& f+ ^. J: s# H; N8 a
    GetTop(opnd,opn_tmp);7 _* G) L% m+ e: M0 e, M
    DestroyStack(optr);9 {9 b2 k/ P, f* l# E1 J
    DestroyStack(opnd);
' s) g$ o* t5 I, \: ]- q8 v' }% a    return opn_tmp.data;
) @& j, O  A# g}& g) J3 \& m8 p0 v. X8 {8 I

7 b) l8 s! H2 D8 D6 K) N' Y; o) Ochar *killzero(char *res,float result)8 Y; Y! I, n' c' l- \5 m' Z
{! `1 v# R7 e! s2 v
    int i;
! P& Q$ W; q+ M( V; s" [0 S" _/ y. N) b$ L
    sprintf(res,"%f",result);
5 \5 t9 L2 f8 C$ n0 n: Q    i=(int)strlen(res)-1;
# a5 e) k+ ^! }0 j3 o/ {' ?+ R. j    while(i&&res=='0')
. s6 |! [6 D1 p7 t2 ~: z    {: _% t# f! X6 b, I6 J) P% H
        res='\0';/ l3 R) ]' b* h( Q2 y" B6 J3 P
        i--;
- w! s% z& C: _& C    }) \! d' E: N7 y
    if(res=='.')
7 E( J! }) e2 g2 d5 Z/ p        res='\0';4 C' x( R/ Z  S" \3 }8 G
    return res;  r# x2 Q9 }$ e) M2 q3 }) `2 L
}
' {! O  E% {$ _( ~+ G% X" {& ~, X* f+ x$ D) e+ l+ n
int main()
8 U0 q! f# @+ F{/ {7 d/ p3 w/ n1 {) U5 [
    char ch;
+ Y3 ~" O4 Y8 n    char res[64];
! e9 o! k2 T* v9 ^    float result;3 x7 `4 g& A2 w# g- C3 R. r9 x
    while(1)6 K9 v$ G+ \" ?, A
    {" A, _2 E; o- T  Z" E% x
        result=compute();
2 B$ S5 B% Y/ ~+ H) K7 p: x/ v5 l        printf("\nThe result is:%s\n",killzero(res,result));
- r9 D' w3 h( w3 o" P        printf("Do you want to continue(y/n)?:") ;
' Y& m- X* C, m0 `/ k; q        ch=getch();
9 r, }% p3 B: A        putchar(ch);( L  S% P5 v7 b9 n3 ?
        if(ch=='n'||ch=='N')# L2 p0 V6 J2 ]
            break;
* d; J% T8 L3 g9 b        else- T- Y4 U1 ?8 ~4 u
            system("cls");
# O1 d! \' i3 y    }
5 y+ @: f! M3 A' V    return 0;
! U8 [  o7 N  y- k+ g( D) d2 E$ z0 F}

. |1 g  x5 w  }7 ~+ E( f% ^4 o$ y2 \1 v- s6 ]( m
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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