Board logo

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

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

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
& O/ Y& M' }  T* ~  l% D程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=4 b2 \2 ^$ _5 a& C
/**************表达式计算器************/
9 W( K& u' w% b! Y6 D! l8 w9 Q#include <stdio.h>) M+ @5 K! H" z& c, Z; T2 X9 E
#include <stdlib.h>- {2 }, j4 x& u" q' d3 w- M3 n
#include <string.h>- K; p, t, a4 c, n
#include <conio.h>
7 s1 [$ i3 m2 G#include <malloc.h>
$ `. K2 H9 H7 T- \% ~6 @
, _: d: R+ x4 c6 z, ~#define STACK_SIZE 100) \3 a1 x2 N* E* ~6 @$ p
#define APPEND_SIZE 10% C9 w- T1 n. ^  `) m9 w  \& w

7 ~0 q0 M- c! D6 s' A' ?( Zstruct SNode{
* v7 a  i$ }5 K* D0 }- M    float data; /*存放操作数或者计算结果*/
8 T4 J: t* |  }    char ch; /*存放运算符*/  ]! v) E$ z+ V2 l
};
0 ~: a7 x( z3 Z1 S$ o, z
6 _( ^0 F  j6 [; [! E, i3 gstruct Stack{5 Q- }* f5 K. S/ H* Z
    SNode *top;
% n: K% k$ E6 H5 K- i    SNode *base;
0 `1 D% \3 Q; h; @" g) `    int size;/ p( O' j; U) N. |' K  n
};; k( T/ ?- p8 f6 ?5 K

! a1 q* A8 G' d" @/*栈操作函数*/9 n  t  [0 a9 f# F' J2 J
int InitStack(Stack &S); /*创建栈*/
2 q  y" T& d. oint DestroyStack(Stack &S); /*销毁栈*/, Q9 Q# l5 g2 U) p4 v" f5 c2 F
int ClearStack(Stack &S); /*清空栈*/% K  C% q7 l% D  n, u
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*// ~# {2 c. p2 ^% X3 _8 _; f: b
int Push(Stack &S,SNode e); /*将结点e压入栈*/0 ^' _' z/ K+ y$ [6 `/ [% Z; }
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
8 i. Z0 {6 J" q" W/ r% k0 ^  C5 a' D
% t0 ]: K5 U: `" i1 y/*表达式计算器相关函数*/: i- F6 j0 F  x( C
char get_precede(char s,char c); /*判断运算符s和c的优先级*/. ~: k7 L4 d0 d  w, o  Q
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/$ j3 {2 o* H2 {( j: l3 J
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
! E. P- r& I( n" {' B* X2 sfloat compute(); /*表达式结算器主函数*/1 I) s$ S4 X* V7 q
char *killzero(float result); /*去掉结果后面的0*/
9 Z' e- }1 ^. F3 |2 [
% B) H/ D3 R4 h7 O' P3 X9 y2 bint InitStack(Stack &S)
" ]# i/ u- c4 O9 {* p{, k0 S7 ~( N, F* u# m( A" s* m! L
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
# Z$ X+ o  q5 r& [6 _    if(S.base==NULL), n+ E4 f. H- d! O) l
    {
7 Y( C- x4 |; f        printf("动态分配内存失败!");/ O) N( R+ x" c/ |$ I
        return -1;1 [2 g3 h, M" Y4 i; ^
    }
& s2 ]' y1 R5 w. D; U+ }4 g3 _# x    S.top=S.base;4 L) M2 m- }2 Z& J5 e0 C% c- D) p
    S.size=STACK_SIZE;
# F# j3 k& j5 A6 L$ b5 x    return 0;* e7 ]# M5 C- g6 \) D( _1 A3 G% O
}
! I& y% |0 |! K% R3 H- ]8 n  B/ y- b' }. H3 ^
int DestroyStack(Stack &S)
7 h1 A1 c( O# s{
( p! e0 H) ]( r  t    free(S.base);
# F( r8 L( p/ d$ d6 r! p( Y4 }, X    return 0;9 I1 ^! M8 ~* |3 K" x9 O
}
5 r/ S+ @/ d9 ]# e6 H+ G; e3 z! P9 t' Y# J2 @
int ClearStack(Stack &S)
" O7 {, ?* f$ w: q{7 m( `# \* N3 _  i5 w
    S.top=S.base;
; i, ]8 ~7 Y) R. c# E    return 0;+ [% h9 M+ B- |2 g, X# q, A
}  S  q' k8 t) X7 N, B8 ^! ]
4 W" P. @) W4 U+ c# L. }( r  t2 O' e
int GetTop(Stack S,SNode &e), W1 D4 O& q0 c' Q: n, s
{( [' \  R* z! c8 F7 ^9 u+ I
    if(S.top==S.base)) X& ]- Z' h4 O4 y0 o4 }- E
    {: _: {8 B8 l( h: I
        printf("栈以为空!");
9 Z  t5 P9 U  x, c3 V9 w        return -1;1 D. O3 O/ t+ O; ^5 |
    }
6 M% o4 N8 E  t  ~$ V* b! o    e=*(S.top-1);& f  J8 Q6 ~8 ]3 U- [+ ]
    return 0;
5 z, z0 ~3 o& Y- D7 r! v: |6 e: p6 R9 e}
: ]  Z: U0 m* m. q( P( T3 D
: K4 A$ M. n- i  {$ Bint Push(Stack &S,SNode e)/ E/ c' t9 D6 t3 ]5 O
{. \; v, _" ?+ r" e9 j# w
    if(S.top-S.base>=S.size)
! y, k* \# @7 x    {
/ {1 B; R! x6 t3 w- @1 h1 A; C; z        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));9 i) _$ q% e7 B7 C! P
        if(S.base==NULL)5 L) y3 G5 ?5 G3 S2 f7 X
        {! K+ r* z7 I4 L; M, q
            printf("动态分配内存失败!");
& j! y1 e( z8 `            return -1;
) L5 Z: x2 m: c$ f3 g  E( n        }
2 S; t& J; T/ }5 f3 q% ^8 O9 d  c        S.top=S.base+S.size;
3 k  q9 c9 p. Z# a        S.size+=APPEND_SIZE;0 D* Z, V- z8 X" {
    }( }# h3 [5 E: G- Q, J
    *S.top=e;
1 {5 q$ |4 l; J* j9 c# K4 U    S.top++;
! N) ~0 I6 q# c; I+ x    return 0;
' z* R& s: j$ X' F}
9 Q% v, v. ^1 k8 o" g2 ]* Z$ d
* t& Y! X$ X9 [* n$ Oint Pop(Stack &S,SNode &e)
( S* R2 S0 M; L' g- v{
- q: E  e5 I. U) z+ ?' Q    if(S.top==S.base)
' a1 w- [) q% u4 e5 A# Z    {( d. h* W$ E; W3 n
        printf("栈为空!");
4 n2 i: p3 F8 q" I        return -1;
7 a1 R. n7 q# E+ z* @1 ~    }1 j  K5 n; o2 O/ z
    e=*(S.top-1);
9 c6 B5 a5 u  {- l    S.top--;2 L* X& ~, ]2 s2 _5 m7 \+ l
    return 0;
# Z( y- i) z+ R' S}
! w; C$ d+ M4 k& C4 }7 |) x+ a  x1 w* l4 G; H
char get_precede(char s,char c): y7 d0 \. [1 w8 C6 ~# y8 m! j
{
8 r2 l9 n: ~: ^1 M    switch(s)0 v( ]9 ]5 @1 q
    {" t& w/ N" F0 ]# Q2 O
        case '+':                 
0 B/ y+ L* n2 {# L2 P5 _        case '-':, L0 R6 P* |' M9 y% Q9 v! \
             if(c=='+'||c=='-')) |8 ]' {, o; P" F+ H. A# w! h! T
                 return '>';3 K6 `: q7 t$ h. p8 t0 n4 z  S
             else if(c=='*'||c=='/')& N* k& Q, v/ P# b* [
                 return '<';) j( I, Q( C$ B0 Z, T- C# f2 I1 t
             else if(c=='('), u& B3 c+ E+ Z1 t+ G4 e
                 return '<';" ^$ l& G8 \, b
             else if(c==')')
8 n! W5 r9 s; @9 f( w  v3 ]1 y! ~                 return '>';. G( z8 D( t( i* O
             else
& D$ O; G# }8 I- v9 G0 X                 return '>';4 f2 h' d( F7 o! L* E( c
        case '*':
) U: ]5 }1 \/ B) i  D& }        case '/':
+ S/ h/ _5 R* m; H+ p             if(c=='+'||c=='-')
+ ]' B8 u. W  h& @! M! o- a                 return '>';$ f1 P6 ^/ D; |1 P4 h7 ]- `4 Z
             else if(c=='*'||c=='/')5 T0 u6 X( z1 `; m- s* B
                 return '>';* F" w3 \) w) y. J! m( b! d
             else if(c=='(')3 d. ?1 w2 `6 S- U! l  |
                 return '<';. c) P* d$ q/ M0 R
             else if(c==')')
8 m) P; i* b' M& G0 S7 T                 return '>';
# U$ r  k* u, a' S3 |$ \* s             else
7 C2 g- e  ^* o) O" J% U. e( F                 return '>';; m; L. t6 V  _7 F: f. S
        case '(':5 Z6 C. h8 e/ h4 Y  U+ |
             if(c=='+'||c=='-')
6 _! v" q2 q8 D0 H( E                 return '<';# {, L4 M6 j# f4 [
             else if(c=='*'||c=='/')& _; H7 B( t, z! i/ a
                 return '<';
" V3 O( \! D. y$ D1 @             else if(c=='(')8 s( S( T5 \7 d; c5 I0 ?
                 return '<';5 F1 X& [' F) j0 j
             else if(c==')')
% E+ `. \% u4 l                 return '=';+ c1 c7 y+ ]1 z$ e
             else1 Q1 ~1 i+ N- h: \- _2 r
                 return 'E';
2 p& }6 ^0 _5 @, @2 v& p        case ')':% o, A1 g* u4 W2 N1 Q
             if(c=='+'||c=='-')
; w9 N1 n, ]2 p                 return '>';
* v1 Y& y+ r8 [/ {             else if(c=='*'||c=='/')0 ]# ?4 ?( D  I3 l; V* A% s7 E5 [
                 return '>';
: ^* d% I0 a4 {3 ?$ g* S8 |             else if(c=='(')
' @2 G% f7 O* Z& p                 return 'E';: z$ p1 ^) y0 ]
             else if(c==')')* e& s- v( `. N! ~; J5 `
                 return '>';
7 r9 B9 K- N2 U( G2 W; r, ?             else
4 v1 s1 D2 ]/ n( u6 e                 return '>';8 ]* g, n* u8 z" B& ?6 a
        case '#':, T9 k* k* i  q- X/ H0 ?: G5 r
             if(c=='+'||c=='-')
+ k( U: l/ Z! L7 R6 I$ e; Y$ e                 return '<';
- Z5 U" [1 o9 y$ r5 R             else if(c=='*'||c=='/')
$ l1 v; U# f9 P6 {) K7 z4 y% |                 return '<';1 Q- C. {) l$ ~" \7 A
             else if(c=='(')+ m5 x- Q- c7 J) }( ^2 S
                 return '<';
8 m( W# [2 V9 W  I' e8 y             else if(c==')')
: B5 x% \6 k; R+ Z                 return 'E';
. r% q- U6 r5 L: {             else
6 [% U+ J$ p; B* Z2 G; Q- l+ p8 p                 return '=';% I+ t# K' j+ J6 f% U; k# ^' c5 H
        default:
  \" n8 v6 A! e8 i" E* F' V4 i+ _             break;8 s0 \8 a# X/ @, C" K
    }$ Y) _( `9 f- K0 f& n! x! N
    return 0;   
. N. a3 R8 o: Q% E& w3 d( Y8 ]}
5 X  A$ y; r! b+ \& s
, Y7 Y! N0 h0 b* y- hint isOpr(char c)7 u8 d0 M$ c+ Q' v. p6 p" v
{- x7 B  r) T* b2 y( u0 q
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
( ~$ V: A% i4 F  M& ]" ^, z1 U        return 0;
* m0 d8 ^- V5 m' h1 Y9 x; M( W* s    else
  L# ]$ `' P* Q& A7 f2 j        return 1;
5 H# l& C' r2 ?1 l}+ |7 L( ^' o/ ~7 o

5 h. b0 H& d5 n4 \# C1 {float operate(float x, char opr, float y)4 Z1 g( e9 I9 u+ }
{
2 U$ e4 }/ ?/ L    float result;$ N+ ^9 B5 y/ e  `
    switch (opr)7 r2 M% y" A. _- J* Y+ \3 Z% s! e
    {
4 N3 G: E' m5 u" a4 w        case '+': % z: C$ S* ?' f
             result = x + y;# A6 A; a  K4 Z
             break;$ D0 R( |8 j6 p" Y* `, K
        case '-':
2 A% _9 D9 I) G3 {  N             result = x - y;  [4 {' `, ?5 B* ~" v9 V* S  P7 l" o
             break;9 q' L+ q% `0 J# {1 j
        case '*':
3 o; z2 ?# \3 D# ~- i( d             result = x * y;
8 @! {! u/ h7 H& q& m7 }) ^             break;
9 s3 V; _& h8 g  x, c: O        case '/': ) f) x) e) q( w3 @% E; S
             if (y == 0)
2 [8 v9 k: U; G5 l* K             {
- K2 U" S+ S+ |# |                printf("Divided by zero!\n");1 f- k- a- _- `8 y- _+ r3 ]
                return 0;
8 S3 P, @7 }1 D$ N; O8 i) V4 W             }
4 e: V. K4 G( ~/ l# v" U! s* ?             else
, C* u& T6 P. [             {
) N, P. g  ]% `% g! Y2 x                 result = x / y;5 P0 [- S5 A( g2 c) E4 E$ L: R+ H
                 break;
  q! r/ P/ N/ K. t- ^* I             }4 A5 d- q, Z! m  l
       default:
$ H7 Q4 r/ \3 w% J' S0 F. [             printf("Bad Input.\n"); . M( x6 |' p0 Z& `2 Q$ ^
             return 0;
4 _3 u" V. m6 e  t    }7 \* c5 o' y- T1 i, r! P
    return result;4 G7 k% q7 L+ z& e) B
}    $ T0 p0 K& o0 G  S2 l: G
! \8 r9 m, v( i# j* p8 U. W& B
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
% T& D" F) ]7 z0 X. l9 O& }{# t8 Q5 L+ U9 I5 g9 I0 v
    Stack optr,opnd;
1 i) w# W$ X  W/ a4 D% b! x' D( Z: n    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;7 S" _$ t1 @+ L
    char c;
$ w  g/ t9 i2 M$ S3 j    char buf[16];
4 f7 N& ^, b5 a$ d    int i=0;/ k/ q1 M4 `0 e; O, L* s' M
   
) c, c8 [; C( @. a    InitStack(optr); /*用于寄存运算符*// t0 X; I! h3 L' m7 P
    InitStack(opnd); /*用于寄存操作数和计算结果*/
  Y& Q0 j- }1 x! h, g    memset(buf,0,sizeof(buf));
- I6 U2 I' Z( M1 p( `) ]    : c% V2 x$ N8 b9 H) q0 l: R7 ^
    printf("Enter your expression:");" l* b5 V2 r+ p; t' `' k/ Z" w$ T0 v
        
- K0 i# b' S/ F: I    opr_in.ch='#';% T" c" {& v, g! v! p
    Push(optr,opr_in); /*'#'入栈*/
5 b- Z9 R& s' w$ q/ E* z2 s    GetTop(optr,opr_top);: d- M1 d' R2 z2 g8 F7 [7 W
    c=getchar();
$ n4 W8 o; {3 r/ [) J4 T; B    while(c!='='||opr_top.ch!='#')% d6 {! Q% a5 }: Z
    {: S9 Z- E5 R9 |# e! B- C5 m' U2 M
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/- {, e& Y  h9 B1 q9 m
        {
( B' n: r$ b6 V* ^/ F. q            buf=c;9 M( |* T  U$ b
            i++;5 Q% n; f9 ~7 \% V
            c=getchar();( j6 p. F& j( f7 l$ J! J# f
        }
& x( c4 C* \% T, \, ?4 }        else /*是运算符*/
, y7 \9 k+ y& N& Y" e        {1 m: P2 \# C  b+ q
            buf='\0';6 O. [3 x5 H% R) N8 o2 m! j
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
. d4 L0 B$ m4 I* t6 I$ S            {9 Z  Q1 {" \5 N. Z* M: |% q! r
                 opn_in.data=(float)atof(buf);9 x6 S) K' v8 t
                 Push(opnd,opn_in);
$ n6 Z& q, A4 Q/ D) S3 X                 printf("opnd入栈:[%f]\n",opn_in.data);
+ M, M8 j; g* G2 H                 i=0;% T* I4 _4 @' ?  p+ N' Q  c
                 memset(buf,0,sizeof(buf));
. @9 [" ^) |( a9 ^5 s/ ]) j, \" b8 i            }
; z" v# N0 b8 C+ I            opr_in.ch=c;6 f: c; }% p. A* l" n% F, u5 I
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/3 q" o$ C& o( @. W7 N! k9 W/ y7 Z
            {5 K4 |$ c3 W6 Z. {
                case '<': /*优先级小于栈顶结点,则运算符入栈*/0 m# G: s2 L6 e" Q9 u' v7 p
                     Push(optr,opr_in);
! Y. v4 I3 d. A+ s                     printf("optr入栈:[%c]\n",opr_in.ch);
% Q, \/ X' {( J% d% |& k                     c=getchar();
! P6 l, ~! j; y) |) }                     break;3 ?4 R0 e3 V! T% \; F& x9 u
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
- o1 ~& R- {  L9 H9 f                     Pop(optr,e);
) M# Q7 ^" c* P5 R, F                     printf("optr出栈:去掉括号\n");- g5 ^5 Y% a7 E/ ^5 ]' x( u
                     c=getchar();/ m' k; X& b1 b" u
                     break;
& t3 w2 x) J2 r* r4 s4 d! ]                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/8 o7 |$ ^6 n' R" a
                     Pop(optr,opr_t);& P! X; H! E0 B7 T! V
                     printf("optr出栈:[%c]\n",opr_t.ch);& V4 ~, |0 b) }7 z0 k4 A* H
                     if(Pop(opnd,b)<0)
: L( ]- p( m8 N6 f                     {/ c6 m$ j1 D$ Y0 u, g- b8 _0 s) ]5 J% A
                         printf("Bad Input!\n");5 X8 P; b% p- x# T/ {. @' g8 s6 S
                         fflush(stdin);
3 `9 K3 \+ h6 j; r  e6 O                         return -1;
' \8 R, p  ^7 W                     }+ Q, s6 P$ c( C2 n3 Q% X
                     printf("opnd出栈:[%f]\n",b.data);/ ~+ l4 v- J6 _
                     if(Pop(opnd,a)<0)
8 I; b1 Z$ G3 G& v0 b& H                     {* j) o0 ~" z: h% t& m* o; z0 A; o
                         printf("Bad Input!\n");- }- F; V- i. `
                         fflush(stdin);
% V6 m. K8 j5 T' k- l                         return -1;) [( S, X- ~4 N/ [' e
                     }4 s2 g4 l$ a* g4 z1 C! D) S* `
                     printf("opnd出栈:[%f]\n",a.data);5 p  t( f- k; Q- P- b/ e1 ~2 b
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
$ `% n' x1 I0 r* O) N                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
- w% Q0 H7 j9 ~2 E                     printf("结果入栈:[%f]\n",opn_tmp.data);
$ r4 Q  \- E7 ]0 I/ s6 X: n                     break;
4 W2 s( W% y# c- Q  o' r            }
) A. H1 ~" Y6 p: q1 @+ O        }  {" ~. C/ G: z
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
' A/ K% c: e; X    }
) u- R9 X; j: T, W& a) H4 A# K    GetTop(opnd,opn_tmp);- p0 h# Z, T) [; N9 x- g
    DestroyStack(optr);# d2 G8 ^5 T, ^- @! g& t
    DestroyStack(opnd);
! K$ k) l" d: h    return opn_tmp.data;$ E- J3 A6 k6 G- n7 S, n& q1 w' v
}
4 ^2 ]5 {; h5 R% S: ]. E5 ^! j( l0 L- v  i2 t2 Q' A7 {& X2 r
char *killzero(char *res,float result)$ k' m( O1 f- X, U% B& H6 ]2 L
{1 f- M3 _3 w+ Q6 D3 h2 H* a) U
    int i;
4 F, ?& C" ~7 M
) Z; V6 E7 ]! D+ T$ `; O- K' B    sprintf(res,"%f",result);
2 e0 Q- [% I6 s% U    i=(int)strlen(res)-1;
" j% _8 s( @% {% T    while(i&&res=='0'). k( B" K) }) E- h. ?& g
    {
5 s- K+ y  s# E! O) B. ]( u        res='\0';
+ \) ~4 \0 I7 y% x. O        i--;
# n$ o- Y: D8 U, |    }
9 `4 \# S# Q4 j0 P    if(res=='.')
7 n8 G3 E- d, {# u        res='\0';. i, T; G/ B2 N8 O* _$ Y, y
    return res;
; e3 V6 n7 E, a7 x6 y9 d8 ^) t}# B6 w) K: m0 v( v' V: p
2 T* B9 W2 M0 \6 _1 R  B! T/ |6 J
int main()
2 |; R. p$ ]" d8 g9 B3 @{7 p  i7 Z3 Z: R
    char ch;
% V7 d! r2 L; G. _- t- I- j    char res[64];
) h$ J2 A5 D! c& \3 S    float result;
2 a/ f. `( y7 X+ M    while(1)
6 H% a6 N4 P& X2 N7 F    {# ^# [( H+ }1 P1 ^- O( I- R. P
        result=compute();
$ O# P6 `0 O6 e! R0 b4 L( _        printf("\nThe result is:%s\n",killzero(res,result));' p& Z4 Y( c6 R! z5 T& `' ^4 l7 s
        printf("Do you want to continue(y/n)?:") ;
$ l! S& ]5 j. h% }+ ~        ch=getch();4 r' D7 v' p+ E) L; q% f
        putchar(ch);
6 n$ B$ s% p3 t) X/ c2 ?# v* Z        if(ch=='n'||ch=='N')
4 W) p0 s( T( U( r3 K            break;# D& x) N0 B. ?
        else
. s. E9 K/ o4 {9 f            system("cls");
9 }+ J. m" p4 R    }6 T- t& o* u9 q
    return 0;1 _' m. C/ C) b$ H& h6 w0 r
}

2 A- J- C1 I3 @+ b
; P  X& K* U/ `, W[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]




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