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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的., B: ~' }1 T" R8 h! I  F7 G; p  k! F7 x
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
, o6 b/ h% y& w/**************表达式计算器************/- l2 s7 Y& ], m; _$ S
#include <stdio.h>
, x6 [$ M% ^# X% b  o) P#include <stdlib.h>
$ _  f7 J4 x5 j3 y2 S#include <string.h>
& Y/ a1 i7 i' ^/ o$ q; t' ?" u7 w#include <conio.h>( s6 ]5 C8 E) X; T5 _+ F
#include <malloc.h>
' G! g. R  t% K7 h" V# A& g* l! N7 U* S: V
#define STACK_SIZE 100  H! \, X$ O& N% ?6 N
#define APPEND_SIZE 10
  F" h  |4 s  O9 z
0 O' O' P1 w" m8 f" v* |struct SNode{
  ]) @6 R4 ^2 m- {7 e9 J$ l) ~    float data; /*存放操作数或者计算结果*/
2 }% {# \* R7 P7 @& ]    char ch; /*存放运算符*/
- g$ v/ y# ^3 ~# ?};
- C- C' I0 v4 x) ~% }! g3 e) t0 ~% y$ l! m1 `
struct Stack{. ]# h" Z. M+ ?) i
    SNode *top;
! K* m5 v, w: i+ _    SNode *base;! S2 @& _& {% h- S, K4 k3 c$ U
    int size;
+ R7 J1 C7 c$ o- ]' P" H};% D: [- H2 j. C- m. a
  |3 d. ?" R" z" v
/*栈操作函数*/
+ K) T) c' i3 T; p8 _" C2 J7 o* |4 m/ Zint InitStack(Stack &S); /*创建栈*/
: a9 q& r- E! X9 X. C) rint DestroyStack(Stack &S); /*销毁栈*/
2 O, t  Y5 ~4 Z9 }5 xint ClearStack(Stack &S); /*清空栈*/
+ ]& ?5 p4 x6 @, r& jint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
( S. `- B1 F* m" z" ~$ \" eint Push(Stack &S,SNode e); /*将结点e压入栈*/: n- N9 T% U. ~+ c
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/" P, S$ W% r; l
8 x& {/ R8 A" P: E# M6 M
/*表达式计算器相关函数*/
+ s1 y  U: x. uchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
% `3 l* z" B! Q6 X% u7 L/ ^int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/+ L$ k3 _, ~* b1 c
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
. c7 V0 j6 Z+ d# X! R0 e4 xfloat compute(); /*表达式结算器主函数*/' P) I& K% w: X" U- E. [. p% Z; [8 P! H
char *killzero(float result); /*去掉结果后面的0*/
* K/ M$ f# U& J+ n& {, R; O' d+ U. R; T
int InitStack(Stack &S)
: i5 U+ Z4 \$ y8 A  }7 V, l{
! Q$ U, T& U; e* L. J    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));% O1 X5 L1 I, r8 v% s; J
    if(S.base==NULL)
, R7 y0 t6 p5 x$ `* A    {# y5 [# {1 F3 l9 {( J! C
        printf("动态分配内存失败!");
% q7 Z" g( E# @8 g        return -1;- `8 p5 n9 k: ~+ ]0 `. t% J
    }: J" E9 W+ W9 l( o4 I
    S.top=S.base;
% H  z' x7 w. `+ E* {    S.size=STACK_SIZE;4 h5 \5 ]$ a; O% o
    return 0;
% S2 [: [7 S8 _5 @}
$ w) n" t+ o) \6 D8 S9 E
! e( x! J& d5 a& p( \! U: v3 sint DestroyStack(Stack &S)
5 W2 |' `8 ]! u1 ?3 i# }9 s1 B{, Q2 J# V* x% C& q9 `( G
    free(S.base);
, Y) H& T' l; Q- g3 ]7 o    return 0;9 h" N1 F+ |5 w
}
* ^2 [3 S# J; E4 A5 }  t, A+ w' n! a% Z0 F/ b
int ClearStack(Stack &S)
8 Q- U' A/ J* y" v, _+ ~: x3 k{
5 e- D  s' e/ f6 h& D3 w: l    S.top=S.base;" V9 m1 d; W* r7 d, V$ C
    return 0;
9 ^" q7 N* I8 }7 e1 ?6 J( c& `}" M; Q  R1 K7 \9 Z6 r3 x! ?( v
4 W3 d4 `8 i6 U% X
int GetTop(Stack S,SNode &e)
5 ^7 Y. `- g6 Q{2 v) L8 i1 i& J$ A; Y& `# p
    if(S.top==S.base)/ o/ |# `) D% q
    {7 e' s9 ]  _) Q3 q1 B
        printf("栈以为空!");3 |& d% X( ]/ y% `
        return -1;
3 Q+ z2 s1 d" {% t/ f    }
* |/ I5 x. h4 }# h    e=*(S.top-1);
5 U6 [& R$ j5 T9 T' \    return 0;7 W3 }* N" \; e8 B' _0 B) Q
}# I- b/ b$ B4 q$ Y& h& z1 n
9 U) R* m/ i! J) M4 ]3 G9 Z% ^. T
int Push(Stack &S,SNode e)( ^% \  h4 O+ Z' F
{: A. b' x# r- ?! `: x3 x
    if(S.top-S.base>=S.size)+ A- r- \  P9 L7 s
    {% T; i$ t* ?, n* q
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
9 R4 `& V0 Y2 h; X' I        if(S.base==NULL)
# v7 ?7 q: k8 Y. x        {
4 E! T  R7 N5 N4 Q8 i; n! C5 h            printf("动态分配内存失败!");
! ]- w0 j" {% C) H/ C            return -1;
' D  d" G6 t. f8 z# Q        }
  y! H  h# v4 ?5 `        S.top=S.base+S.size;
! X$ E2 t/ T9 U/ j        S.size+=APPEND_SIZE;2 Y( a: o, S9 ]) ]. _; J* O
    }
; F7 d! u9 O/ E$ r1 O2 U' J    *S.top=e;
  C* t! N' w1 n' l2 v% R! O% e# s    S.top++;
& y# W* N& C/ _8 G1 e    return 0;
$ k1 Q6 K1 v; ~9 q& N8 I}+ c/ R1 r( I( d2 b
; P8 i4 g* U1 F% o
int Pop(Stack &S,SNode &e)
( l$ M9 t: P" T6 ?" ^* \6 z! _5 o{2 R0 @' @, _( Y& {* u6 m9 L6 ?
    if(S.top==S.base)  s- B9 m: n  O9 `
    {$ b6 i$ z8 V- c5 m
        printf("栈为空!");
, z/ \$ a! \+ U4 m! s+ d        return -1;1 a7 ~/ L* `6 C/ s0 c9 d/ y
    }
( K- i0 Z  z' c: R8 W4 w, B) y    e=*(S.top-1);
/ ^& U4 `+ A4 u, e3 m. c    S.top--;* T, t0 W2 f+ e2 d* s  }+ r* L
    return 0;
# L! G. H. S" u* N; R}
2 C  P* j7 e: [( z9 l' t
$ ]# [5 U) X8 F+ pchar get_precede(char s,char c)5 |# t8 I; t7 H' ?% H* j. i5 q
{
/ C, ?) C4 V( h  x5 d4 m5 C    switch(s)5 i1 u9 b! u+ N, O# k
    {( @1 i3 N/ c% p, ~$ g, z0 G3 ]
        case '+':                 
, x4 d& J& I5 a4 T, Q        case '-':
- t6 w& f. A0 Y' M             if(c=='+'||c=='-')
# b5 B+ b# X% L/ P1 s8 q: X: y                 return '>';# r$ J4 b5 O& v9 P
             else if(c=='*'||c=='/')
! p: g9 N- ^7 h5 W2 ~                 return '<';
* _/ H! a$ F' \( J  d+ v  x             else if(c=='(')
" W6 {1 R- U  |1 b  {. P                 return '<';
, ]" k8 u( C$ N7 L+ P             else if(c==')')9 m5 m3 G, L7 Z. O5 L0 m2 ?
                 return '>';
0 ~/ C' L/ B$ r9 j3 q! K  R6 `* r             else
4 z4 h3 b$ A6 N                 return '>';
. d' x% p9 ^; h+ Q* x        case '*':: E. J' q" _* p' o& S
        case '/':/ I. q8 D, W& H4 P1 P  E* R- |+ f
             if(c=='+'||c=='-')' k7 B  ?0 p; j4 B, g' F  U# n
                 return '>';
& E3 h# i* a2 r* ^; W8 \, n             else if(c=='*'||c=='/')
8 C3 F0 p8 c8 H9 [' E7 b+ b                 return '>';$ W& T2 D2 [6 ]4 ]6 c. L+ d# n
             else if(c=='(')' Q: h& M  k! N( P. [# D2 \
                 return '<';
1 |' M) J! g& q: Q( v3 L             else if(c==')')/ o  ?  X7 j) Z0 C, F
                 return '>';
2 Q- U, D$ K7 B! ]# f" f& Z             else2 u! w; e7 s, `* I, U$ N
                 return '>';5 N, S! s4 N% i6 t$ C' t
        case '(':
5 r) N3 ?1 {+ {4 O3 C7 z2 M             if(c=='+'||c=='-')$ P6 S7 l$ |6 z; f. w' z
                 return '<';/ J) v( f& ?& U# g: L# n
             else if(c=='*'||c=='/')
1 |4 ?8 `2 ?% a                 return '<';
4 k) m+ _8 f7 y8 e             else if(c=='(')
& M- d9 t! }7 q$ A, K                 return '<';* ?, W6 Z9 {3 C9 v0 f. f0 W1 d
             else if(c==')')
* {) k6 A. u& j9 S3 t                 return '=';
& N0 q2 R& h0 f' s8 [             else
/ p3 k* x( F: V2 m7 u* @                 return 'E';! |/ @$ K4 D( M- o# d$ u0 c% o
        case ')':
5 K  M- I; b+ b4 R' a& N             if(c=='+'||c=='-'). @' a  ]6 _* Z9 D
                 return '>';
0 Q2 a1 ^% }, ?             else if(c=='*'||c=='/')5 ?6 y# E2 Z/ ^: N$ ~6 y# j7 {( A
                 return '>';
* q8 C7 R- g/ ?( J" e: n             else if(c=='(')% z& E  E6 s! ~5 Z( T
                 return 'E';
: I& o$ E+ Y7 S8 p# h8 S: F             else if(c==')')3 v) ]& z: g% l
                 return '>';) d, O/ V& Y( n1 L. W- I0 m1 W
             else
$ J, V$ Q9 x1 c* ~) N% ^, @7 n                 return '>';/ N, i- C& ]1 C
        case '#':
2 @& a2 j$ w# @6 y# o             if(c=='+'||c=='-')
+ I4 t) z+ P7 `' t                 return '<';6 Q& P. I# C8 C& J% i: M# N* D
             else if(c=='*'||c=='/')# w% `7 p' T0 S
                 return '<';* _% r8 M' J5 k- L7 r6 W
             else if(c=='(')  U2 c9 Q& S- i
                 return '<';
) r0 I, \2 r. k, B# q             else if(c==')')) Y( f" E7 w+ e
                 return 'E';7 h. S) {: H2 N0 F- _& j5 E6 n
             else. i. Y/ z/ W4 h3 a+ L4 P
                 return '=';
) u% F5 Z! H+ j* O        default:
4 g4 a+ C2 A/ G$ \7 c             break;) R/ k) W( P$ U2 l# V9 }
    }
1 z5 N! m4 E  J! v5 j5 d' L3 L5 y    return 0;   
/ Q8 o6 C) H. y  q; U3 {! C) m}
! I1 p& j# D* c; e- {! F3 n+ J: A3 ]* i- S  m9 n5 G' p
int isOpr(char c); x' n  K) R0 H
{5 _% E0 r2 S6 R1 l
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
1 N: }" y* ]; d7 {* _# W8 x& N        return 0;
' ]# \* s6 f7 L9 P* D    else
9 ]5 j' z- T8 G1 \. F        return 1;
3 l) x  M. |& K}
% ~7 R8 t% ~" |" H
. @+ ]( H  P7 o0 V9 ofloat operate(float x, char opr, float y)
5 J/ Z% J' G) g& t0 `1 _{1 t# O) i+ i. B+ u7 k# T4 e
    float result;
# l" H7 u/ D1 i/ H4 u& z9 J$ G2 h    switch (opr)6 H% m; k" I. L
    {
$ I2 B5 M4 B: ~% M. y( y        case '+': 7 x( Z- w; H7 W' |& O+ W
             result = x + y;$ _1 I+ H, A3 v) X5 ?( ?0 g
             break;* ]% s9 @! h$ Y1 m3 \1 W" }3 m/ P
        case '-':
0 T6 Y/ f$ T' H( d2 U8 \             result = x - y;
: S" L& G, u. n) g9 }             break;) @4 S5 M. ?) Y% w$ H4 U
        case '*': ( H/ @) F+ L* z* \7 L
             result = x * y;$ C! c; p4 A+ P8 V. I
             break;, j* ^/ V0 f/ G  G- B5 O
        case '/':
4 F+ X4 [4 [3 T" @1 S             if (y == 0)
! v! W& h+ ^/ C             {/ s3 Q/ h( n* m7 t
                printf("Divided by zero!\n");
1 Q. j, T+ T0 |1 a5 Y, b                return 0;% y7 a# t7 w/ g6 {% U  w% }
             }
! ]7 |5 r( i8 u$ p  u5 K) z             else
, o$ s1 ?. Z8 W6 o2 n. x. X4 ~9 V             {
7 G. D+ i' F- [% s                 result = x / y;6 @5 r! B& T' `8 l1 ^# t1 b
                 break;0 y4 l" V, c. d/ u. s7 n
             }( ^) }" A& I8 e$ _3 p& y
       default: $ E* Q; \% i( {$ y* X
             printf("Bad Input.\n");
) B' _$ _% q1 u: X" s             return 0;
7 \. M7 b% `+ e2 x    }
4 M* m& {. _: \8 l    return result;
. b& V! L9 M- n3 s. P6 \; U4 y}    ! P4 B6 \7 r& v/ l) {, J
1 L8 {: {& K9 G9 ^8 p: P* c5 e
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/4 p; W% z/ ]8 `! b
{
* T8 @2 E7 A6 b5 D& Q/ Q+ Y    Stack optr,opnd;) t  i7 f5 K0 N( d0 `+ _9 s  K/ {" g
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
7 ]1 z+ u8 I4 R    char c;
" F! Y4 |' \/ d4 ]    char buf[16];
# H4 Q' V( F/ J, `& f2 T    int i=0;
: s! R. N9 {6 g4 W9 T" l   
* k2 W: ~. D% ]# N5 E! u5 _2 S    InitStack(optr); /*用于寄存运算符*/7 h& h7 l+ e0 V  k2 x; [
    InitStack(opnd); /*用于寄存操作数和计算结果*/
" b, z2 S- X6 R7 `    memset(buf,0,sizeof(buf));
! S8 _& I) R5 P0 M! Y# v$ ]   
- h" Y. a6 D/ k4 g8 u2 f. Q    printf("Enter your expression:");' R. v* @: O6 v, n/ n* q+ H  r
        
& S# j! ?$ i  J2 B9 ^    opr_in.ch='#';
  ~7 j+ k" X# U8 ]/ E. L( d4 ^    Push(optr,opr_in); /*'#'入栈*/
" d) c  m7 m  O- _    GetTop(optr,opr_top);
6 z, k/ n( G3 V; W. C# Z    c=getchar();
/ {% Y+ W8 J5 ~# x4 w    while(c!='='||opr_top.ch!='#')% N1 q/ r& g" o' o- a- j
    {- O& D3 @: g! Y$ E, ]; \% T
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
) D$ V( ]3 `, h4 a        {
! I7 g  v! B5 O" P            buf=c;
! D+ h/ o4 J, y            i++;7 P) X: y1 `$ v  ]9 o' {
            c=getchar();7 M# Y& S: ?2 Y
        }
# X; q9 h4 ^% i$ S3 a( W        else /*是运算符*/* O% \4 |, s: U$ i* W. q
        {
, w* ~3 Q0 N+ d- Q3 Z            buf='\0';
. }2 G5 N) J$ Y6 F  Q, C- Q            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
# k, i+ S2 o* p, x            {5 e6 h2 }3 e  f  C+ X0 P8 D
                 opn_in.data=(float)atof(buf);3 W6 W  O6 k: u, j1 x% z8 R% N6 F
                 Push(opnd,opn_in);7 ~& {3 j: x  C% T, l& `$ `# J
                 printf("opnd入栈:[%f]\n",opn_in.data);
) L& ]' {4 Z# E4 H3 z/ d# U                 i=0;  g/ N2 ], U7 z! `! P( y$ H* {
                 memset(buf,0,sizeof(buf));& J5 Z1 V7 {1 p/ K$ @7 \
            }
5 D7 D. w( b: n$ C+ U, t            opr_in.ch=c;* c1 i1 u0 |$ h/ H8 a% x2 }& _' w
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/1 i% I5 p- ^# v& m  b1 y5 v/ G; x
            {! o3 \! n4 m/ _) q( f, w- D; z( [3 }' p6 W
                case '<': /*优先级小于栈顶结点,则运算符入栈*/1 t* D6 s: S2 S1 P- h
                     Push(optr,opr_in);. M1 n. ~6 a5 b
                     printf("optr入栈:[%c]\n",opr_in.ch);
+ O* ?8 E8 C9 {, [" _                     c=getchar();7 C0 S, D) Z- n3 x2 w
                     break;0 l7 q) e) t- E) p5 U6 j
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
1 D' O) `0 I1 @$ T3 y9 U                     Pop(optr,e);
# U/ S) _8 `  t. a                     printf("optr出栈:去掉括号\n");2 ~( R. J7 T" S- v! n7 k# P
                     c=getchar();
! t2 L- e6 |. ~& {  x                     break;
/ \7 N7 P2 h+ u( c0 N                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*// S0 r. h+ f, ~  r+ p( l
                     Pop(optr,opr_t);
/ l& H) R/ q$ E  k1 B; @                     printf("optr出栈:[%c]\n",opr_t.ch);: P& @) W+ I# N( x9 G6 a- e' F$ l
                     if(Pop(opnd,b)<0)
$ F; Y6 F7 B) J+ L+ n                     {& Z6 u" E; w1 {6 c5 M' b( m
                         printf("Bad Input!\n");
0 Y/ ], \; {& k# r! [0 D# |                         fflush(stdin);
4 O( N7 t3 n  ]) E5 D/ c5 J! t                         return -1;( G8 [4 f- p- \( f4 v! @
                     }+ E, `0 z& v' Y3 M# a
                     printf("opnd出栈:[%f]\n",b.data);4 S/ A! ?9 J0 M, y# X2 W4 r
                     if(Pop(opnd,a)<0)% M: I* b& j* i; g4 H$ O. j) I
                     {& V% R) _, C' ?- W  ]4 v1 S7 P- u
                         printf("Bad Input!\n");
3 X0 K) I+ I6 `; c$ ~- p                         fflush(stdin);( B3 j: d& A! V
                         return -1;) [& a5 ^& ^* H# v* D
                     }9 s  Y3 ~* z* f( z' N  |" v  x
                     printf("opnd出栈:[%f]\n",a.data);
" j+ C; A: P# b2 S( f  ~- I/ m                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/8 K- j# X# \! E
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/. t5 d; x9 L3 u$ Y& g5 s
                     printf("结果入栈:[%f]\n",opn_tmp.data);- e7 ^) m" |+ o) m0 U
                     break;
3 _5 |0 n; @2 @& a+ O+ z$ C            }
% M2 ]8 s1 S* x* F& O7 n% @        }
% d  h5 M# I' @' u" C        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
- ~/ X# U+ R+ x& F  s/ o7 }; @    }. Y( F& t. G- P  ~
    GetTop(opnd,opn_tmp);: K3 S. y  K) A2 _4 M; V
    DestroyStack(optr);
' X4 P1 p4 K8 e) _    DestroyStack(opnd);( |1 B$ e3 f& R( Y! i1 U
    return opn_tmp.data;: z4 V8 w- h8 R( ^
}
4 [4 `1 z  i6 j: {2 T* C1 J0 v" m0 j3 T
char *killzero(char *res,float result)$ x2 i4 i/ {# Q# a: [9 j
{
* K& X- n4 O# V. P+ ?    int i;
+ r$ S# b* U4 ~6 T- ?% j
7 T9 H. j9 \7 |: y    sprintf(res,"%f",result);
7 E! C  P5 s3 Z' |" I    i=(int)strlen(res)-1;: V) q( L5 [4 \2 ]* G
    while(i&&res=='0')
. \+ }$ I1 X* A    {' q: D, X9 I) `2 h7 h" w9 \
        res='\0';
& N' m' Y  Z2 q        i--;1 y' i$ z- d& d
    }
# T: c) V8 r/ g6 K7 J    if(res=='.')! W2 _  N# G2 J" C4 D1 a7 h
        res='\0';
' j* Z) p  k. u& l8 i; j    return res;9 \/ v7 r' D( [! ~" u
}
6 A, H2 e- m) O" g# t" U& F6 E% n6 s5 [, \
int main()
+ `$ c; F- k* w0 [  y7 o& K- c( [{' O* h6 h/ R6 M) L9 E# M
    char ch;
( x1 @, w! K9 f8 O6 x5 X; \% G3 B    char res[64];
* R' a8 X# G+ e# @    float result;+ s6 C! E2 p% `5 C
    while(1)7 f8 v2 T- H: Q0 N
    {$ p5 M" Q4 U3 _9 _# L0 _& j
        result=compute();4 C+ O, S( W/ W
        printf("\nThe result is:%s\n",killzero(res,result));
; C1 `1 y2 U- a+ ]$ D/ i        printf("Do you want to continue(y/n)?:") ;  y9 H$ G5 z1 `9 G- X
        ch=getch();
2 k9 k3 x' Y3 w7 A        putchar(ch);/ d8 v9 f2 @, }* f. J" B9 r% W" X
        if(ch=='n'||ch=='N'); J. Y/ r* C! P" @4 X
            break;' ~! h1 c/ L; N6 y
        else
4 p1 I, W7 ~  G9 l$ l6 m            system("cls");" N6 g7 F9 Q( b
    }/ `/ j8 _" |( Y% u. {8 l
    return 0;& }# N' p- r9 X% q# ]! ~8 j, r
}

0 J! l- s, Z' V% R* {* g/ W% m3 t4 l- h. B: q) H& B0 a. J
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ]

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