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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
" p4 W4 K; m2 P1 o8 p( ~) ?) D程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
3 {/ U; X' d8 v; V. E6 I, j/**************表达式计算器************/
5 Q+ Q5 r6 l5 @3 U#include <stdio.h>
' x) l8 D1 X$ W7 ~' q#include <stdlib.h>
4 j& J2 }0 L2 t9 j" O2 ^8 x) H#include <string.h>
- u5 X- D7 w2 o3 {5 A) A" P#include <conio.h>
' L/ i% {8 [! D$ K1 v2 b#include <malloc.h>2 ]) j- w. E: y5 `# P( G. j4 D
: }4 e1 r; A* M! D8 b+ ]. S4 N#define STACK_SIZE 100
( d) } E; k2 {" }' k- N3 Y3 K#define APPEND_SIZE 10
+ l+ X' X% ~8 H& R6 d" G" k; R! B' O- M
struct SNode{ _& v9 J# ]$ @) q: x
float data; /*存放操作数或者计算结果*/
d% @2 l0 f6 ]% _6 u char ch; /*存放运算符*/- R' p: {- E; D3 [
};* f. |" T1 v$ h' d3 k( x, l
( b( p3 _2 z$ Q1 `# @
struct Stack{
; T7 L& ~8 `7 ^! @) d5 H SNode *top;, u X( P7 T% l, m, Z5 ?/ O
SNode *base;8 F3 m9 ?; u a e2 j7 s
int size;$ @. C* R* u% Z4 u9 b' n& w* s
};# J5 s* o8 F- H1 T/ Q( i
1 ^! T5 \* X H, Q1 q
/*栈操作函数*/
+ P, {/ C. C, O4 Q( Xint InitStack(Stack &S); /*创建栈*/
4 V# a' R: \& @: I. G- Rint DestroyStack(Stack &S); /*销毁栈*/
: Z& m. \2 o: }( ?: H, }int ClearStack(Stack &S); /*清空栈*/( n. `. X8 ?' F* t3 J W; X
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
# }) ?8 e6 h* zint Push(Stack &S,SNode e); /*将结点e压入栈*/
+ a3 @5 E5 D& v6 ~$ \. B' `8 |int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
9 p$ H! L C' ]! `0 O3 g S* n. C9 j- q8 Q# k
/*表达式计算器相关函数*/
# W5 J3 t# P* \* p& E6 rchar get_precede(char s,char c); /*判断运算符s和c的优先级*/- Q8 h9 t: f) r( W
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
) Y1 Z) L0 p$ yfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
3 N" ~. V/ Q3 d9 F9 P: ~2 S! b Qfloat compute(); /*表达式结算器主函数*/
% ~' D. z$ N- u% a# F% `2 y8 kchar *killzero(float result); /*去掉结果后面的0*/ 7 J) G9 e- V3 @: t
, h1 ~3 ]( L& w0 U, m4 E5 @ Bint InitStack(Stack &S)4 b1 C, ~4 X# V. [. C0 |3 h* r
{
7 |$ x% F; S3 f0 T3 E S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));* n( z- X9 x: ?2 @
if(S.base==NULL)
- I+ i$ v5 @. a5 p {
} m5 q$ i0 g* e6 o" Y7 W( { printf("动态分配内存失败!");
$ I( G# \5 ~0 U& Z r4 Q$ R return -1;
0 t7 h% T# Q/ G9 z0 k }
. r5 y9 L9 w" d1 {) m2 x) [ S.top=S.base;
2 V: [# A7 ~$ M( R2 \ S.size=STACK_SIZE;% R" A) K* z' \4 [
return 0;% I: d% V! w) j1 Y
}
# N# ~5 V$ T$ ]+ ?& e& B0 q; e
+ k2 j& J7 p* yint DestroyStack(Stack &S)
% p: n) Y% _9 n{( l! O2 D3 }- }2 Y
free(S.base);
2 `+ [1 k. f" \8 ?0 n h return 0;5 I z" B: L) N) @6 a2 L
}
5 L" z7 r [% U+ X$ e) u2 y6 @5 @% Q
$ r4 D+ m- C* {5 G, tint ClearStack(Stack &S). y R% T( A' [( g
{
! U6 |2 }3 `) y' J+ m S.top=S.base;
' ~" K" p1 E: b return 0;! |" y$ R9 L4 @: V
}2 y4 ?4 a1 t L/ r, m" p# R
6 [% W& c7 N2 ?: n% Bint GetTop(Stack S,SNode &e)3 y2 r9 [/ [$ P0 o1 q A4 r$ r
{* p& Z% f+ ~4 [4 O/ Z- g
if(S.top==S.base)' g: A6 E: D& b7 o/ j8 ?
{
' z+ H5 U% q* C" C; W2 F9 p9 i printf("栈以为空!");
1 m0 T, O) V5 U h6 j4 ` return -1;
6 q$ \( y7 t/ J' O {% y/ t }
5 _* b6 V1 _3 F6 x+ M e=*(S.top-1);
" @9 Z" H# Y' c4 `2 A, V- _% N+ B' ^ return 0;: b+ ~5 G9 C' h; s
}
$ w& {- c. C f: b; l
2 ]- b2 }' e; ~2 Pint Push(Stack &S,SNode e)
, m: v3 r( K5 i4 T{
' h5 v( N2 |" C7 q" d if(S.top-S.base>=S.size)/ { Y' B% O0 z4 ?
{% V. [2 U# t) M- y
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));* ~* ~2 w1 O, R0 c$ F: ~( `+ N
if(S.base==NULL)" u* J7 A7 |) N. L. K
{
8 L! r/ B6 l G+ V- j: p. z, b printf("动态分配内存失败!");
4 r0 `, l+ o, E* j4 C return -1;
+ n9 |, T* J3 Y! h- _" @; Q! d; _ }/ G6 V1 x2 C2 v: {: N) a
S.top=S.base+S.size;
) C0 x1 |' L* N+ v/ G/ q& ^ S.size+=APPEND_SIZE;5 R9 S2 e8 I# V4 \' E9 ^; t& ]
}7 ~. R% y4 D1 p, D5 H0 }4 M0 `' x& \
*S.top=e;3 ?! u/ X% T: f3 W( p
S.top++;
* k# r2 Q9 \3 T! Q. t9 U+ \/ m return 0;6 ?# B8 A% l4 U6 `
}: n- `1 g. T3 Y0 l+ b2 T+ f3 V
$ r* O3 B1 \7 [2 j% ]
int Pop(Stack &S,SNode &e)1 M+ I" j9 v3 @, b, s- n
{7 d& V5 B3 |6 c$ g' s
if(S.top==S.base)
) v9 @$ m: o4 b$ n% j) w) U) t4 Y {/ F- f6 f3 R2 t6 P. V) o) h, y9 r
printf("栈为空!");
) d5 Q- p- s: F q$ X return -1;; \2 @; C* R E. W3 P* v
}" S; w7 u. a) w& a
e=*(S.top-1);
7 S- V$ e0 \9 k; r, e& Z4 @7 e S.top--;
7 d& _( H- C4 U C- P return 0;
6 `# w% H) p: n5 T2 E7 @}
' O! b+ D/ B8 e' N4 H, ^
6 @0 E) J2 N7 h5 g, g7 L. D3 nchar get_precede(char s,char c)
+ }$ u* _/ a: Y! h7 |+ L, {- M{
9 P1 |% D& n+ W1 N( v) G- B switch(s)
4 s% j P7 ~9 e5 ~& G {
! l2 F# } V5 H4 U/ \2 k. Z7 M case '+': ; k; h! J. ~1 p5 c3 W% {
case '-':7 k' ?. y& f5 o7 b
if(c=='+'||c=='-')
r5 u; L9 ]& I return '>';: N8 r9 g+ L* q1 g- k6 v8 j8 [
else if(c=='*'||c=='/')# q* V4 e" g. R5 j; K+ N
return '<';' c7 N7 [+ ` B8 n
else if(c=='('): R d* v4 M4 ]" S4 v
return '<';
9 P& n6 X, W8 }4 E; T0 V else if(c==')')* H. w% N$ w* Q% U$ ~# E" q
return '>';2 k# @! [2 d+ z* G" z
else 3 g8 I. ]1 g; r1 q. t
return '>';' c, C, L$ t5 v" H
case '*':, n! H4 s4 W6 N5 g
case '/':7 W: j& j0 W8 E5 | A0 h& b6 H* T
if(c=='+'||c=='-')
- V3 B- g. T5 }: j/ P* P return '>';
; L9 u% n" W6 ^ else if(c=='*'||c=='/')
8 F6 I7 s% K* _6 C. Y3 N return '>';
2 e$ V+ L6 s7 c0 J else if(c=='(')
2 |& J. h4 s% y# [2 h$ S5 c3 p) i+ N return '<';
( `+ l H. J2 l) A6 {) x else if(c==')')
" f$ G8 O/ v' n2 T6 ?9 _ return '>';- @9 T" N& t9 \
else: [ ~" X n& ~, z) U1 x
return '>';
7 X ^1 T/ ~% q A* W& z case '(':, b) J7 Z. c+ k3 ?
if(c=='+'||c=='-')& v: H8 e4 e4 S# H8 s2 }8 z, w
return '<';5 T. U3 u3 W$ a O- K- m3 I4 ^* w
else if(c=='*'||c=='/')
8 J$ P8 g0 V) o return '<';& N- S, Z0 I# _- G2 v3 m
else if(c=='(')6 S. \* e; m/ K4 m `/ O
return '<';
- x$ e+ s$ c0 x2 k' R* M else if(c==')')) `! c5 l. o5 u" N
return '=';$ | z# [3 _1 b/ r: a! \1 ]" l
else1 ^: W& n8 A, j: |; N3 ?1 u6 n
return 'E';1 c' q) f0 l0 F
case ')':8 S) ]( ?- _) I4 u* e0 c+ {1 q
if(c=='+'||c=='-')
8 c7 @, `: o9 `" z return '>'; W2 r# H! y! d; Z
else if(c=='*'||c=='/')
* D8 ] x4 n% ?8 Y2 L9 L6 q/ c' M6 j# r return '>';
8 K% x1 ~( t3 n' ] else if(c=='(')! ] x- X5 ]" |1 D# K
return 'E';
4 g/ m1 H9 e5 U4 f8 s+ g( a+ h else if(c==')')
7 u4 E7 y, ?$ s B# D return '>';$ I5 |2 x3 }7 a) _1 X& `7 g
else* C3 U5 J v9 G; W) \* a
return '>';9 h7 J% G# Q0 R X, e( I) ?* A+ J
case '#':% w! ]* l) c- |4 ]
if(c=='+'||c=='-')
2 U# x7 W9 s% s return '<';/ e- j8 R- S" }; S% w! c: I1 Z3 x
else if(c=='*'||c=='/')7 C/ W* n0 N+ A( D) k) C: R \
return '<';0 p1 R% n" b* f
else if(c=='(')
) m6 s7 Y1 x& F; Z7 F+ Y$ G4 X return '<';
r0 m) w0 ?; {. W8 s6 k else if(c==')')
3 t6 n- X# Q# ]* `& h return 'E';0 f o& W/ e [# Y% K; o5 i
else9 f7 O( D) z1 R, c/ s* ~( I- c* j
return '=';1 {1 y- e" u! Z
default:$ I, Q5 u/ S3 B$ W8 k& e
break;+ s- C' w1 T7 `# Y1 W4 z
}
! m( j/ F, K( H3 H2 f4 m return 0; 5 U- o) r4 k' j5 p+ C
}- c0 F" R+ D$ O4 `) o( j/ c
( [9 j# B2 k) D; r9 Gint isOpr(char c)
$ l6 q5 ?! i% a5 ^; P{: b$ x7 Q0 x: B' m) B
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')4 |5 \. O8 {. Y& _6 Y. K
return 0;
+ h) `' F8 {1 p# W( @" O else # w% h+ P3 l: B8 Y+ k
return 1;* M7 H4 i) w$ S* G* H. F
}
8 _1 i! [: j$ O, h9 Y8 M
+ ? Q0 c- @0 tfloat operate(float x, char opr, float y)
" K+ s' p( V9 F% E$ _ W2 o{
8 `0 R# f3 E$ p$ u% o float result;
& z6 J( {! a0 p7 R8 ]% d- h3 Q2 W switch (opr)
+ a- ?6 ~" j2 P {( w$ ~: Q+ n" `$ m
case '+': % }5 h& I' e3 w. X" V3 o
result = x + y; \+ U7 u, b9 C$ l
break;: O/ r5 p }5 c* J9 `
case '-':
9 Q5 Y3 M, [% m* @" P7 n h/ Q result = x - y;7 b8 i" h% X# B+ l3 T+ \
break;, ]( w( [$ C! B9 _, Q; i
case '*':
( \. c D2 d# k5 e' j, O result = x * y;, {% q9 M" X( ?) v
break;
; g/ S4 t, v" ~ case '/': 8 \# w+ D; ^- ]$ N: E$ s. `0 J( ~# t
if (y == 0)7 A. ^$ Z: |0 |) h2 p
{
; x9 [9 t. H: B" @' W0 W8 L printf("Divided by zero!\n");6 |3 J( W: D& d& [5 }( E
return 0;
: y9 }* P3 N- m9 }/ _ }
& U% j1 d8 V: k. d$ |5 Z' p1 z: [ else; v; o6 f0 L* r+ f( x2 a
{* q" r( A' u1 Y1 ^( S% `* ?
result = x / y;4 O& |0 N" i/ n9 f5 K
break;
9 O; E6 m0 x! q0 e' Y9 ` }8 t# T& C+ L+ h
default: 7 Z6 H9 P) r6 C
printf("Bad Input.\n"); . |$ _0 `1 }! [9 I# s4 B
return 0;
7 ]. Z+ w* S) K' T4 L# e }
* l6 Z. Y- `+ L( A! W! q return result;9 w0 l) P7 M; J9 |$ V0 q6 F' P
}
- B5 N9 a& v* |" n& ~8 p( `0 X+ x
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/8 W: o: M% X! K( s$ F
{, P5 y! j; w C8 h7 H# f m
Stack optr,opnd;
2 T& t7 n+ W* v3 y- J" S struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
+ G5 v9 _( b3 i8 o/ g8 @ char c;
9 R. r. L/ o: D$ [ char buf[16];
8 K& q+ E& j/ F0 ?! ~$ Q1 k int i=0;
( V; g- a: ]" ]& }; }2 R * W5 K* Q9 |- G" r; M) a. b
InitStack(optr); /*用于寄存运算符*/
$ q$ t6 V* E, @ InitStack(opnd); /*用于寄存操作数和计算结果*/! ?# J2 q, ^1 D- N1 U6 r
memset(buf,0,sizeof(buf));
8 @2 ?6 L: v* M4 L0 T) `
. O( L( C8 r; Q& {$ b! M printf("Enter your expression:"); L5 M& [ f1 D3 @- h0 v8 R
0 o' M% o* v- }. E, R
opr_in.ch='#';
- v. i% ~% h6 ^ Push(optr,opr_in); /*'#'入栈*/! X; g$ h/ ?6 v0 N. z6 l
GetTop(optr,opr_top);: w7 E, J+ W% _8 ^- s1 R* l
c=getchar();
7 T* R$ [( p) H while(c!='='||opr_top.ch!='#')
2 a. X( ^- V' s4 N( d8 C3 {; Y {
) J$ W0 l3 V" Z5 A3 f& o if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
+ }$ V0 K3 h4 H. I, T, `+ l2 D {% K& Z. W+ L( Y
buf=c;
p% s& u4 F# }& s+ ^ i++;& k0 N9 |& a: ?. s, S5 p
c=getchar();9 `$ A/ d S6 J, M' ?9 J+ Z0 Q3 p
}" J* a1 i0 p) n$ Q( _, s# `
else /*是运算符*/- j0 M7 s2 J: q
{
* s& D# f0 t% [8 b8 W) R2 D buf='\0';- D9 z y. y9 l* b
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/7 ?* V4 J2 O. q/ q* q
{' o: A7 I! R1 n
opn_in.data=(float)atof(buf);5 T4 \( Z+ S$ w$ d& j7 F9 ], O
Push(opnd,opn_in);
5 x8 V- x% a2 R7 f% M2 a printf("opnd入栈:[%f]\n",opn_in.data);
* q" _: Y1 U/ \- Y& Y- Z" P i=0;
6 X5 B ^( M# } memset(buf,0,sizeof(buf));
- J. w0 m! A4 a" |' T! E$ }" A }: I% X/ A# G0 x+ M: C6 k+ L
opr_in.ch=c;+ U8 M, M6 C# Z9 @" N9 \% @; Q
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/4 w' F3 c' o. x1 z6 K" i1 g$ E
{, B+ v6 K% M! A2 O0 G
case '<': /*优先级小于栈顶结点,则运算符入栈*/# H6 Q! a: i9 t; R2 n7 E
Push(optr,opr_in);
* ?% `% x" x" w0 z( s2 r/ o4 C9 l printf("optr入栈:[%c]\n",opr_in.ch);
6 j8 U. k N# _/ ]% L- C& ? c=getchar();' Q l+ T# f, ~' w+ z# ~* w
break;/ p1 t5 l3 s( x u9 P1 c
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/1 a& E! ~/ x' t4 X% t
Pop(optr,e);
2 f7 a# ^# U/ @$ R3 m6 s printf("optr出栈:去掉括号\n");
6 o5 g8 c/ M3 N/ Y l7 M0 U c=getchar();
& `3 s: E) r- s: {! M/ P break;
- S: l% \ s( ^7 _ case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
$ q- ]9 _2 x+ a0 q+ H* V Pop(optr,opr_t);1 x8 P- x, D8 b
printf("optr出栈:[%c]\n",opr_t.ch);& J( E. r. E) `5 }$ R
if(Pop(opnd,b)<0)
- O: p! i3 l# |& T1 b; v' m7 b {
) M# P) I1 c* ^; ` printf("Bad Input!\n");
3 }, r( E* I* w- ]5 e+ _. x fflush(stdin);: v5 [4 C7 U& N$ X
return -1;
6 s# K- R! W1 O# Z2 B1 i/ G }/ { \1 K* ?* p+ N( h
printf("opnd出栈:[%f]\n",b.data);9 f* M9 [- h1 _. c G+ z- K
if(Pop(opnd,a)<0)
% Z! t- k3 E: w5 x { X" e5 H% |+ u, i: c! x2 Z# h
printf("Bad Input!\n");
' O2 i/ M- f* ~6 e fflush(stdin);
' r0 _2 p6 D$ s F' n return -1;' T9 m7 d6 t7 X$ L3 j' ?
}. y1 n9 n9 R4 l+ D6 o1 j
printf("opnd出栈:[%f]\n",a.data);) L0 Y% l3 [, P
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/, f5 H( p( x+ q& O
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
0 _% u, E, N* w C4 E! e printf("结果入栈:[%f]\n",opn_tmp.data);
/ ~( e& Z& d- c& S; T break;
: B% B7 w8 b5 w1 F3 @" O% o1 ^# ?4 K8 K }% S: E, b, D1 e3 I$ l
}
% ?" R/ |! l/ H4 m# ?* r GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
* ~3 j& n- }6 t0 L( @/ T }- \. ]% @, S8 R4 @. M0 b" C
GetTop(opnd,opn_tmp);3 n2 j& }$ j# V# m M9 I9 N2 c* o. Q
DestroyStack(optr);( ?% G, t8 ~& H' b4 W- ~
DestroyStack(opnd);
2 f1 o [. i$ R: M' I1 p" q7 J9 B return opn_tmp.data;
1 f( }, R. P3 ]' H3 R% p}9 t! ?# c5 L$ y$ \
+ y4 m+ ], r) j4 N) }
char *killzero(char *res,float result)) \( O# G$ r1 z5 C: H2 Z7 @
{
" N1 ?2 I) A0 t y {/ P6 v int i;+ p4 c2 a; z9 q
* m, O! D0 J$ F9 z5 U5 U% b% d sprintf(res,"%f",result);
4 f% P6 B8 L! r8 b2 x i=(int)strlen(res)-1;
1 l/ y$ f4 U- O* Y- k while(i&&res=='0')
3 z3 t0 H# }8 [, A+ H {- u; d# C7 y. S8 A) p* f
res='\0';
' ` ?* c; e) K- y: P i--;4 a; z) ]2 C$ Q. [7 g# T5 P1 @
}
e0 G9 z) d, Y! y" ?7 O4 d3 r, N: T if(res=='.')8 v2 S' ~/ f+ ?4 L4 |2 r6 E
res='\0';3 m: Q6 k$ y- e( g8 \$ J
return res; ^( Z0 L" W9 F4 C9 [7 N
}5 O0 Y6 E0 J y; V
( }+ p4 C4 c- l. d! Eint main()
5 Z' B# e6 B6 a; w+ f0 N{+ j2 ?" A4 T% |. `4 L Y( [
char ch;0 B e3 p& d2 x: I$ Y' w- Q
char res[64];
8 B5 E8 \5 ?" s/ L- `( k+ p float result;
% A; L1 a, l3 y* a9 G3 n( I* Y while(1), e3 F8 v5 U4 D; p
{
" z% B I I/ t- I& T result=compute();
/ V4 A9 o) r) {& K! n printf("\nThe result is:%s\n",killzero(res,result));
5 E' @1 k* L- J4 ^, H printf("Do you want to continue(y/n)?:") ;
9 g9 F& v" |2 S: C- B ch=getch();' C+ w0 K! D1 H$ U
putchar(ch);
7 A) M1 N5 W1 _0 B1 n* q3 x0 ^ if(ch=='n'||ch=='N')/ h0 M4 j' g0 f, C; r. p' ]
break;
0 U; v s8 d' k( L+ M; W else
5 T; ~' q4 m+ P, }2 _ system("cls");
+ @- Z& C8 ~$ C$ v; h! _, U/ l }
7 W( M. |: w0 D1 ]" l. Z2 J return 0;) D. {, ~. A+ f( f6 l2 l2 \ ?
}) d0 t% ]9 _0 f9 j0 ~
( w0 C* t0 w7 i[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|