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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
8 ^7 C' z" ~8 `1 |程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=3 `6 X; m! q/ Z$ m. ?. g7 D6 B  B6 P
/**************表达式计算器************/
5 Y' `" H, \# J* f  T8 X#include <stdio.h>: ?( [# {6 J  W/ h$ v. \: \
#include <stdlib.h>
3 U4 f( }* g1 }- o0 E; ~#include <string.h>4 T6 h8 N: f$ M- i
#include <conio.h># I/ y( |4 p- f  f
#include <malloc.h>) q" Q0 ~4 p. g$ j4 p- f
4 u# c7 g4 D+ |3 L# E% w7 G
#define STACK_SIZE 100
8 v: S0 ^; m4 M#define APPEND_SIZE 10
' ?2 z3 b4 q, H  u" T/ [
# K) D! I0 G/ T) kstruct SNode{
6 T. R* t) n+ p$ E+ P9 M    float data; /*存放操作数或者计算结果*/
5 [$ N! k- t; ~: B- Y    char ch; /*存放运算符*/. c, {3 L: B4 C  }7 n# m
};
0 c! T! j( N$ U4 S. v( G" X) p: D% A7 R+ z; E* X
struct Stack{
) o% w# d; X; Z    SNode *top;6 A* b) b9 D+ R' [# g
    SNode *base;
* _6 N5 M8 o: R) V# L+ ]" M+ a    int size;
- O/ q8 L  k2 w; K, U" d};8 s. A( }5 ]- i
! k7 W* r; I$ ?$ T) f2 v: p' o9 y
/*栈操作函数*/- j/ r0 x& _  x* k! `; O
int InitStack(Stack &S); /*创建栈*/6 j" |/ c5 Y# D* A
int DestroyStack(Stack &S); /*销毁栈*/' r) {; @3 ~  U+ O
int ClearStack(Stack &S); /*清空栈*/8 ~: A6 B, K  S) a$ c$ b, s
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
: Q  P2 L* B) Z* A, l8 t3 Qint Push(Stack &S,SNode e); /*将结点e压入栈*/
1 V& K" G: g9 K$ s. Zint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
# u  @% `. b' y. R$ ?1 {: [; l' e* c0 m1 ^
/*表达式计算器相关函数*/
& }7 C) f/ l7 [+ ~3 Rchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
% L, `# c' F- ^: Q* R( y1 u# q5 J$ ]5 fint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
3 T' _7 m& d7 K) V4 Xfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/% }* Y5 z4 b8 L2 {  k( b' C
float compute(); /*表达式结算器主函数*/
# O! T$ t. p; J3 j( z6 M! T0 Z  dchar *killzero(float result); /*去掉结果后面的0*/ 8 }1 w7 b- h" H  T; F. h, M/ ~( ]
8 d' V/ R+ W6 F, t; A3 o% {1 Z
int InitStack(Stack &S)
' W+ C' v  ^# d: _2 A; f{6 Y% J- X  O: O; M3 p4 ~
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));& L6 d+ r: z9 A( V4 M
    if(S.base==NULL): S( D% t3 {+ j' ?4 r( m) ]* ^( {. k% }
    {
" s( J5 q' ~6 M* T  Z, H        printf("动态分配内存失败!");9 O+ s( c& J8 x) r# s
        return -1;  T+ p# U- d6 S8 G  @2 p
    }
) f( `  d9 |0 m% O+ @    S.top=S.base;& l, w( R7 C- T2 }' z' N
    S.size=STACK_SIZE;
) e% S+ C4 W! C$ q8 F4 U  e    return 0;- n( A0 Q+ C5 @2 C* L) b0 y
}; K, c( O3 S$ Z8 `
. l" Q8 M) r& C
int DestroyStack(Stack &S)* x( z8 Z/ ~- n# q. U$ i! _
{4 |4 m+ w" X) A" K' J( d7 Z) {
    free(S.base);
  ?9 y) x' c9 s# L    return 0;3 g/ _# K1 H% ]* @4 K: ]. e
}9 r- [# B" W8 }: C/ A' S6 v- W

+ l# F, r4 S3 d7 _$ m2 zint ClearStack(Stack &S)
5 ?7 m3 P0 I: Q" O9 b1 L{
5 H( G  c4 l1 Y5 z0 a1 l    S.top=S.base;
. L6 J3 ~5 g# d$ O" [' {; k    return 0;; j0 W. G5 H  f
}' B+ r; S3 T* F' A) m
* U  b/ S7 T7 |& \/ B& u
int GetTop(Stack S,SNode &e)
$ }0 s# q0 P/ v* t9 S0 R2 Q{
6 a. }$ X" W) F, Q7 j6 I2 G5 B- C    if(S.top==S.base)
9 N) }( _! C' s    {
  F3 ]8 G% Z1 a6 O. d        printf("栈以为空!");( C. k( Q% Q  P; U  Y* Y0 g* j6 Q
        return -1;
, [6 Q; O2 X$ `' F: p    }
$ x  J# d- z2 k  L! Z- ~: P0 w    e=*(S.top-1);. U" W6 [( d. j% s1 ~( d
    return 0;- ]9 c7 s' O2 A6 ^
}* k  ?- u7 `+ m0 R! A, b( Q
0 G9 [  S* j6 w1 l: N9 D# K
int Push(Stack &S,SNode e)) ^9 s0 A5 B. T% |7 O  }9 U# m
{  {+ l$ V3 U8 P" K
    if(S.top-S.base>=S.size)% {& _9 G# H$ X6 M5 v3 e
    {8 [6 y4 r" v5 X" W
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
" k0 R( s7 I* T2 E% s4 F) f        if(S.base==NULL)
; _7 b1 S9 W( z5 E  B        {% `$ I$ b$ w# ]* T" o
            printf("动态分配内存失败!");
7 G: x" j( s/ P7 F  z3 m* b            return -1;8 Q5 u' f5 `' O9 Y* F2 ~8 i
        }
- k2 [$ U5 G8 e# D8 e* I        S.top=S.base+S.size;
& ?) _+ h% Z( m( c        S.size+=APPEND_SIZE;
7 B6 N, v; u- z6 J    }" A7 _4 B0 ^, `+ q1 X
    *S.top=e;
+ Q5 m, Y3 a# }    S.top++;
; T, I: u" _$ D2 K6 |( I( }4 I7 Z+ L    return 0;
- G' f; @% F& A2 v}7 m) J5 `, L8 u/ k  s' g- T

7 b/ _& x3 K/ gint Pop(Stack &S,SNode &e)
& A: W& O$ `( C' |( e9 i{
. w( N; {& s, p5 |6 K6 m    if(S.top==S.base). y8 l' y( r% O( j8 \) }3 z# n2 ^1 a
    {6 A/ U0 h* j/ J* t+ i3 O4 h/ F" j
        printf("栈为空!");$ ]% H( u  m; s4 q6 ~0 y
        return -1;
. A' u" t* {( Q/ t# g/ b0 h    }( R( Y: k* C" a+ ^, M& `
    e=*(S.top-1);
% Y/ F/ V; `/ p& C& k    S.top--;
* o; w* K6 \" d6 K, G    return 0;
' n1 M; q8 R0 O. w6 i" c6 S6 E}' L6 \# Y! b& p" n" ^8 {
" N9 @& D9 v5 B- i
char get_precede(char s,char c)# ?- k4 Q; `4 g( b4 u/ }! g
{+ w6 A2 i/ v5 r+ R* e  V
    switch(s)
" v% d* L1 q+ e' O5 Y  O    {( t3 V' i* e8 r5 l+ G$ S$ y7 B# s
        case '+':                   X. ]( P) E4 p8 ^; S5 k% i% ?* f' f9 r
        case '-':
  p( z( e# Q" z# O+ L# [( @. r             if(c=='+'||c=='-')
  J0 T; Y4 T; L                 return '>';$ H+ S: p0 w/ U( z+ B; }
             else if(c=='*'||c=='/')
# p! |  \1 p* `1 `* N' i                 return '<';
% `6 z5 V# g$ d! H$ L7 z  g+ j             else if(c=='(')7 G) m% Z8 \2 F3 b4 A
                 return '<';$ y. a5 b( p2 A9 f0 U% q
             else if(c==')')) x2 G! I  l! G% V/ I
                 return '>';' s4 U3 C( x" y7 Y0 F% B! P
             else
/ C" ^: C* F5 l' h+ A; h                 return '>';
* G; y  |9 _% Y+ G+ @, v1 g        case '*':+ u9 n% F# Q' S8 a; d% g/ Q
        case '/':) j0 U$ s% Z; d3 l$ z0 F" L
             if(c=='+'||c=='-'). e5 i4 W) h" D6 M
                 return '>';
- X6 h# B0 F8 I             else if(c=='*'||c=='/')
* I) w& T, ^$ C: A                 return '>';( V) w0 G+ \' g' h0 n& p' W8 [8 l( Y
             else if(c=='(')$ V) U0 V) T7 q! D6 s+ K" r
                 return '<';
, L) K. z* I' H+ R& @, D             else if(c==')')
9 J& _; s5 N! Y1 }7 h: O; w8 D) b                 return '>';" A7 ~( a" C: k; Z! c$ ]; J3 G  m
             else0 n6 t; J- G+ U, Q% F9 t  J; O
                 return '>';8 z# n5 I% V3 W  _% M$ g4 Z
        case '(':
" p5 A5 O8 Z6 |* T1 t             if(c=='+'||c=='-')6 E; b$ [$ k5 o. R0 u% j
                 return '<';
, i. {& S9 E/ @3 V             else if(c=='*'||c=='/'); h4 m# I* c6 ~/ b" i: O) K
                 return '<';
/ D! {- l% t4 C             else if(c=='(')( l$ O- W6 c$ k5 |# _) x) w9 H. {
                 return '<';7 v1 z' Z" {( g$ ?: G7 ~
             else if(c==')')( c' S- f3 B# ]0 F& U) G
                 return '=';/ r- G6 V* H/ `7 q4 Z/ G
             else2 W! a5 {% y% Y3 V" i" T" ^  ~
                 return 'E';: c0 X* p! p& P; O5 z
        case ')':+ E" Z( s8 X0 F2 p2 V, f
             if(c=='+'||c=='-')9 A  a" r  F( ?0 B( H: ?
                 return '>';
4 W; D6 }( ^) B: r  B* d8 l8 ^3 E             else if(c=='*'||c=='/')! N7 i0 u0 ], Z. J- t" v* U* G/ S
                 return '>';
3 o4 P. S) N4 x% H( H& H8 e  q             else if(c=='(')
7 \! B' @& r; z: I& y' \                 return 'E';
$ @" E) }. ~" ?0 A             else if(c==')')! J) [; A2 M. G) Z
                 return '>';0 Z1 V3 @, F) y$ D0 u
             else
/ a3 p) S! j7 a4 b3 n                 return '>';
& a* W8 r/ s, O. N        case '#':- D. m: w1 [; _/ p4 j: k
             if(c=='+'||c=='-')
4 ^2 \5 U$ J! r3 o7 J9 h! @; O                 return '<';7 L8 Y+ o& R* S5 E
             else if(c=='*'||c=='/')! A+ p6 _5 a/ H  m
                 return '<';* S9 k: S5 t9 m" s2 Y) Q$ ~
             else if(c=='(')7 u6 ?) p2 q( Z4 P% q# ~
                 return '<';- {( }1 w. A" ^+ y, o3 x
             else if(c==')')
- ^$ K% S4 S+ e' y8 I+ C                 return 'E';" ~* b" M: H/ C% n
             else
+ V8 s# `. v- f" y6 |                 return '=';+ I0 T$ n) G$ E1 u" X, R% P7 {
        default:
& T9 r$ g8 D/ `7 p) k* }& r             break;: K+ Z& W. [7 ^' }& i. a0 Z
    }9 T, T& F* t5 A" E, R
    return 0;   
/ @8 k0 d( G* V) v}
9 A$ n0 U6 m0 ?6 _1 G  S* c. l! [' p3 y  u$ G
int isOpr(char c)
5 Q2 |8 K- A' o0 F$ v5 j{
1 Y' e% G6 W; }8 z    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')9 ^( y$ b7 A% G
        return 0;
) ?7 \0 a# G- G' i/ G6 @& h5 Q    else / ~: V: v$ e) p' ^" y
        return 1;' a: @+ ^3 y8 J' k- Y* D, ?5 s
}/ N$ a  i3 W+ q2 f
- |* \' d+ Z0 V9 e
float operate(float x, char opr, float y)
9 c% Z+ o. v; C- ^! m2 ]+ q+ y( b{1 F  e: K$ O9 e( Z9 l/ }
    float result;
0 e) M& K/ k2 P9 V    switch (opr)( @3 F" S5 u0 w% z4 H- X. Z3 v
    {
! p7 l; e, p; L        case '+':
$ H0 `$ ~! c( t0 b+ M+ @: e9 I             result = x + y;
$ N6 f* V/ @( N: B             break;
! h, U6 |2 w) b4 T! t: G! \        case '-':
) t0 ]) Q1 l2 r5 @             result = x - y;
; u( s( C9 p% ^- g- I! }/ v             break;
, ^2 p0 v/ I9 _! e+ i+ e2 D        case '*':
, D' P; Q) L- P" f; E             result = x * y;
( l% T0 F  `$ a: G' a  N- O             break;) s" T: j, U! I0 C( v( o
        case '/':
2 X$ q' F( z1 t6 U9 B6 o2 ?. f             if (y == 0)* ?& O- D8 t3 q' K
             {
% T/ `9 p- {* I( i- L* U1 B% c0 i                printf("Divided by zero!\n");  M( n/ l* D* G) j
                return 0;
4 ]% p+ u, h7 M: u             }5 P3 o7 e0 J' K7 Z5 S: `
             else5 Z0 ?! V% k; }( X" b- x4 _' {
             {. ]; F5 P; r/ A
                 result = x / y;
" X5 Q( U5 v0 j" H/ b                 break;
+ J* s. c# _6 s; J             }; X1 ^+ t( I( x1 {6 `* w
       default: , S& T+ |, B% a) v
             printf("Bad Input.\n"); * \3 A4 m$ M) o. @# b
             return 0;8 d: {; Y  T" r
    }
/ ]& e6 d& B: H4 b5 k    return result;
) E5 y% D6 S3 v2 E}    ; D2 z! e, n) J0 r
: t$ O& S% \# s: x; B% ]
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*// e( w, C3 L! u  e: e  l6 G
{
4 a% ^9 m0 u1 E! e! Y! i3 M    Stack optr,opnd;
: l! V1 M$ ^  H3 ~; x( d* s    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;- z$ n. i" V( E
    char c;
+ P1 z! `3 D9 d. @2 y/ y- ]  i    char buf[16];0 Q1 [5 K2 s, y* M% i% F' g/ [/ Y
    int i=0;
1 Q6 ]5 b7 j0 y   
: @1 _3 g. b7 N    InitStack(optr); /*用于寄存运算符*/2 R3 @; d! j9 s. s6 Q: K% W4 Y
    InitStack(opnd); /*用于寄存操作数和计算结果*/8 G/ m5 z/ n2 O/ [+ @
    memset(buf,0,sizeof(buf));
7 l- w# y# U# k3 [7 d" O% a9 h   
6 i! j' B# D3 [  M    printf("Enter your expression:");, t2 ?1 N4 S* a6 V- F8 O
          P4 O* x0 B/ S7 Z' V
    opr_in.ch='#';
6 a5 U- o' Q2 M/ P7 X3 Z9 a8 z    Push(optr,opr_in); /*'#'入栈*/; ~/ P- t5 V+ ^6 D4 i8 \3 I) P# E. q
    GetTop(optr,opr_top);
+ p5 p. i7 z6 K5 M3 K% T! M    c=getchar();
" U) H- w# b) H* j5 H% d: n* ^' F    while(c!='='||opr_top.ch!='#')
! G  W+ ~9 |; Y1 R    {% F7 k/ v) c7 x1 t  r) U. V
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
$ o4 o0 r. [- B/ P' ^        {
. n: S1 b2 k& r1 R  `% l% |            buf=c;
% U9 n7 _! r- a6 h- I4 }; U            i++;6 L! \* z! ]/ _' G+ l$ R
            c=getchar();& T+ U8 W$ W+ I5 T  _
        }" B# W: h2 k$ W1 v) z
        else /*是运算符*/+ [/ t+ o& W: i* _
        {
: P( S! ^! M, t  Y# V& r7 Y5 `            buf='\0';3 A6 D2 X9 @( M, g; X
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/. D  j4 e8 w2 V- o! J2 G
            {
# C+ ]9 G& s5 D4 w0 H                 opn_in.data=(float)atof(buf);
6 _* i% o7 l0 ?8 F  l# l                 Push(opnd,opn_in);
9 G5 ^/ [9 d" `% i                 printf("opnd入栈:[%f]\n",opn_in.data);9 y7 \! `$ s! L* |
                 i=0;  j  k# y3 i& ^2 i; p
                 memset(buf,0,sizeof(buf));
  ^9 Z9 o# ^; K( q# v0 T            }
& O2 c+ Y. f* d0 ?            opr_in.ch=c;
" n5 p7 P9 r; y+ c0 X7 `. M9 ]            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/! N% ]2 M% c- B+ h" v. ?
            {4 i+ @' P5 {" a  L, h1 P6 {
                case '<': /*优先级小于栈顶结点,则运算符入栈*/! f8 e. X( o' g6 }
                     Push(optr,opr_in);
+ c7 T$ A0 k3 o2 H8 @! i                     printf("optr入栈:[%c]\n",opr_in.ch);
: v5 v' H/ S: H' S                     c=getchar();
  I/ I( J/ T6 f* P* I. t9 k                     break;
" w/ _+ J4 S3 |4 F                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
& i- B; x( B2 a' P3 D( Y& B                     Pop(optr,e);
6 E0 R+ Y) R# _                     printf("optr出栈:去掉括号\n");, J1 f4 S- |' T% Y
                     c=getchar();
( v+ x9 Q1 M% I) j* }                     break;
8 y. ^! x5 _6 [' j                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
$ S; X7 l) V+ n: X0 Z, C2 u- E                     Pop(optr,opr_t);
/ G  |/ J, B* @7 i. b- l                     printf("optr出栈:[%c]\n",opr_t.ch);; w( h- x: x+ N) }/ w1 N! m
                     if(Pop(opnd,b)<0): |1 J* U- @. }* a' N
                     {, u6 o. q7 ^+ i3 S
                         printf("Bad Input!\n");- l8 W+ Y1 K  D. K' d
                         fflush(stdin);' v% h0 |0 k# H' s
                         return -1;
7 O  V4 J* V$ F+ n+ a% C) R) z                     }
! N7 y: i4 a: V" E- w/ ?- w                     printf("opnd出栈:[%f]\n",b.data);
4 f: y2 @- D5 A6 j0 ]' J                     if(Pop(opnd,a)<0)9 S& S& k: y1 y4 v" e/ F1 I
                     {, r3 p9 _/ m) z0 A5 e' S
                         printf("Bad Input!\n");
9 Z# \' ?7 G  p) V( @                         fflush(stdin);$ F, S+ C- Y# `# a" O. f; p
                         return -1;3 O0 E' `! S' y+ Q& V' ^% e! M/ b
                     }( {1 O4 o7 C* ^' k; I/ L2 C
                     printf("opnd出栈:[%f]\n",a.data);" Y4 D: D: n8 |" _) g! F& N
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
$ ]. q6 A* }$ H( g* y& l                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/  I7 U+ s+ x  U. G- Q
                     printf("结果入栈:[%f]\n",opn_tmp.data);
! A0 E3 n$ J/ E: v                     break;
3 O+ m9 C0 t4 F' F            }. f  a6 J. ~; I9 U& ]
        }
4 Q) F7 F0 w$ @( _+ ?! a        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
5 O8 R6 k$ t4 R3 t; j8 R    }$ u1 P- [+ ]# A# w& _
    GetTop(opnd,opn_tmp);) M% R/ J4 C5 @: K
    DestroyStack(optr);
( Q  M$ W7 g. R* U! @* _. G3 [* ]    DestroyStack(opnd);
3 C/ Q, x) E0 Q4 R    return opn_tmp.data;
4 d' d: j3 I1 p! q, k3 u% M5 N% G}
$ c" a% c! s4 d5 [" g4 C& |! D3 W" C+ w1 L& y3 S% F9 {8 H5 V% W
char *killzero(char *res,float result)- Z6 z& E4 M* t) \
{4 ^$ }0 q2 s) L
    int i;
) n/ X7 S4 j  `1 b$ C( l  T: F6 w4 G! x! L) m
2 n$ P9 x1 X. K0 h! T    sprintf(res,"%f",result);. M# v5 H" p! z) ^  ~* N9 r
    i=(int)strlen(res)-1;- _& d5 y' Y+ J- Y1 W) @* r
    while(i&&res=='0')
% p  a1 }: f, }' n/ F    {0 X5 @! \4 ], F( P5 z" Q4 @
        res='\0';) k) J* N+ R  u% B$ m; B! a
        i--;1 m* h0 `! |. g, X
    }
/ Y4 e, J- d* x    if(res=='.')
& g0 i- s7 a. n- _$ G        res='\0';
5 v9 _8 J0 M! z" K: J5 }5 ]5 W; I% N    return res;" c4 r4 O3 l9 {) s' d, a# s
}
( Q5 r4 R- B1 Q) l; q$ A0 l' P
/ a" F  @) b8 Aint main()
% h; ?; @3 \" K" q$ `" y& t{
# y# Z8 O) S; d$ @* G    char ch;9 U0 e- M9 ]$ T) M2 ]
    char res[64];; J, n; t6 G" V+ o  [6 U5 S
    float result;
2 b8 C# R& n8 z. `( M4 o    while(1)/ X' o+ o8 m+ S( f' I
    {
0 B5 i9 e" a. z4 T        result=compute();
* z2 B. R3 j8 Z        printf("\nThe result is:%s\n",killzero(res,result));
& V4 r1 W  N5 F+ g, f8 V        printf("Do you want to continue(y/n)?:") ;3 i0 A# R; }$ @$ f4 c
        ch=getch();
* _+ L4 W! r/ o2 S) G$ S        putchar(ch);" D8 N+ t' ]! m$ ~( S
        if(ch=='n'||ch=='N')1 P/ z; j. i1 y5 B0 z3 f
            break;
5 p8 S0 N# D% a3 L+ g) J( ?6 k- f        else: i7 Y4 @  B; E
            system("cls");
3 m0 W+ @; O( Y* p4 H, \2 R( s' O  G    }, E' C3 l: g/ I7 {- Y: ~
    return 0;! G. Z8 U4 Y9 z0 i' l) D
}

% H" H2 r( u. d  o, X
. n7 x/ M4 [" v[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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