返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
$ C/ g( l& b5 W" l, Z, J程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
, F0 e" O3 l/ a/**************表达式计算器************/8 {; z' d8 Q! S% n" [! E4 @
#include <stdio.h>! C% A- k: m5 D! {# q$ C$ r0 Y: Q
#include <stdlib.h>
* Q5 c" O; N! U% x5 K#include <string.h># Q# }+ I5 O  [7 X0 }) [: ~0 e
#include <conio.h>. f' S* V5 M5 e8 h! {) \9 a# U
#include <malloc.h>  P- G7 v' a. n
9 g  [1 E8 s. ^5 v
#define STACK_SIZE 100# u& B+ n3 g4 B
#define APPEND_SIZE 10* }* U6 |1 R" ?* ]  C5 _/ |
6 }2 W: T( H" [! z: B
struct SNode{: V$ K. l" T% Y: {/ |; d
    float data; /*存放操作数或者计算结果*/
7 H5 Y" \3 i* z5 G% E. g% f    char ch; /*存放运算符*/
1 ~0 O. l7 S) n" t* u};* ]9 c7 U# G1 ]& \6 @

6 u6 _; w. t, i1 B# Xstruct Stack{1 n+ n7 p5 _* J1 g
    SNode *top;! o0 J' ?. t+ v3 O0 n! j9 E
    SNode *base;5 ^1 K2 O3 S4 x: j$ g- U
    int size;9 a0 [% G1 v/ b1 o, G8 |
};
2 @  [& \* r3 g# l$ B1 [. l
4 t2 D" l8 ]' J& A9 q4 ~/ L! e/ r/*栈操作函数*/( G# \7 e4 t7 Q" c( v
int InitStack(Stack &S); /*创建栈*/
0 a# s3 J9 ]* Lint DestroyStack(Stack &S); /*销毁栈*/
$ J, ^$ P5 v( Bint ClearStack(Stack &S); /*清空栈*/
# }' ]0 [- F- S7 ?# `6 w: ]( Eint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
5 \+ y/ S5 E# i1 o3 j; n$ P( R# kint Push(Stack &S,SNode e); /*将结点e压入栈*/- u# x* d4 Q- z+ d( X
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/1 ?2 G' B: z% P4 \- o! k
) A, S- E+ A8 [2 D  M( Y8 e
/*表达式计算器相关函数*/( ~9 u; ?! H* e6 T( h! E1 {) W
char get_precede(char s,char c); /*判断运算符s和c的优先级*/7 {# c) h. l& W7 u* U: l
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
3 z5 e$ j+ r% Y* [- v: T- _float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
# q5 [# X) b' W3 {, h0 ffloat compute(); /*表达式结算器主函数*/
9 J9 |) M0 x  l) W. X1 n. Kchar *killzero(float result); /*去掉结果后面的0*/ 0 w& X8 o6 f* }" `0 x; I( J$ v

' R. d& @+ z* I  F: q5 Y; Pint InitStack(Stack &S)2 n2 o6 F9 A* I7 |1 S
{; r* ]9 V: g" p5 H
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));2 ^7 u( y+ j" W0 l2 ]
    if(S.base==NULL)
9 |8 X* _8 \: H, h    {2 x$ G% a. R! O; W2 i
        printf("动态分配内存失败!");
  r6 l3 P% ^" {, e        return -1;+ n" t  I1 u/ j  U& l; e+ n
    }( S1 L9 A1 z* {" y
    S.top=S.base;
  o4 P3 w( y# c    S.size=STACK_SIZE;
& z8 w0 R& X* N( A    return 0;
; M4 J' ]$ M" |+ ~}) V* p( @8 R6 I0 o
" l% u: x0 K# A0 E$ A
int DestroyStack(Stack &S): v- r! m; s" y- X
{9 ?, x, ~3 I. N) }; v
    free(S.base);9 i* p% b6 @( P0 s1 B
    return 0;
1 Q! K  T$ _- Z5 x, @, }6 b}& J+ f/ r6 j8 j/ ]; [  H

& I+ F7 d2 y8 d  w* y: Eint ClearStack(Stack &S)" r& L  R" a: y3 ^
{
; V/ ~) {+ r7 A" x- S  [6 }9 p0 B    S.top=S.base;7 d' w: m7 t& y# f; i
    return 0;* E) d8 C2 ^( G9 }6 Y( ^% i% s. U
}3 e* h: s. j8 K- [& {
4 S& d3 P/ c: i4 ]$ r( Z8 ]3 B
int GetTop(Stack S,SNode &e)
$ [; e" L: f8 ^- p{. F8 V% y: h# [- p" @+ A, R
    if(S.top==S.base)
3 \( E! k- C$ k! H. v% @/ t    {7 b2 U3 h! A/ H: Z
        printf("栈以为空!");* D( V( G* ~8 i% E/ W" k
        return -1;3 b3 t) [5 g: d3 I2 ^
    }
* L$ u( U( ^, c( d    e=*(S.top-1);
* K  G9 W. z6 u* g6 i- L    return 0;4 a: H( `$ H- W/ X7 ~/ N
}$ v. G: F1 I4 X& g& r" T: K

/ \" `0 X, {$ i8 i/ g' O, mint Push(Stack &S,SNode e): S0 I+ c! d1 @3 [& r
{
% ~6 @$ _+ O& B4 B; W3 O    if(S.top-S.base>=S.size)
9 B' B$ m1 l7 u' I4 N6 ?0 X7 k' L    {# @+ Q3 Z% U* G- B9 K9 v! l
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));0 F7 \% M- f' F% C
        if(S.base==NULL)6 j* i) \) \4 a
        {
. p/ F$ x. |' o) G3 e            printf("动态分配内存失败!");1 Q) e- P. D! w7 u5 P: g
            return -1;7 M; t' [* d: Z- \6 q0 L/ l
        }$ \: @  ^1 G# C
        S.top=S.base+S.size;; g# H2 E" q" m
        S.size+=APPEND_SIZE;- P- ]$ s* \: J- g, k
    }7 p$ D) Q6 E  G, p  {+ U8 _
    *S.top=e;. h# c' W4 u+ m+ Z8 U2 n" B$ I
    S.top++;6 \  M3 e2 ^1 N" G: i
    return 0;
9 p+ P' Z( u" N, @}  S) G! |% Z$ x" l! C% c

, ?: P& d" Z) j- \int Pop(Stack &S,SNode &e)- O$ ~* \/ v4 e  ?* u0 O1 R
{' A- ]# N7 a) a# {9 x
    if(S.top==S.base)
! E- L( S- y  f% j5 d    {$ _0 T/ o; S; B2 z7 J2 d
        printf("栈为空!");* ?( G# F  U9 b' P* n4 Q% H
        return -1;
! I- U& h) I3 z0 G    }
6 I5 j9 B0 @  M, F2 o5 _3 I    e=*(S.top-1);) ~, ~- ]0 O0 Y  [  B
    S.top--;! v& r8 M% n6 \
    return 0;7 m/ V( k4 ~& \0 k- k$ J0 Y
}
7 F4 I  u' |3 _! Z. o2 O3 P0 B0 u2 H3 M( i$ i; t4 O* J( d
char get_precede(char s,char c)9 Z+ I! \/ N8 f. P. s* L- @0 ~
{  W  A1 @, b" [* k
    switch(s), ?/ N1 S: M% e7 `; }- }) L
    {' ^5 {( W& s- h
        case '+':                 
" u& D, i6 y- z! y& ?( I        case '-':
" S) z& |' w6 L( B5 R             if(c=='+'||c=='-')
& n, [5 e2 e6 t& B, P/ k                 return '>';% V. P5 v. S0 ^& ~2 A6 q" U( ~0 \
             else if(c=='*'||c=='/')" R* y+ G8 J, ^* V) g0 R. q
                 return '<';
& \8 |4 ^; \% f3 P0 e' K  N% y             else if(c=='(')9 |5 \  d+ y1 o7 \
                 return '<';2 U' \8 ?; t, a
             else if(c==')')$ E" X0 l4 R, |/ \6 `5 v% P
                 return '>';
. i2 G- e2 C. {% I             else
. D5 P6 A: Y0 t                 return '>';4 }$ g) n" H: j5 L4 a' x0 e5 ^9 h
        case '*':: F6 {" O6 m. m5 o5 S* s
        case '/':2 W; z- V- B/ W/ d4 ~
             if(c=='+'||c=='-')
! P. R+ H" h( r9 o! H4 V: a7 l/ E6 d( C                 return '>';
9 T4 Z' O" I1 `6 E! b; D" z1 u             else if(c=='*'||c=='/')
$ I* \6 J6 |$ ]1 |                 return '>';3 h) X+ J2 K) e1 I+ G+ Z6 ?; y
             else if(c=='(')/ k+ _& s/ `& |
                 return '<';
! w5 {1 ?$ r! v             else if(c==')'). P+ k8 ~$ _+ [2 o, p$ o
                 return '>';! v& q1 J) ]/ J  t$ d
             else
% T! c- j+ j* K4 D4 b' F                 return '>';
- W; J- n6 z9 A& o2 z        case '(':
1 Z$ g" F6 |. }  H, y# h# S3 T; Y             if(c=='+'||c=='-')
+ S7 y( z8 `5 Q5 x                 return '<';' c2 _* F; `( @! m0 s9 S9 w, L7 K+ B1 e
             else if(c=='*'||c=='/')
1 x- I- E" X. O1 I/ \( B' p                 return '<';
' b: l7 y5 A) Y; S1 Z1 H             else if(c=='(')% A7 a! }2 A, @" a3 ^. u
                 return '<';
& M" _7 l% j# Q, w             else if(c==')')
. M3 U4 \$ i0 l7 M( p6 P" I                 return '=';/ x, t; W+ x8 u# i( b0 R6 X* X
             else" d( L2 b- q6 I$ ^
                 return 'E';: p' ]1 f, Y# M8 G
        case ')':3 s' H* M& M, Z* J; ^9 a
             if(c=='+'||c=='-')2 |& d( v2 O8 |1 y2 s! A- k& e
                 return '>';
, p5 l6 a& i7 G' |             else if(c=='*'||c=='/')- [' n. c$ A: r1 {2 n
                 return '>';/ D  Z6 G% ?* M' T3 `* \( N3 ]
             else if(c=='(')8 J8 a- m' z3 j: ?( o- ^
                 return 'E';
$ c  i" q# K/ u             else if(c==')')  |0 |- y2 ^: }# w
                 return '>';! b% l. a; C4 I
             else, m( u! _, d* ~6 w* A& Y
                 return '>';7 i7 F& p- m7 R% x% X
        case '#':
' `/ m$ ?5 x% N; J/ R             if(c=='+'||c=='-')4 F' U3 {8 c( F0 l: s/ R( T9 V
                 return '<';6 ]* U# I* j  d( w$ h! ]
             else if(c=='*'||c=='/')
" F+ |. E& Q' Y3 Z/ R                 return '<';
/ {. d+ ?8 X! b4 ?. A             else if(c=='(')
+ M% v5 q& ~% S  u                 return '<';; p9 g0 m' J) J0 P& Z  R6 }
             else if(c==')')
, ?+ ~* Z0 S+ d% V                 return 'E';* T$ K9 z  Z1 N+ V5 f) Z: d. t  b' L
             else4 T7 e9 g3 a) b% W
                 return '=';
0 f- c  X$ H7 F9 ^        default:, y7 w; i% M: Y: r+ J2 d: T3 k
             break;' R( v6 p6 Q" J3 B2 h$ p5 {
    }
+ v4 L+ E: v9 _5 C9 |    return 0;   
: _1 a# M9 P- H2 v* |7 s! \% W% E2 X}
% i, C( R. i! m$ |' }5 ?
* \' ?5 [7 E2 S$ \- h- J+ |7 Rint isOpr(char c)
( h; u) R: X& r  V) y' J+ V{0 C  t( b2 t2 Y& I- ?: E7 b  A8 y
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
: V2 o& y! ?: Y6 t: ^2 m        return 0;" c7 h8 c3 i3 P6 Z) D$ t
    else
& j" s" l1 k- u, R        return 1;
+ k5 u. I4 p' F! X}
& t* b2 d6 r+ q2 F# d
3 t7 \8 ]' n/ d( [+ u' Efloat operate(float x, char opr, float y)
* Z- T/ O' r0 w0 V+ O{
( _" Y- ~- @# h3 K" V    float result;
+ V7 r% i8 t$ K; M    switch (opr)
* g6 S: ]+ R. e7 q) K" P/ C    {2 `% n) h! j" J+ D
        case '+': " p- y% ]( v( V6 v# g$ w
             result = x + y;4 K' F4 J5 y. l2 T' l
             break;, @  Z# g/ p" o/ D
        case '-': / t) |( I0 G( I+ ^. z
             result = x - y;8 T- L1 G, o/ h6 c+ n( y
             break;
# E4 i0 g8 E5 A% A% y        case '*': ; I/ J0 n9 \4 S/ P8 N4 |* }# G* D
             result = x * y;
" j. v; j4 d+ K* }7 U             break;
: n2 _4 O/ h! y        case '/': / }1 O0 r' v" X3 [- d2 v
             if (y == 0)
; s7 _- c# a) M* \& x$ G; R             {7 [7 e! A4 R" T( H  E
                printf("Divided by zero!\n");9 B8 r: F1 m! o; V$ K$ x4 W
                return 0;
3 I9 [/ v+ d2 A3 C$ |' J             }- s0 L: h& A' G6 |1 K
             else
5 J) x7 m! G' ~8 ?. s             {: ~- [4 h6 V! i( e/ c! p1 j
                 result = x / y;
5 p( a! B0 t) K                 break;
2 ~- v; }6 I" z0 [6 e; F( w8 o  e             }$ y  [: y" B9 R. P
       default:
  Y0 J- G, y( |# y. n: ^             printf("Bad Input.\n");
. K% V, X* ^$ ^  X" v4 b5 Q8 u6 X. [             return 0;- N1 f5 K5 @+ ^! A9 G' x
    }
# b1 N& u. J: P0 Z3 }    return result;& A5 B- j, c4 b6 G+ W( C
}   
0 I1 _2 M. U6 G) W: p
! c) D6 l" u1 ?9 n, c3 efloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/& ]) u* w1 O& X
{
5 ]4 A4 ?+ r5 }$ p9 h7 n, i2 ~" j+ z  E- `$ Z    Stack optr,opnd;
$ K4 B9 l* f* q$ K    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;6 D5 h) {- j% |0 ^6 G
    char c;% t8 R$ [' P/ r2 N- B, U; L
    char buf[16];# P+ o# {+ Q) @4 n
    int i=0;) ~& i$ _- o( T
    # I9 z) G, F' s! R
    InitStack(optr); /*用于寄存运算符*/
; z; v: N6 l+ j( ]7 r$ \    InitStack(opnd); /*用于寄存操作数和计算结果*/
4 M8 B  U1 a- B) [; v; f" V& H    memset(buf,0,sizeof(buf));
/ T% i$ x* l" w+ S5 l' K; d    $ U3 a* ]- t% b
    printf("Enter your expression:");
; d2 e& Q7 L. m* J' a! q        ( c# o. f/ E' ^' m; a+ D5 g: B' q
    opr_in.ch='#';
0 c  e, o0 i& ?3 c1 q6 \5 @    Push(optr,opr_in); /*'#'入栈*/
8 T4 ~: \( d0 Y    GetTop(optr,opr_top);
5 h4 ?; L- i% H0 P    c=getchar();/ [% R, `3 M1 g8 i7 `! _
    while(c!='='||opr_top.ch!='#')
1 E+ D' T2 ~' L" R    {
/ b8 e( ~$ K7 T, Y! b        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
4 M8 c/ \( u$ v  d        {* Q5 @1 Z, m7 z, I
            buf=c;
3 m; C+ R7 G' R9 Z: V) g            i++;4 ^3 z+ b' K1 h4 b$ H+ U3 K
            c=getchar();* ?, ?9 q( o& a) }. j! w
        }
1 Q2 Y; ^( @+ F! V. U6 a5 U3 G        else /*是运算符*/* n! Y, v& X6 ^+ b! z7 R
        {! V, P0 R# C; ?) ^& W
            buf='\0';
  y: E$ b) ~) M. Z( J7 ^            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
3 X/ V- K  b7 t8 H' }3 ~" ]( [            {1 X$ L" M( o; m( ?' h& B
                 opn_in.data=(float)atof(buf);
, q; |! x. l2 j  f2 i' y( T0 q                 Push(opnd,opn_in);/ }1 j) s, l9 o5 ?0 `& X$ R
                 printf("opnd入栈:[%f]\n",opn_in.data);4 d8 Q" P. R* p1 Q
                 i=0;
6 }9 y% w1 o+ `% ~. \( {, Q                 memset(buf,0,sizeof(buf));
, l+ S) P7 R$ f: J2 Z            }
1 ^5 w! }( _4 c- H            opr_in.ch=c;
, F& J% f+ Z2 q2 {! o" {. |            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
# l$ E& d7 C1 j            {
$ ~8 D% J% N- w) I1 ~( \                case '<': /*优先级小于栈顶结点,则运算符入栈*/
- e. i! B+ M! [3 t* s6 C) h/ \% e  X                     Push(optr,opr_in);/ w5 d6 M: G' h
                     printf("optr入栈:[%c]\n",opr_in.ch);
0 V3 i- C, P% x" Y" u/ f                     c=getchar();# U) ~# Q& h9 B9 M
                     break;. i/ U( s" [0 A. M) |' p
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
; r8 O% u2 Z, R5 l& v                     Pop(optr,e);$ K) {  `* A" Z: S
                     printf("optr出栈:去掉括号\n");, l0 A& D6 G5 W$ S; E0 G& S' ~4 `
                     c=getchar();
) A! u6 q4 W& |5 g! I, z                     break;5 Y) ^( A1 a- `9 H5 p  \& x4 [
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/7 n5 |0 @* v/ a9 M( O2 @
                     Pop(optr,opr_t);2 B4 c8 Y; H' d
                     printf("optr出栈:[%c]\n",opr_t.ch);
  c' c1 H) m( x  g( V$ `                     if(Pop(opnd,b)<0)
7 X! ~% y7 l3 p2 h8 {5 ~8 E% u                     {( y9 F6 i* f! t, S; V0 S  y
                         printf("Bad Input!\n");/ z! b+ w+ N) t
                         fflush(stdin);
8 n4 g1 c  i" V! j6 J4 \                         return -1;" G: k8 `7 t6 S7 h
                     }
1 P: K$ Y' i! v. F4 q                     printf("opnd出栈:[%f]\n",b.data);
* X, u) k" ~3 v+ q                     if(Pop(opnd,a)<0)
5 S6 Y9 {7 V9 u( |                     {3 }( j8 M3 V  ~( c* I4 j7 C; G
                         printf("Bad Input!\n");, P7 _/ L# @6 E2 E# c
                         fflush(stdin);
/ F$ t% q8 b1 q- a* a                         return -1;0 c2 M( t, ]0 T, h
                     }
# q, e) h) c" U$ n  N                     printf("opnd出栈:[%f]\n",a.data);- }- f; O) O% n1 z- O+ T& {
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
. e5 K' t# R* n( j; ]                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/3 D+ Q9 i. ~* E7 J2 p
                     printf("结果入栈:[%f]\n",opn_tmp.data);- F; Q7 `7 c  N7 i! i6 D7 O2 N
                     break;
& |; u: N  W3 g; m            }# }8 d4 {% d' l2 b! G( o0 R& c3 r- ?; G
        }
5 Y# G* g7 d8 o- r! E8 A  x4 ?; |8 A& w        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                - J# Z# B( m; J3 e7 `( {
    }; W+ Y1 I2 Y. L- Q9 x: U
    GetTop(opnd,opn_tmp);( Z/ H/ T: `- W: g( |5 f& p4 A  w
    DestroyStack(optr);
' N' W# ]% c; j8 O6 @( f/ z* {    DestroyStack(opnd);
6 @# f- y1 e$ p5 q' z    return opn_tmp.data;5 v" Z3 ]) a* t. S
}6 _/ x, @) L* g& X' o
2 O1 J7 @) g+ A# Y$ b
char *killzero(char *res,float result)
7 F' [/ [& c$ n{1 H# {+ ]( H4 d" W" ~7 m# t
    int i;
9 y, K" w% x2 H# y
! }5 f3 f3 w- I& `- A7 U! y8 A    sprintf(res,"%f",result);* ~8 e; F; }0 X  |
    i=(int)strlen(res)-1;. e/ p9 u1 S( ?$ x" H: j
    while(i&&res=='0')
! G, n9 W0 V. K4 B0 ^" w    {6 c8 N# {  v$ C; D
        res='\0';
; l7 G# W' y5 ~5 ?# m        i--;; I# ?, I' C6 C- {) }
    }
3 v4 c. L, Q8 }; K% v# R4 [* w: D    if(res=='.')
% u7 X! `% H! e# f( O+ G, m9 y        res='\0';7 x; ?" c4 @8 ~$ v% j" R" Y
    return res;& v* D2 d9 s( s0 O& y7 l
}; \9 U" z! d. H- b- Q: s

2 P$ T+ Y% |! }6 B" Jint main()) I* F. W. U: r
{
0 k1 K3 v5 z- y    char ch;5 O6 }7 T2 m' n
    char res[64];. A% u4 D  H5 a" G" A
    float result;
# V! I/ i4 a- y6 y( C, Y  p/ L    while(1)2 u5 y  O$ E9 \+ R
    {
: \8 d3 H% F2 Y! Q0 o        result=compute();
- A" g/ J7 e4 a) T" H0 ?5 [        printf("\nThe result is:%s\n",killzero(res,result));
4 @6 G3 n8 U7 S; E* y  E/ L- @7 d        printf("Do you want to continue(y/n)?:") ;8 F8 F- L6 u) q  w/ z. i' q
        ch=getch();
9 F( C: z5 Z: @( z+ e' r        putchar(ch);  u+ ]4 }6 H6 {
        if(ch=='n'||ch=='N')1 E2 [9 s% V: e
            break;
1 w3 |. B) Z3 ~0 r        else
2 L3 I! D3 j8 b  r0 a4 X' @9 B            system("cls");
* `& X/ ?+ c% b) m    }% W/ ~; d# ]# j7 L
    return 0;' s; X7 C. q, ~* l' |
}
# }7 q; }, @3 v+ E, p$ s; z3 g- t
+ T+ @9 B6 Z$ p0 G" F
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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