返回列表 发帖

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
2 I+ ?& h5 ?; i/ W5 N1 [3 p程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=, J+ E& U: S9 z+ r! f/ j2 Y3 z+ b  W
/**************表达式计算器************/
8 x% L# ~! n( k! H0 ~. B#include <stdio.h>) _9 _. r' j/ B1 m# H* w' \0 G
#include <stdlib.h>; N. k6 D: O: b+ b0 o8 G
#include <string.h>+ y: c9 ~+ y" I
#include <conio.h>7 B; A* G3 r  H  r5 I# w  i, x/ S
#include <malloc.h># R2 L+ N& a6 ^* ?+ o+ g! ^: h/ I

) a$ F1 a. P% I- L( O#define STACK_SIZE 100
( G2 L" _0 i5 S5 N; a+ w& |) ?#define APPEND_SIZE 10
% }) F" U0 a% B8 f: f8 v4 v+ |' Z8 H
( U! {3 H7 C  ^% i# O( |struct SNode{
+ C! ?$ t: v3 O( Z1 P% [9 V. G    float data; /*存放操作数或者计算结果*/
# O4 x" ]/ ^+ r    char ch; /*存放运算符*/( }" p' }# Y& z" O; N2 F7 I
};; A9 |1 l& u; r( B- a, M- U

; y1 A% c; y4 R8 E4 i7 S% T. [# S  Ystruct Stack{
6 y* d$ ?! l' i/ e, f. }( `    SNode *top;! S$ V/ O) j+ I: p3 k
    SNode *base;# j; O! X3 y7 M
    int size;% p. t( p# b' [$ O0 }; T5 I
};1 g# [; ^7 @# X- b& v) f
0 }3 w  Q4 K0 Q( C0 q# K
/*栈操作函数*/
& K$ i4 Q7 b5 J5 p8 d8 O5 dint InitStack(Stack &S); /*创建栈*/
9 x/ i' a" O# j* I9 A$ U4 H+ {int DestroyStack(Stack &S); /*销毁栈*/
% w2 u$ F, w5 e6 E1 a: \) bint ClearStack(Stack &S); /*清空栈*/8 Y' s- l3 Y+ w( @/ D
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
8 w/ ?5 V0 k5 d; lint Push(Stack &S,SNode e); /*将结点e压入栈*/1 J% N9 ~8 E% X* Q8 z8 f
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
( l0 |8 u# o" k% a' E  Y" O( D  P! p9 L3 t, p3 U
/*表达式计算器相关函数*/
$ t. O# t7 v3 w* L! C2 `+ jchar get_precede(char s,char c); /*判断运算符s和c的优先级*/. D2 I! B" J4 O9 j$ V6 W5 r( j
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
8 w( |9 K0 t' F0 [, g' q8 Tfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
! r' g. B" D7 A& ]float compute(); /*表达式结算器主函数*/
0 D9 F1 J* _3 b- @" X/ ^* Fchar *killzero(float result); /*去掉结果后面的0*/
9 U, }# L( B4 m8 w7 [+ g8 X2 B2 T7 e$ F$ @% E0 g3 }* D
int InitStack(Stack &S)# I& q  p3 Q' i4 B3 U& Y' n
{$ I; d# `) M3 j# a: I5 }
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
) z' e" h+ g' a; T" h    if(S.base==NULL)0 f: ~: d+ c: r, m$ J- T
    {6 j& v5 \: P. }' T9 Z
        printf("动态分配内存失败!");+ N2 H# R* [9 U4 H$ a9 g/ ?4 b& H
        return -1;1 ~% ]" A, `- L; E9 M8 D
    }
) Z6 i, C9 v5 R1 K# s0 E    S.top=S.base;
( G& }3 m0 k9 \+ {    S.size=STACK_SIZE;
, z1 q: j$ C0 X    return 0;, ~7 C$ [  W0 H. g; X9 [
}; _# J5 m9 n6 F
& l+ t, _& U- G; m. E7 w
int DestroyStack(Stack &S)6 w8 m9 e/ y% l! p  V8 z. e
{. J0 j9 b6 i" K! x
    free(S.base);, d6 b4 d; B/ |' y0 O
    return 0;
- T8 Y, G  D% y% }- L; J, n4 A9 d1 i( n" F}
2 d3 v! N# q- N
* z- Z$ ]" D; B9 pint ClearStack(Stack &S)
+ E8 d4 w) h- z- s4 N6 ^' c: u{
" U6 p4 @. j, f* u% _/ h5 z6 Y' y    S.top=S.base;, S) w6 w* }* ]
    return 0;
4 c3 q8 S" ?- ^. b. w) I}0 |8 w& K( i2 S+ A8 c
! K# \  r6 P) j+ R$ G( y
int GetTop(Stack S,SNode &e), b- {: |3 `) q
{0 f1 R9 i, f% T9 p: W# D( U
    if(S.top==S.base)7 T9 p& |, Y% \" ]+ U* z! K! R) r
    {
% |* N6 M+ c; l, l/ w        printf("栈以为空!");) S/ [+ ?' R' v& ~- x
        return -1;
- t9 P, e5 H0 v2 o; @' D" H, t4 l    }
  i7 |9 e4 x5 V, `    e=*(S.top-1);. _8 E+ c$ n  `9 a
    return 0;
" y2 E* O" u- X) k, J" Z% _1 @1 F}5 _* z+ E1 e8 F/ ?9 m
6 D$ x) c$ q% z$ h8 S! C/ e
int Push(Stack &S,SNode e)
( u) L$ s. ~% d, n4 C{
4 r5 b# s6 D9 ]- j* `4 v' B) P  A    if(S.top-S.base>=S.size)
8 O* S: j9 z. y1 J    {, P4 F  o9 ~1 X6 z
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
, N6 u$ D, Z+ t$ Y        if(S.base==NULL)6 P% h9 K( |. D" V
        {- d2 v9 X1 l* h9 `/ x. W: v
            printf("动态分配内存失败!");, t+ I5 z8 |2 B% d
            return -1;& l( w# F: o# U$ f2 W
        }1 g# p1 v; T/ o% |* u# V, ~* b
        S.top=S.base+S.size;, r) \0 j) D  r- J5 v6 p
        S.size+=APPEND_SIZE;4 a3 r/ i7 L; [' h
    }
8 N$ h" v( n" H3 ?: _    *S.top=e;
# C! T9 `9 P) M2 n    S.top++;
0 e! f! ~1 ~- V; A+ R1 q    return 0;
1 M; B( B$ g) c4 ]6 A2 {}
  n& P( s: R; ^% M/ n3 i4 z. S9 r. X) e2 f
int Pop(Stack &S,SNode &e)5 ^6 B8 t; Y" Z4 A3 e8 `
{
+ F- y" T+ _) V# G/ I    if(S.top==S.base), u# Q: T) f: e$ e) U7 t) ~1 H
    {
8 `* k1 L* m) a: z" N1 v4 d* ]' D        printf("栈为空!");" x  h& o4 v& \8 ?! z, V
        return -1;
3 a% l1 I% o8 j% F* q    }" x8 d* k2 @, g) n2 b
    e=*(S.top-1);( P- t. [+ x8 S5 k- I
    S.top--;
7 M; e4 O0 P$ x% ~    return 0;
5 W+ A% Z6 P. j( I  F  y7 h# t* m}
6 O. h6 z! `: H/ ~/ E8 E2 d% T2 ~7 r' M# @! i3 C* R) b' s/ k
char get_precede(char s,char c)" m3 v# A/ s  E! n
{9 I3 Z  ~/ J/ C; c$ D: _$ W
    switch(s)& R. s8 ?2 Z- q( b* k& k+ B
    {
% _) B0 q& \5 F" ~8 l        case '+':                 " o9 e% _0 V7 D
        case '-':3 e1 M3 P. N$ S
             if(c=='+'||c=='-'), \, N' G: s5 a" y
                 return '>';* l  H, |1 ~, r3 b% o# Y% f
             else if(c=='*'||c=='/')
6 p0 b2 W7 r- o. {: _" y- J: I6 ^                 return '<';
8 ?" H9 [& z5 Q- p; A6 I& t             else if(c=='(')
1 n4 |3 z: f! f8 S* c                 return '<';3 X9 h* q+ k. R
             else if(c==')')
; S3 `% L8 V: x* L. t1 ^$ T                 return '>';$ A+ ?4 J! V% a; u8 }) z* L5 s* q
             else
8 f1 U: }/ r4 t$ J" o                 return '>';( n5 j" N# H: P! D8 C
        case '*':1 s2 T% B9 G( I4 M0 P$ k! t
        case '/':
" w9 p  \5 B4 g$ X             if(c=='+'||c=='-')2 a9 N2 C+ j& N. U4 J
                 return '>';
& j7 F9 J* u+ N) `+ V& S4 l             else if(c=='*'||c=='/')1 W" S6 h6 u# m4 ~& W
                 return '>';
! \0 c% ]' A; C- l+ B8 t0 z" a+ t6 t             else if(c=='(')
( j; w% _! M! D- s, O                 return '<';
0 J5 i. G3 A( y! I/ `# h             else if(c==')')
/ M2 u; o& M" e! E% n$ B* o                 return '>';1 e0 P7 H: j8 V) i# A; d* _% J4 E
             else" N; }; _. B  N
                 return '>';
% K& q' s- R( k- j        case '(':
# h' L7 j% L- k             if(c=='+'||c=='-')
6 _8 [; r# a1 f! A& C$ L# b5 w                 return '<';
" y! B; E  _7 d% h: p             else if(c=='*'||c=='/')
! |0 g& R0 V+ f0 A                 return '<';, ?7 Z$ B$ p5 F
             else if(c=='(')& ]& \5 ^3 y$ W1 P& T  {) b
                 return '<';
/ U$ O/ V# i# ]- x; l( T, S             else if(c==')')
6 q# Z& q$ n) W" i/ s( {8 D/ |- z                 return '=';
9 E$ B" ~; _8 Q/ ?& J             else
8 G" X. y. X- p6 }/ m& C                 return 'E';
; v7 K/ v% o9 c3 r# T' D        case ')':
3 d0 p/ w1 w2 {! U2 S5 k             if(c=='+'||c=='-')
$ N% ?6 V  @6 I+ w) G7 @4 g                 return '>';$ Y/ ]( [  i: u9 Y
             else if(c=='*'||c=='/')
' t% r( O2 f) K$ \6 Z8 _# g                 return '>';
' {  E/ M  C7 v/ i& R' x: G4 K. b. X             else if(c=='('), E& Y; R& z* ]; a* ?
                 return 'E';) O, M( y7 b8 J- n- q7 F0 z
             else if(c==')')0 N1 j- k4 {+ g) w4 _
                 return '>';
+ G: l- g  @! T9 V/ n             else) ]# q/ S8 [+ k5 ]/ v$ F
                 return '>';$ p' s1 v& E: o, |  L3 y# s
        case '#':
, X4 ~7 D& }2 l. }- r  g; d  m             if(c=='+'||c=='-')
7 f9 ?# Q2 `& n0 X                 return '<';
7 p4 j# a) K! U  }  x9 E/ r             else if(c=='*'||c=='/')9 f; I4 J% |" Y2 `0 u" B
                 return '<';
) C, v# }% G  N5 K: D- u1 ^: s             else if(c=='('); l& k: @& a5 t+ Y3 y1 }
                 return '<';; F( V, b4 @! O( ~9 h* v
             else if(c==')')& w. F$ }+ P1 [) x, |
                 return 'E';
( U" n, _" q2 G" Y; \1 j             else
0 C# h& j3 V* w& E" b                 return '=';
% K0 ]/ N% Q' d. J0 Z        default:
: u; A4 W9 b. k2 O             break;
2 F5 o7 p0 @. l    }. x* K  D3 u2 o8 G& a
    return 0;   
7 d9 j! u) K* G9 b+ Z/ G, \# H! a}0 ]9 P4 w! f. o1 E) L' T6 j
7 F+ @5 H3 }- k
int isOpr(char c)
' o$ [$ F) a' I{
: I4 R3 Y* t* \5 U    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
' `# z3 @/ v5 L9 U( L        return 0;
7 W+ k5 N/ V! c3 u    else $ {( o, ?2 B4 a4 o
        return 1;" |) B. r2 m4 n: y; q- w
}5 E; ?6 ^- w# @1 [" K( r0 R
% I% A- F; q6 T9 N
float operate(float x, char opr, float y)2 |, l/ c5 j7 [) t" {7 C2 ~
{' A0 M! k; W: M1 B+ A# u' c
    float result;
+ R+ o/ B: J6 k  H( }2 P& f: j    switch (opr)
$ k  {+ _- |; L6 g" d2 l    {
' Q9 i1 e* m, K: N        case '+':
2 p3 d( B: A% i. L! K             result = x + y;
7 F* U$ n' l, S             break;
/ X# h0 ~* }, ]$ d9 k. U! H) A        case '-':
2 J  Y# U4 W. @' X  N  V             result = x - y;& G& u0 l2 \9 S  {3 X) Y  s
             break;; c& S: T6 \7 A: P3 Y( N7 }  k3 L
        case '*':
9 }& Y! ~$ T* z' g2 x5 ^             result = x * y;2 t) v* f9 U& R: G) y% R
             break;
2 ^* A8 c2 I: w  W7 r- y5 i        case '/': " J- }: _" M' A, H4 k4 D' s
             if (y == 0)6 i' c" X: r# K
             {  @) l* Z( @* q, w
                printf("Divided by zero!\n");
) {1 }+ X7 e8 L$ I. q9 n                return 0;" {, h5 B" ]- K2 P+ O
             }9 A  N( E0 {& x) @+ p
             else
3 k( H  r! Q' B5 |9 t             {
; `. ^3 h/ p. F) z                 result = x / y;+ G1 m1 x5 `) |( f$ }& [
                 break;
9 `% U+ d" j: o0 Z8 G             }
7 i; n/ I7 d  t" _9 E       default: / [2 M' A- O. D9 g; p# e
             printf("Bad Input.\n"); ( E$ @! j: z& t
             return 0;
: ]* Q; g- ~, o% h, |    }% I+ K4 g' P  e7 Z# x' S+ d
    return result;8 N' z1 j6 X( L5 A5 d6 F, D
}    8 x9 c0 C- Q- j2 U

3 n9 ~9 c" [$ N4 N  Rfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
  E. y$ O5 Q& C+ H8 D& b* m{; Q: u' u3 d; z3 y
    Stack optr,opnd;+ a6 w% q  _1 a; l( W" V
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
, q* }5 ?1 N: f" n/ W' J3 p4 m    char c;. @$ T1 W1 C: `4 V
    char buf[16];. ]0 R3 p' k. |& t4 q
    int i=0;
1 |# s% _0 d/ ?% @    ; k0 j9 _/ k! O5 y1 S
    InitStack(optr); /*用于寄存运算符*/0 `$ [- d/ a7 d+ r. |3 B
    InitStack(opnd); /*用于寄存操作数和计算结果*/2 o9 R2 s$ A! i! F
    memset(buf,0,sizeof(buf));2 \1 R( m: F9 r+ j' C+ r! Y$ b: k3 I
    2 Q( ]  j/ V8 S9 u
    printf("Enter your expression:");
$ J& Z5 }  W6 [  \        
& N# A& Q8 d/ ]    opr_in.ch='#';
! Z# `. q& M) Y% b* f0 k1 z4 L* n    Push(optr,opr_in); /*'#'入栈*/) _$ ?0 H$ q/ B  J
    GetTop(optr,opr_top);
) ?' ?" G4 d# H0 s2 Q/ m    c=getchar();* k( x! d  z% [* |  q. A8 m
    while(c!='='||opr_top.ch!='#')  K6 g$ w& ^  _6 p. z$ R
    {
$ W" c1 _" O5 i0 ?        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
' g2 w# D0 W7 a; S5 R        {
' s: {& q2 B( K+ ?' }            buf=c;
; Z! D) w2 P& h# \            i++;
& l. I4 C4 m6 n9 _            c=getchar();
) P, R+ ^/ ~9 z. N/ o        }
8 j: ?& m/ @- m8 m4 t        else /*是运算符*/) a1 W2 }* M! t. a
        {2 c6 Q, B/ `1 `
            buf='\0';
8 S8 c5 {7 L8 a4 [7 P            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/4 A  F% [5 A3 Y1 T* S- U- w* @
            {
9 k8 ]$ @, k6 U- E3 x                 opn_in.data=(float)atof(buf);6 r$ ^7 S% V5 Q+ Z2 I
                 Push(opnd,opn_in);2 L1 V' G# T1 b8 ~9 `9 Z3 ^
                 printf("opnd入栈:[%f]\n",opn_in.data);3 {/ c. M) k9 n; m. H; O
                 i=0;: I4 L. f0 L5 o/ y7 t
                 memset(buf,0,sizeof(buf));% a7 O8 g- a( |: U$ m* {$ H
            }
, }: [, \6 E" x4 ^            opr_in.ch=c;
) V! C, f3 V9 Z& |4 V) a            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/; u8 ^# c3 o# _* X; w
            {
$ x" S: h. [- t" b8 Z% Y% W                case '<': /*优先级小于栈顶结点,则运算符入栈*/
) u6 \9 X8 N% T# J                     Push(optr,opr_in);  w- _1 l6 e& x
                     printf("optr入栈:[%c]\n",opr_in.ch);
2 F7 \, X4 N( _' A% N0 d                     c=getchar();: [/ l' {! |' U) U# ^
                     break;
  L5 d" ~0 b! d. D# \% S7 h                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
) A) E! G3 s# s2 U9 e: F5 C7 _! G                     Pop(optr,e);
9 ?& m  {7 c9 ?* X# [% {3 m2 {# k7 k- K                     printf("optr出栈:去掉括号\n");
0 r: j3 O. e; ~                     c=getchar();1 `$ b5 k, }- T+ ^
                     break;
+ b- f# z% F8 ?' t) f                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
4 Z* T  {( K' v" M4 v                     Pop(optr,opr_t);/ F- [. x9 I7 _) J$ ]) v" t
                     printf("optr出栈:[%c]\n",opr_t.ch);5 H/ f4 Q' L% k# A8 a: I
                     if(Pop(opnd,b)<0)
3 z! _, S! v# \+ B2 U. F" a                     {
( o( n  z0 L5 b+ B                         printf("Bad Input!\n");% O5 D. O; B+ ~' L7 _
                         fflush(stdin);
5 u4 u+ g- I# ^2 G# s" B* W! T8 q- C                         return -1;
7 P, q" b& i, W! c5 c' Z                     }1 `. [5 ]2 v! ~
                     printf("opnd出栈:[%f]\n",b.data);" `& M+ F! \0 n9 Y- _- v" P/ p
                     if(Pop(opnd,a)<0)
2 _3 B( R8 n  a# f( M                     {
, _. f+ M! ]0 m7 a" d' a6 E# d3 i                         printf("Bad Input!\n");
4 g1 J; @8 C4 ]9 B. e6 p( a/ y                         fflush(stdin);) ~* y% A" U# A& o' C4 \" ^& p
                         return -1;
- ^' r/ U: O9 P5 c4 H- C# L& F                     }: Y/ A( I# n( m2 l; m
                     printf("opnd出栈:[%f]\n",a.data);: i% |' @( w2 e/ ]- o
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/5 Y& e0 G. I* A" l% x( g  j
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
) b( i4 `7 f# o1 ^                     printf("结果入栈:[%f]\n",opn_tmp.data);
! ]7 G$ p8 v3 V- J: _; X                     break;, v& @( {' c. A- H7 G) G* @9 e! V
            }
) }. @9 l0 x) I* e, {7 K        }
! l. C3 Q; ?* f) }! n        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
4 O- W7 l  J8 X1 s3 g5 M    }( J0 ?$ h( k: G
    GetTop(opnd,opn_tmp);
$ R: T; D) _* {2 O    DestroyStack(optr);& L0 K2 G' ?8 N7 z7 \. A- X
    DestroyStack(opnd);; ^: |8 ?3 w( x
    return opn_tmp.data;
! s9 v+ y" t, V! J) F. h}
/ |4 Z; Q* S8 ]5 X" r% b, b1 ^+ A' v6 |
char *killzero(char *res,float result)
  M! d5 K" I, K{4 U9 A, d; S# ]  w
    int i;* N! u5 Q* I5 ~% |
' j- A, o6 o3 R+ p( j
    sprintf(res,"%f",result);2 u. m( S( f# d% ?6 u' [3 f, [3 e
    i=(int)strlen(res)-1;
$ A, r, Y. i2 ^2 W5 [    while(i&&res=='0')
3 d- P/ F+ k* A' D' ^; @    {
/ o1 Q3 S$ \0 e# p- f+ D        res='\0';6 Z0 ?9 Z6 T) f* A
        i--;
( B% _& W2 P+ }6 H& T  K; n- r    }8 ]: |$ r; a+ A  @) n) C, [
    if(res=='.'), Z! h- j# j; }& C3 \6 B
        res='\0';- D- ~- `4 M* M1 p
    return res;
/ K5 [! X5 {/ B5 _7 a' @4 }6 V}
2 K( p: F5 f) q. n" B: {$ F! y% i9 {# j; {) F  l  D' i
int main()! @" B. {4 e2 F& \& E4 S% p5 L; z
{
/ a  W" P" i4 O$ [' Y    char ch;
" V; a% ?+ v" x8 R    char res[64];
/ B2 G% e1 X' u0 H    float result;% C  A4 M4 k/ ~" n' O" ~7 T; E
    while(1)- a2 ]1 m( K& ~( S+ N) @
    {* n; ~5 P6 E  O9 }; q- p
        result=compute();: k5 z) b0 W. i7 c$ V0 z
        printf("\nThe result is:%s\n",killzero(res,result));+ B( U0 _$ H$ x5 i5 x
        printf("Do you want to continue(y/n)?:") ;
  n- w; e4 e/ w5 N! G# H3 _        ch=getch();
4 F2 _( W# |& D* S3 \        putchar(ch);
0 f  B+ B0 r' x        if(ch=='n'||ch=='N')
4 e- j) Q! e4 W, j7 z* }3 I) M8 L            break;+ F. L2 A5 H% f4 a9 i
        else5 n; C5 J/ z2 B
            system("cls");. O8 |9 ~8 M& R* j& E& D; p  d1 T$ l
    }, w' I- q$ b; }* U$ v; t
    return 0;
3 g' N/ D, ^( y6 Z& }( X}
$ X; ^4 O; v, J4 j+ ^8 g
6 I9 T: t4 u* c8 m; Y( G
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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