  
- UID
- 133
- 帖子
- 51
- 精华
- 1
- 积分
- 186
- 金币
- 55
- 威望
- 2
- 贡献
- 0

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.& A2 P9 m; l3 g+ `$ Z% T
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=9 d. h# B8 W X
/**************表达式计算器************/( ?1 F$ A5 m8 P, O. s, D7 d. k
#include <stdio.h>
; _4 e3 k5 S3 F. [" n w# j5 f#include <stdlib.h>
& L3 q6 [9 A) v- h#include <string.h>
$ N) S# C0 V$ ^5 t% p3 \& c$ P#include <conio.h>
9 h" \' F& Q2 g9 f#include <malloc.h>& o) q; e5 e6 X" B" ?; w& J7 i
4 }5 e, Z, E, ^, [+ O1 ~, A$ O#define STACK_SIZE 100% o( T, m+ W) b- _9 O5 A- l5 {. ?
#define APPEND_SIZE 109 a, N8 \ @ Y- D( C! Q& ? F9 E' P
- O$ b- C/ o" p$ o
struct SNode{* H/ a z. ]+ }8 m" _; z
float data; /*存放操作数或者计算结果*/
/ C; @5 V# n% v2 w1 m4 Y+ F! c char ch; /*存放运算符*/3 w7 l: x# R. T6 [6 l5 R6 @0 X
};; h* m/ W9 W1 l/ R
$ k4 l8 J2 ?/ O% V( h& u
struct Stack{7 Q8 _! x% G4 M4 h7 Z9 J$ Z" C. V
SNode *top;+ W w" w2 W9 Y) H& S3 ]" K
SNode *base;
4 T9 T4 k% e" ]6 R int size;( Q- x2 z. r% j2 h) B3 Y
};
' T& A: a8 ~, ^, v" y* N# o! `; K' b+ p5 Y
/*栈操作函数*/" }2 R3 |4 I) M \
int InitStack(Stack &S); /*创建栈*/
* r4 v8 n) Z# n8 Nint DestroyStack(Stack &S); /*销毁栈*/3 g" p. X8 E3 d9 Q5 R/ }
int ClearStack(Stack &S); /*清空栈*/
! `! ]( W$ |" n, tint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/! e/ s" L3 _7 o; N M! v
int Push(Stack &S,SNode e); /*将结点e压入栈*/( C0 [# i$ L+ d) p6 g& e
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/% i% J7 @5 \ h2 J) ?
7 M+ C6 e' \3 ~/*表达式计算器相关函数*/. S: O( o( V0 L6 M0 g
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
3 c& J/ S: \6 v+ r; ]9 V* \0 V5 oint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/2 m2 e7 Y! p+ _. {# f* I
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/$ J' Y; L2 e) r& X; K( w: i7 C; {, Q
float compute(); /*表达式结算器主函数*/
! Z1 S Q& y5 K/ Q3 a/ E8 tchar *killzero(float result); /*去掉结果后面的0*/
' f* t9 S: u2 ~5 p w
% U" }2 e- {+ c) @- Iint InitStack(Stack &S)
. f/ n L" u, S) a. M+ P( }{/ e+ V6 C5 l, _3 W% X# ~
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));6 w8 t, r2 E0 T2 N: o2 c
if(S.base==NULL)4 V; I2 B7 e. ]( B2 L
{
1 D# T: Q: H5 X4 q printf("动态分配内存失败!");
6 t+ Q( g2 h& M* r- D* N return -1;- E p( ?8 ?4 W+ ^- p
}1 t% {# j* i3 N
S.top=S.base;
5 C& z: f; {: f S.size=STACK_SIZE;
) V$ T# D* Z5 P' g m. _9 a return 0;9 F+ K7 |$ |, z/ q
}
5 I3 O) Y3 B) [8 c, K! p7 B7 N& t2 @( D6 g" F% R; S# b" f+ F
int DestroyStack(Stack &S)' `4 w# Y# o( j$ j( q- S5 r
{
1 U! L5 x* O: Z6 s2 _( f* @ free(S.base);
5 e/ U: w8 g; U# c7 W6 D( { return 0; b; j5 t2 `1 e! o4 {$ u
}
& c8 t$ J. F2 i& f' x" B. w* O% y& W7 w. g9 G$ n: r& u: f
int ClearStack(Stack &S)
% r! K5 N+ e8 B+ [1 @{
/ Q% s5 [ T S: v P7 n! t* s S.top=S.base;
+ `) {6 v6 Q6 k _9 v. G return 0;
4 s, x1 E. _2 {! R9 k1 d0 H}; ]) H8 z, X2 J- M, X' z' K- n
* ~7 k: o. a4 B8 [- ~8 m' M) H- {int GetTop(Stack S,SNode &e)" g% H4 q1 G5 X- @1 R0 i
{
; S3 N$ ]4 i8 k1 ^ if(S.top==S.base)! p" O p2 J4 |: Z+ f, j( Q
{
# d: y' c$ \6 N9 q, }( M1 g printf("栈以为空!");3 l! u8 q$ ~! g5 x7 t& m
return -1;0 A6 w( f7 A! K5 s
}
9 E8 X4 a1 ~2 ?" r1 z2 b e=*(S.top-1);
4 D* \3 A8 V/ P" B. B0 U return 0;: t5 B# E/ T" N) _
}- G$ J# G& ?. C1 s- o
- f0 y) S+ p9 ~0 b& ^int Push(Stack &S,SNode e)& }% a" Z0 l2 ]& q* b1 | p
{
: F! u& v/ Y, K [- f5 g5 w" J y if(S.top-S.base>=S.size)
9 y+ K7 k5 M7 w7 q/ H {
' T3 j* I" A6 z& _$ k S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));2 Z9 p4 k3 ~4 |1 l. p1 x
if(S.base==NULL)
: v1 B5 O" P2 G9 a: e s {5 c1 T# L; y2 \& c% ^* q. E
printf("动态分配内存失败!");
6 C# E3 x- c4 { return -1;+ g6 o# t5 y. m, P$ m' n
}
2 L/ U0 m0 E+ a7 ? S.top=S.base+S.size;
9 t4 ]* f- _+ F& \8 R9 L S.size+=APPEND_SIZE;" X/ n5 e7 b# b, r3 V, P
}
0 T, Z, O* h; n3 N( _ *S.top=e;
5 _5 O% N* S4 J9 _. }, c% N S.top++;
% B" `1 O( h' f" n/ e; [ return 0;
& G( y. |3 K) C; S7 L! n}
/ B& V- i9 h: }- k
! ^( p E. g# ]( s6 u+ ^, {- `int Pop(Stack &S,SNode &e)
# t1 C+ N6 s8 Z5 F7 m{% ~7 ~4 P0 S, X. H G
if(S.top==S.base)# V; a7 \* j5 v+ t; H; G2 } d4 @: r
{; k" P2 Y8 g5 f z, S
printf("栈为空!");: V% e& p9 U, ^0 S2 n
return -1;5 q+ g0 e% a3 l( d( t Y8 ^3 {
}
7 i% [9 Q% J4 s# O' d" o e=*(S.top-1);
( H/ F5 i' K$ r- X S.top--;
$ O' j8 o6 p! z; _: P0 Y- w' z& @; c* P return 0;0 n8 s( ~- U& P4 G3 }% b
}6 o" `+ {2 _, r) u
# {1 K+ o6 A4 m9 L' t: z+ Q/ {
char get_precede(char s,char c)6 M* c" S4 S( `! u: `9 T( \
{
/ H0 C# S K3 o$ [; q& [5 x. e switch(s)
) X0 O! e: O* W, ] {
* d1 O+ g+ v- i1 N* H case '+': # Y p: }9 Q9 ]8 ~! u$ w; X3 ]
case '-':7 Q( w; U2 S" L
if(c=='+'||c=='-')) N2 c* E! V% e; | ?7 w) u
return '>';' ^4 n3 E0 j: }6 T$ [ t
else if(c=='*'||c=='/')
# l9 n( J# N( W& H return '<';
7 G9 W$ z) U& g2 Y6 m# _# T. l else if(c=='(')& |- y- Q" h' L; o7 B. l) g8 l
return '<';
0 p- U6 j5 k& i& \7 I8 g else if(c==')')
3 ~4 c r8 a$ ~. O+ @4 ?' J return '>';
f" N0 s3 c1 @: y: u else
) d7 `- J7 _! W; a8 t return '>';. j; r5 O5 R# ]9 p% }# H
case '*':
1 v' }7 m& g) w8 k+ f" x case '/':
$ j# F3 {! i$ [+ |& C/ o/ r if(c=='+'||c=='-')
4 _; \3 n" l) `4 c8 Y% O( |* |" U return '>';
3 ^! C7 r) S' T" h else if(c=='*'||c=='/')% v) m3 M' _6 }* m# f4 y- q
return '>';! W5 N) C; y% E3 D$ z
else if(c=='(')5 X, R: S+ e! G/ Z$ j% E3 E* m
return '<';0 q) d$ x& K* g) ^' ~
else if(c==')')& y: s" n! L3 y, a0 z3 N3 X
return '>';3 b6 [! S9 x$ n
else
' j/ k1 S2 W) K. s1 R; y: N return '>';
, Z0 M0 I, \6 X) F" m case '(':
: _7 \( c9 A+ u& b4 [8 z if(c=='+'||c=='-')0 x" t8 G- A& w' y) J; K
return '<';7 a. {5 j ^& o9 z
else if(c=='*'||c=='/')3 ?- {& Y: O2 t( p; d3 _/ O+ l
return '<';
2 ?/ ~3 w: G9 A1 j/ r3 `- ` else if(c=='(')4 w! \9 ]4 t: J" {1 h+ k
return '<';8 L6 S7 d1 c( C7 a% v4 u
else if(c==')')" i. I5 L# }) S4 v0 b: }2 s- f' U
return '=';
) X, a0 z, O% I4 E. B* P9 r7 F0 U else
6 U- d4 M% l- [ @ return 'E';
3 \+ v& ?! r7 w# ]1 n, t case ')':( p8 H4 }. Y4 b" B) b
if(c=='+'||c=='-')" ?7 \0 D; s& ^6 _9 \0 B1 u
return '>';
$ Q% V/ P# {+ P9 W2 s else if(c=='*'||c=='/')8 d5 b" f2 `8 E: ?
return '>';3 c; \3 s; z: L2 \( m {
else if(c=='(')
4 [; Z6 |& z& n- v4 N, g( v6 | return 'E';' o$ @0 z) t5 p/ N
else if(c==')')
2 T" H& d! B; I# a/ l% B return '>';$ _2 ~2 S9 O u; H8 M! z
else y: i4 `! g- J3 o, G5 w3 g
return '>';
% F3 t- e8 b4 r: E) k6 n4 i0 n case '#':. u+ y3 Y4 H. u" q9 G% N" D
if(c=='+'||c=='-')6 a+ v; V4 `; Z! }6 g( f- N. D) T% L
return '<';
7 i5 R/ M# m- z" d else if(c=='*'||c=='/')
! `; w: Q$ u* n5 I% Y# E7 _0 B7 L. ] return '<';2 |1 T9 b! o, F
else if(c=='(')" Z9 k4 x5 b- F7 I/ p
return '<';
; E$ G! {- D5 G2 f4 K7 z else if(c==')')
1 @5 ~8 a7 m7 R- O9 y return 'E';
9 g+ R8 m4 X2 e. P$ M; k; k0 d' f! w else5 g; O! O* }5 }5 @
return '=';$ f* N A) F3 b/ N* R$ r
default:2 w K6 H2 ]6 b, M5 G, y9 X
break;
! h3 _ r1 F" H' w }9 y" {# L+ G% ?. l
return 0;
. {& g2 C$ L; C( K6 n) T}
2 A* G) V$ M/ i/ \% R
. R Q# B E4 t4 [0 t: a- ~int isOpr(char c)
& N% w8 g/ x! W9 `7 T{7 I9 D- h6 R! a
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=') e, n! J" e u2 [( {
return 0;
' N# S6 v; e8 ?' i% h& N else
7 P9 a( s8 M# A& S1 l return 1;5 ?" o) D2 O% r) g) L9 `9 h
}
7 t2 T7 D+ s8 C9 ]$ e1 G: T" L: y2 N- w3 k; g+ J
float operate(float x, char opr, float y)
) M% h, [ s! V{( ?5 ?' I; \: A: x
float result;# p- W! t% V4 i( u; r' H# C
switch (opr)
; W) E$ W6 v: F; M) A {
; T2 I, \; {: D: Y2 ]+ B# c0 V* f case '+':
5 r0 n/ h( W0 e) C+ E _% Y3 T/ o result = x + y;" w( V7 t& Z& w& C
break;
t+ H% n8 ?( ]/ e9 M case '-':
8 h4 X, `) s& n% E9 W% d result = x - y;- h8 K: N, j, Z# l6 c
break;+ y4 y1 M2 d! m2 w6 y
case '*': 9 @& ] I( Z) | {, r# d
result = x * y;
V: w7 a: a) ` break;
" w; ^% X b$ V' z: y case '/': ' k8 c# ^ l6 A a. h# \0 X
if (y == 0)* ]& p$ S/ p3 C' u" {
{
& P9 j7 b8 Z8 k0 } printf("Divided by zero!\n");
4 y! U5 ~4 M: H return 0;9 f& l8 F) N! g6 p) L; }( J- ]
}3 L. T; W9 r+ }" I2 e3 s" ?/ K
else9 k( _+ t; K, k( `+ E
{
- c$ L+ t+ g) E: \& t5 f result = x / y;- }3 i0 u, F; r7 j: N! F$ K/ L T) |
break;( o3 |6 }5 q# B/ v0 w! _6 Z: _$ z
}
& I' z1 l2 x( { default:
3 L5 Q" e( p) @ printf("Bad Input.\n");
5 D& F! p! m5 M& k return 0;( x0 F8 F% J* T% y0 z% ?
}4 `+ i# Z- G6 s' }
return result;
1 Q# r8 l0 ?8 K3 p" y} ! b* H! b5 T, \0 @* M3 N
. m: p% a' @4 S' s# \5 N4 y
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*// l# q D, H% T7 N
{
# g9 i7 L: M- V U Stack optr,opnd;
* x3 ^8 [4 _0 v x0 ~" O$ [! y! ^( Q* z struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;9 k L2 |+ V0 F% ~4 z z
char c;
% N; _! `8 n; B( B" E3 t9 s char buf[16];
. ]' Z1 e% O6 }2 I) h int i=0;
4 ^* }& h% `! s; ?* J: x / K, Y# u& |. Q* S
InitStack(optr); /*用于寄存运算符*/
; A: s- o+ N- f+ b) Z InitStack(opnd); /*用于寄存操作数和计算结果*/( |/ @! }8 b1 b- f7 z+ F
memset(buf,0,sizeof(buf));. @, H9 \$ X. c3 f/ R% y8 v
: M! `* H. {! e. A' D, I. l# y+ o
printf("Enter your expression:");; q6 c1 |2 w! L$ q6 E R% W+ s* H9 F
$ s* |, p2 u1 x& b3 I- p opr_in.ch='#';
/ S/ ]- c' l+ P5 o Push(optr,opr_in); /*'#'入栈*/
8 u5 q9 W- ]3 l GetTop(optr,opr_top);
& @: Z, E( y" M k c=getchar();
2 l q, g( N9 `9 Y, A% | while(c!='='||opr_top.ch!='#')
0 d c( w, ]: ~4 |8 ~8 I1 J5 f" r {* k! H5 N. R. a2 Z
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/2 ?3 v# _; t+ \& G+ @
{
& K' u4 ~" z: w2 N buf=c;
$ Y% f; G' C' J2 x5 b i++;
' {6 V- \; `7 H- Y3 S' }; ?; v c=getchar();
1 ^6 h: n3 v% X, J; J }
\ v- U0 e. k+ u4 x else /*是运算符*/) g- d% q9 E1 Q& s/ h9 Z- b
{
$ c( R8 C# f0 J+ d% [ buf='\0';
& K; H) N' \9 j! a# x if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/0 g6 q+ @, p: k+ q+ E' K
{' t& D+ t" H/ Q, o
opn_in.data=(float)atof(buf);% B8 M3 ^: j$ m
Push(opnd,opn_in);4 |+ x4 k1 n( G1 h
printf("opnd入栈:[%f]\n",opn_in.data);' Q) V; z6 m ^# E" X! p I+ Q
i=0;" k: M! c0 X; E$ C e5 q" D2 C
memset(buf,0,sizeof(buf));
2 A D9 Y9 a- V3 k [# ? }
* d- ~& `; S$ Q' { opr_in.ch=c;5 j/ S* _, n2 u) ~
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/" u3 Z% Y7 Q( l6 h" W+ V+ M
{
" K: C; U1 s @1 h; t7 Z! [7 D case '<': /*优先级小于栈顶结点,则运算符入栈*/
! l" n+ n, D0 N+ q, U. {( o3 x Push(optr,opr_in);7 o" w& s9 x9 C/ E! c* ^
printf("optr入栈:[%c]\n",opr_in.ch);
2 j& \& A6 a2 q j9 w c=getchar();$ `) q; n6 K! J$ w3 E6 E
break;- ^7 A; K F ^0 A
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
, s! s+ ?) c* J* R6 R G7 V) S Pop(optr,e);4 z# A' H. ?& q9 Q
printf("optr出栈:去掉括号\n");
* H! R0 v8 J Q+ N* s' u c=getchar();+ h4 }! z4 v6 D, O
break;
1 y& r. k: q) E1 P4 T( O- z+ a case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/# ]5 i! A: j% x/ J& K; ^) ^, ~
Pop(optr,opr_t);7 ^/ {3 a3 M U$ I( f4 y) n
printf("optr出栈:[%c]\n",opr_t.ch);4 x4 G# d- Y- s* W% B5 }
if(Pop(opnd,b)<0)! S) f6 G5 G: h0 K
{
+ D2 T6 R; ]1 Z printf("Bad Input!\n");
% C; F9 l- y* O' B) D fflush(stdin);
; N' `/ n# C M return -1;
* J2 f$ N+ q( x" `' C( b1 C4 S3 m }4 }: P6 M$ N* |" L9 c( [
printf("opnd出栈:[%f]\n",b.data);* a# q7 O2 h: M( P. K/ n* B
if(Pop(opnd,a)<0)3 | x8 Q8 C" J5 B
{
* k( w1 \2 O6 o1 Z/ m3 n printf("Bad Input!\n");. z& y( P1 k$ Y5 H
fflush(stdin);7 E% \* B; A9 |- W P" N; }
return -1;
1 t. K1 \+ p+ a% K& m0 f6 u }
# r5 N8 w3 N# j: v N+ J& h printf("opnd出栈:[%f]\n",a.data);
8 S2 X- R' P4 w- ~7 a0 Y; m opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/, q) r& i& S1 W: o! L
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
9 s* F7 k7 y) w printf("结果入栈:[%f]\n",opn_tmp.data);5 X2 C9 l: ?- K7 }. y
break;" R- U; Z% }7 x0 j3 e& a2 \! V
}- u/ F5 S8 D2 \6 _2 g: s
}- _" I2 V8 O" {# ?
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
, ^1 X) ]6 }. a1 G$ i }9 {, Q: A! V5 t8 q8 c
GetTop(opnd,opn_tmp);& O$ z' O! m. x! P( D2 ?, V$ d
DestroyStack(optr);
% U! E- c) z5 V, H" I# n DestroyStack(opnd);
! z( B% V/ ]6 k& c9 ^! i: n return opn_tmp.data;
6 z4 z! J F2 d9 s}% q/ Y. V. k0 p* [$ H( ~$ R
8 \ x# j% `& z; pchar *killzero(char *res,float result)
+ v) j9 P& ?" \# _{
$ y) M+ j. B" P8 o int i;
( H" ^3 K9 P0 q; T- ]
% \) w; z0 c, m) f e; {. ` sprintf(res,"%f",result);
% N/ b# r& a, M; f" L i=(int)strlen(res)-1;" C: {0 C2 J2 l4 y. G
while(i&&res=='0')
2 }2 J$ S1 p8 E, F# E {* w/ C# f% ?* D2 Q7 j+ {
res='\0';3 [/ U V. ~! \( Z+ L: r) K& c
i--; S) k, z6 p, }$ }5 Q4 h
}# K% c4 Q" [4 v) m# S
if(res=='.')3 l. z' x9 F+ i! g% S
res='\0';
4 N' S3 Z( M$ T3 M" {& C8 b$ u return res;1 n' ?/ Z- Y( T& o, @% E
}( Y5 S* `3 e B- `: I
' |5 n; a9 P; ^2 ]$ P: m
int main()3 J( C0 r2 p. M: h4 }# a9 h
{
! q# K! L8 b2 X7 ~$ ?: u char ch; ?) e+ v1 s4 ^ J s* [4 u: [5 ^
char res[64];2 E8 @, X: A- l8 x
float result;* R( {+ Z6 k0 g( Q" }5 m/ O
while(1)
R. U" S- W. v# r4 u0 b# ~7 q {9 }- J( s% M7 u' `
result=compute();
6 j: A& D* E5 y printf("\nThe result is:%s\n",killzero(res,result));
2 ?/ k& t+ @5 g1 H% |" k$ g- m printf("Do you want to continue(y/n)?:") ;
3 N h2 l0 I/ C3 z ch=getch();: J) {! I. d: c7 h2 X
putchar(ch);
6 @& z0 Z4 v& B2 ], Q- H if(ch=='n'||ch=='N')+ Q' l, c+ r/ f1 y) E- B6 c
break;
4 l( G. A5 z. W Z; f. N( E( d! } else9 C6 P% P& P7 Y0 z
system("cls");8 T, ^3 D2 ~8 A# L0 R3 ]
}, s* L( }2 _ w1 D
return 0;1 c# ?! w1 a" b4 p* y7 p8 O$ Y
}
" @& W- K% x# [3 ]0 x2 l6 O- W. Z6 }0 k8 T0 M
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|