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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.! ~' q8 r9 H0 r' S% d8 x) z
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=% d$ K! a: s' C& h& p+ {
/**************表达式计算器************/
& _* W% @! |/ g2 K; |#include <stdio.h>/ M8 X* d, {0 V. i
#include <stdlib.h>
5 D0 O* {) H+ b6 [+ T3 u5 F+ W2 r#include <string.h>
) }( q9 b4 V8 `# D' P' `- j#include <conio.h>
( Q' h$ z! w, ^7 w& |$ B% e5 o#include <malloc.h>( D7 h- N0 Q+ J7 w+ I, Q |8 W$ S
. x5 g9 ]! K4 m. Z! e/ ?( X) T' Q#define STACK_SIZE 100
1 ]' u. y) R$ K! k; ]#define APPEND_SIZE 10
! t& Y5 _$ [% W2 Q0 c' k0 ~5 L; z. b, P Z
struct SNode{
9 e" L7 k7 O5 p# N/ j, C float data; /*存放操作数或者计算结果*/
1 r7 f4 U& K9 n8 A, V char ch; /*存放运算符*/
9 ^+ F; b3 i; R, O" l n# C+ L};
e; b. `8 B! q* u- _
3 d- j2 J- a4 N" S% W+ Astruct Stack{% g4 B4 m- n) O5 X9 `1 [1 \
SNode *top;
! i) [. ]# B- Z SNode *base;
u$ r. U/ f* Z% |/ f int size;
8 v* m( V0 i. ^, M$ c9 Z& L};
! f' H! {& \0 Z( j: [' m3 }/ R, R. w9 X0 E' a
/*栈操作函数*/9 i$ J% Y: t; v1 s# y1 R. C
int InitStack(Stack &S); /*创建栈*/
; v5 a0 @! r( Q& o- _7 k# ]- rint DestroyStack(Stack &S); /*销毁栈*/3 [- _& F: _4 d, H0 z8 ^6 W
int ClearStack(Stack &S); /*清空栈*/
& n& c. b3 j3 {" Oint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
- t! L2 P: l! v/ N, u0 dint Push(Stack &S,SNode e); /*将结点e压入栈*/4 ? }" Z% f! E2 K, B* e6 y
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/1 E/ H7 _2 z& d7 J& g
* }' R8 F% y/ l, N* f5 b' J
/*表达式计算器相关函数*// c6 n( l' R8 O5 x
char get_precede(char s,char c); /*判断运算符s和c的优先级*/ I! X- J# K: N, U4 w; o
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
+ V# ]& w& g6 e3 q( C- G# m% ~' dfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/7 L P0 z l! J/ J5 u
float compute(); /*表达式结算器主函数*/; V, P$ |- [; C7 C3 s
char *killzero(float result); /*去掉结果后面的0*/
. s6 {* p) J9 P; f$ @, k( H% l7 E% ^- U3 U7 u
int InitStack(Stack &S)
- X4 @! i% ]' d7 X, n' m{+ V; Y ?' n( A" Q
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));% d4 ?1 ]1 o* v+ C
if(S.base==NULL)
% E, Q( f8 W4 | {
8 A. _ M4 |2 z: N5 e' X printf("动态分配内存失败!");
5 |* B) B9 Z+ `5 e! j9 \, e return -1;
+ g! P9 U3 p2 o: E9 S l }
; y5 }( T0 r! h" d( c) c1 O, }4 F S.top=S.base;
) |( W. U: x. u; I, k. I: W S.size=STACK_SIZE;; d* K3 M/ Z6 A" H6 d
return 0;: d3 W" U- {; Y9 a+ m& P4 t
}2 z1 G0 T Z3 g2 G6 T. t& P# b
7 x( `2 }' e: g7 X& m
int DestroyStack(Stack &S)
, t, A* @# v3 J- H5 d3 f{
% x! C& |7 u; ]6 j# |) W+ @ free(S.base);
8 N5 x+ j# Y$ V. P* D9 U' i return 0;
( q2 x( H, G1 y8 M. M! ?+ ~% F}
! ?6 r/ q6 z. D: _! j4 u. _
2 ]5 h" v$ K. Z3 `) w" J' Q" p( Hint ClearStack(Stack &S)
( n n" g0 t/ K1 v# Z{
0 N$ y! A& s+ V1 l+ y S.top=S.base;. C& ?7 X/ `, ]) l# D: m
return 0;6 S. N% U( P( J2 r8 D" C& t
}
% h, v4 b V# ^8 S0 J5 @' }
5 `3 }+ u6 ]5 Y; U2 s1 g9 Dint GetTop(Stack S,SNode &e)
+ }* r; S2 B$ ^7 [0 c! H{$ F" ~- m) t3 r" n& _9 a
if(S.top==S.base)
% u8 R* x) {3 d {8 B( d, S1 X, Y' ]; }% v
printf("栈以为空!");
8 `' {0 U0 O0 {, j1 Z return -1;
) f/ |4 p% q5 _ [; i }
2 t% c; _9 C% z7 o$ t# }6 N* ` e=*(S.top-1);# }, ^. ]9 z9 C9 g U9 P
return 0;
/ \! j3 m* |- p" K( }- m7 b: r}
- c3 x( H4 j' b2 l5 g' J* X
U R/ U* @! H: M4 ^+ O8 V7 d( [int Push(Stack &S,SNode e)2 d$ e. i2 {1 v4 a* V4 x# m
{% ]+ K( V# ?; F/ ]
if(S.top-S.base>=S.size)
I: J, |+ ]1 H/ ?, a& S {' e4 S2 B; }# R. [$ }8 P/ h! B
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
6 D% x W* X, s if(S.base==NULL)" w0 w7 }, a7 b/ h \
{: W" n1 r3 W( W
printf("动态分配内存失败!");7 l& }" u" L' [
return -1;
7 b' B0 x7 ]0 x6 {, d }+ L A% ?) ?" ]8 n
S.top=S.base+S.size;: B& A+ B- K+ f7 \3 O: B5 c
S.size+=APPEND_SIZE;
5 \3 m/ e {/ u! o$ Q }
3 R, y) Q& I+ t: G *S.top=e;5 `- m* u# C; Z. a; g
S.top++;
! F6 B8 u d* _ return 0;
) e) d8 `7 f& l% E; t6 u) H! O7 M& B}2 ]9 p- U6 y* i+ K4 Q& W% z7 o4 b
/ S) H& ]- S! }2 _, c9 Q
int Pop(Stack &S,SNode &e)( O- r+ R" X! k" s
{' ~, }$ }& R( e8 R, B) V5 I
if(S.top==S.base)" X& o' J3 t( ^9 l# V
{9 T6 v- I' b8 V, Y( A% _5 {
printf("栈为空!");, y% {9 o! h8 C6 O" n) y$ p
return -1;& g5 M' f: Q6 e# T! @: E
}3 \! Y9 G# c: Q% h+ S4 }
e=*(S.top-1);
% u2 W6 M8 ]" B/ @4 y S.top--;2 M1 j* y, D9 @% L: B* m l+ k$ q
return 0;9 C' N& p% Q2 ^
}2 F$ M1 l/ [5 g
0 W; x1 n# M" c' q4 L
char get_precede(char s,char c)* [! u, n; ]4 [+ n) ]
{+ ~3 M" w( W7 p0 C/ r
switch(s)
2 } k: {- P6 U# u {: L9 J6 Z6 r+ K X% W0 {$ ^) B% o
case '+':
, d8 r: l [/ C' K6 F6 d case '-':
& Q7 b; b. u# _, V' ?6 p5 j if(c=='+'||c=='-')
7 o& }( }# I1 M return '>';1 J1 z5 K' i* E2 S, O! R
else if(c=='*'||c=='/')( W$ j" _' |1 D5 D6 D/ D. Y
return '<';
& N# @, Y+ f* Q! u/ a$ Q else if(c=='(')2 s$ ~" X9 Z9 s) e) F3 c2 }2 u
return '<';5 \' i4 U, |& p+ G
else if(c==')')
% \: o4 Y# g4 k return '>';. ~' O9 T1 v3 e
else & G, o3 A: V- d4 k# ?$ s
return '>';+ ?% ^1 X) c: H
case '*':1 @/ @/ Y& @# b! v! w
case '/':
( [' I* g2 W$ T/ @ if(c=='+'||c=='-')
# _" R- D0 [9 \7 K* h return '>';
! K) S+ t& \! i: M/ Q else if(c=='*'||c=='/')+ e5 L, v# X5 P
return '>';. t# M, H8 B. O6 e Y
else if(c=='(')
, s/ X, e- s% l6 n0 X& P return '<';
* w: R2 [1 s: h+ j# d3 P; V else if(c==')')
6 a7 U$ z* t4 X9 j! t return '>';$ R8 n! Q* D; O: U' G7 }: W! X
else" u3 k e! M( J( A7 f
return '>';
; h+ Y+ r; A g; x* n case '(':4 C# {; @4 D( F0 _+ G) ]: L
if(c=='+'||c=='-')
# v* b. |) R; {7 h5 J% P6 u- j b; M return '<';( M; |" r8 K5 x7 [9 t
else if(c=='*'||c=='/')
5 u$ T3 y, b7 @7 H+ o return '<';
7 g" ?/ m1 {; n9 Y. \ T/ W6 a4 g else if(c=='(')
& z" U( ^$ \/ S( T" O2 P2 s& i return '<';
, F5 K' X+ F5 [1 O( G: J/ w8 Z else if(c==')')5 G; d; y/ u1 ~, V$ c# |
return '=';$ ?1 X8 C. P O$ V% c4 w
else$ a# H) Z, P- W3 d/ Q' J
return 'E';$ @9 T7 i$ F% @6 r/ Z. h0 @
case ')':
! X$ Y9 x* x; h3 ^) K8 ? if(c=='+'||c=='-')
: Y0 e+ G; [# n, a, Z6 Q& v5 m return '>';7 j$ Z3 T) y9 l0 E g
else if(c=='*'||c=='/')/ n3 ?5 j% G, T7 y
return '>';
8 S ^( k* R% g; Z9 z) Z else if(c=='(')( N: |# c0 {, q9 o; j
return 'E';
# o' u1 Z1 `2 G& Z; \/ H4 Y9 x3 x/ d else if(c==')')0 e% ~3 O0 }9 N* V4 e# w
return '>';3 D( F" B* b9 v8 h7 d" d
else2 ^, I) g; Z8 W5 y# `$ F+ b
return '>';1 D% E; t; `) y% C
case '#':
+ F4 G! ~6 w& m" L- ?- F if(c=='+'||c=='-')
3 K5 l5 o% q. j8 h return '<';
& @# B& U: P; ?, t7 W. d else if(c=='*'||c=='/'), V' i& Z+ Q9 T- w6 Z
return '<';6 B i$ |7 L& B' f9 g S- ?4 s
else if(c=='(')
8 f5 [4 p6 N, u! j" W: c0 w return '<';& w1 y. k3 E$ K/ |6 {) j+ K
else if(c==')')
5 I4 {9 S. G. A3 k return 'E';0 V1 H: g D, C# Z
else+ \* r) A p5 P7 L
return '=';, e. R3 L7 v2 u, N0 Q# S
default:
% V; m% r$ D: t9 W* m break;
* Y# T0 O$ p% ], s" X5 X }
2 q3 v) w' V" R7 ~2 u+ s return 0; " @# b1 k% L8 U+ W5 r2 P3 o; O- b
}3 O; E0 X# d" ]! v+ m+ w& R; D' W+ H
( I O% P' M$ ]( ^7 p- _0 T7 Zint isOpr(char c); T6 a9 e X4 e8 f
{
0 l* L _- m! d6 ~6 n) j0 f* A if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')7 w( }+ x2 R) {8 |6 ?* q
return 0;
{1 j6 P/ k# \/ D! x else
9 r. F7 b, |! l+ b" Q7 ` return 1;4 I6 k7 v( G: c1 ]+ z
}
: V y2 X. W7 k$ K( s; b' L' Z% g2 ]6 j2 X* Y* M
float operate(float x, char opr, float y)7 h8 ^& U# A* P
{* r: g9 C; n! [
float result;
6 }; T0 D! L' T; W switch (opr)3 {- v! I9 @. Q* u/ B1 `( y
{
5 T- E8 p/ \! x3 y3 @% h case '+': , V5 ^: `0 T. h3 |& H& w& M9 M5 m& f# F
result = x + y;
$ R$ T/ T) `1 G. a; `1 A5 L8 ] break;+ P. M2 s: y3 a9 C I
case '-': ( B# k8 ]* g0 k$ [8 U- Y
result = x - y;
' \# a& l% P( u( F8 `6 }9 p' k1 O break;
0 z3 U+ n' I; j5 e! {5 G case '*': 7 Z9 ?( M+ N, R5 e
result = x * y;
! L1 }$ ~- \1 f( [# T3 X4 g1 N" d break;9 [8 Q& V( I7 X4 y0 s# F& w5 J8 W
case '/':
9 f. B6 |. D1 Y, N0 a* m- ^ if (y == 0)* @9 M4 X" w1 B' ?" E
{. T0 C! r" V5 v
printf("Divided by zero!\n");
1 w* n' U7 N$ m( ] return 0;8 E$ D0 M$ ?9 W1 R# F* s# \" J
}( p: V' b* k, k
else
$ p6 a- E3 D9 R) R7 l3 s {
! A- [: G4 S7 e2 q result = x / y;, K- l/ H. ^1 @- |. e
break;
1 J" T% @: r5 M* L, w }) S* {( n( U9 Z# a% B
default:
$ n) P) r% ?0 [: F: u6 y# U7 u printf("Bad Input.\n");
! S0 E' V$ v9 V" h& |, [0 [9 b' W return 0;" x5 @* ], J3 k1 E* p) ~8 u5 h
}
* R# d# ?7 f- z return result;
+ t- M9 S8 \4 C9 y+ a9 J2 V; v} 5 r& k2 _& Z( [# F
. u g, Z6 l) }# g6 qfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/. ?/ A' j* M/ G3 T! o/ H
{ @6 l9 h4 f! H) G; i
Stack optr,opnd;
1 r, \# Q/ z/ N% n2 o4 a# J struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;& V5 v/ L' p- X* ~( R0 D9 p8 s
char c;6 }0 b( I, @* F7 A" Y7 [
char buf[16];5 |2 l4 |# L9 s& w
int i=0;
; h2 Z3 i3 o; F# ?7 ~1 ^
# P; g' Y; X- V# g/ l B8 L InitStack(optr); /*用于寄存运算符*/
, j6 o- c, M8 P InitStack(opnd); /*用于寄存操作数和计算结果*/+ i4 [& o# _, ^$ e
memset(buf,0,sizeof(buf));3 d$ E: D! v1 y4 U6 Y5 X0 [$ T
7 z* @! X; n0 Y printf("Enter your expression:");
. E: |% M' G# P1 v; O2 I
- B0 e2 Q/ `" a4 z$ {; c opr_in.ch='#';
* A. F6 M6 k' s, C# c; T- D! c* @ Push(optr,opr_in); /*'#'入栈*/
. P U: i( b7 O( z GetTop(optr,opr_top);
* C7 i7 {6 e3 w c=getchar();% n5 @) y2 ^# N% q- Q) J
while(c!='='||opr_top.ch!='#')
0 e8 s' J; i; t4 i. _8 c {
( E* c7 m" v. e4 P* n if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
. |' Z- N) A; a {
1 ~5 K6 a$ H7 O8 { buf=c;
# k0 j# A9 B3 y! ?) g" A# U i++;
6 g& F- m r8 E c=getchar();: i# j* Y# r! M. h, Z
}
2 {+ `0 U0 f2 [8 X+ }4 s else /*是运算符*/5 Z' N' l; ~. @! U
{& O4 e( V0 R% E" A, y
buf='\0';; N1 ?8 f5 `: j3 l- n! B
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/4 b( _1 W8 a7 A/ h0 m( ~
{
( |9 n: f6 E& H* Q opn_in.data=(float)atof(buf);8 b# M) V% g' ~" @& V
Push(opnd,opn_in);; G. m+ v+ q/ k* k8 l9 V' ]- S
printf("opnd入栈:[%f]\n",opn_in.data);
( [ S9 Z$ _3 C6 I! ? i=0;( f" E3 S& `' `; ^
memset(buf,0,sizeof(buf));8 g/ v- ?5 F* `7 ~- h
}
$ R. `. W! i# B& Q* o opr_in.ch=c;) T7 Q. Y: t4 m/ \* q, s1 H+ _0 |. s' k
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
8 R1 \' f/ v! Y& W {9 B. ~$ l* o# Y$ V. S* ~& _; m
case '<': /*优先级小于栈顶结点,则运算符入栈*/
) z" n+ @4 w2 g9 j Push(optr,opr_in);; b% Y+ s' D, f" k* A
printf("optr入栈:[%c]\n",opr_in.ch);: S/ W7 T r- v* W$ c3 W
c=getchar();- j" j. w) z; `6 W0 L
break;% ~% r( Y+ b& w8 P8 p: c7 \
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
1 H9 U% S$ n+ c. r; a" q Pop(optr,e);
9 P- u9 E9 H1 G6 `' q printf("optr出栈:去掉括号\n");7 k: W- N; c2 Q# B! e
c=getchar();
3 F( _9 e1 r4 t8 a( T0 E% _ break;8 @& e& `* u7 l3 n8 [, R2 Q* z
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
+ v# o! E+ |9 v' |( z8 Y0 G3 b Pop(optr,opr_t);; i/ ~3 k7 V: t! @) q1 W
printf("optr出栈:[%c]\n",opr_t.ch);3 ~3 i) X- t! E# p( w+ T3 D; ~
if(Pop(opnd,b)<0)
% i# q( q+ K# I5 Q {6 g* h* l3 ~9 Q" Q/ P! s
printf("Bad Input!\n");
' ^. @, {. l2 H2 J fflush(stdin);' z& f+ X, U0 I0 N1 e3 l3 ?% L+ n
return -1;
. p) E6 u o8 F4 X% I }
6 N8 k% f0 n$ Q- A- h printf("opnd出栈:[%f]\n",b.data);
* I8 _3 `2 ^1 W! b4 t if(Pop(opnd,a)<0)
+ E U/ b0 `( m8 R3 e9 E {
% \) z3 @; d" \+ s: {; [5 k- ? printf("Bad Input!\n");
8 J V5 E! E9 ]# s8 H- C fflush(stdin);
) E1 X6 x, Z/ B return -1;% i$ E i7 e* z, |7 _" u T+ A
}" S- `, C. Z1 W+ q2 |* |8 ^
printf("opnd出栈:[%f]\n",a.data);
+ W- N& f6 s1 v8 Y, j2 U" M- L: b opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
, T! j' v; m% P: Z Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
% T$ F( @9 |/ I; O# q printf("结果入栈:[%f]\n",opn_tmp.data);) [1 Z& J3 L6 U" S
break;
* |& Q+ v. n5 X/ k V+ V2 { o7 y4 K+ ~ }
/ R. Y2 p% Y- G. Z/ J( ~ }
* T8 Y- [6 s$ G$ m GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
5 I- z" R5 H7 c$ g8 x1 e$ E }
1 I+ w8 d6 M. m2 H GetTop(opnd,opn_tmp);7 C2 y- l% X5 Z8 ]
DestroyStack(optr);# g* `% h6 d6 Z2 H2 x' Z. M
DestroyStack(opnd);+ d7 k2 K; ~4 h: I/ r
return opn_tmp.data;
3 V$ E2 L% f' m$ o S) ?+ q* ^}1 @+ \5 W/ N. |, j' D* x) k, D
% Z9 [4 W+ {2 ^/ I; a; \
char *killzero(char *res,float result)+ G- V: F+ V% K0 Z
{
7 p. O( V* p9 A int i;
$ F$ v% ?, _0 ]; Q3 n
" ~3 y* f& }+ m' N5 v1 U sprintf(res,"%f",result); P) q- p' A8 L! F% Q* u' Z
i=(int)strlen(res)-1;
( l) P5 o- K v while(i&&res=='0')
$ d, T7 f2 R! n3 L$ D {
1 \2 q# u# p0 v res='\0';' @. [# g1 B9 n" G* h
i--;6 H$ x3 |5 j2 C
}0 h; [8 ~/ ?$ c5 C' K- l
if(res=='.')+ q) |- W7 C8 R7 R
res='\0';
! w6 B* V9 O8 E" A/ Z, |6 k return res;
& [: ?$ u; b, P) G0 J A" p% |7 u}
6 \6 b7 }% T! C! D" |
, r( B: J* b" o* c: G5 Zint main()6 z5 H D% ~! n. j& `# Q+ l* j/ V
{5 S0 x l7 S$ N+ H
char ch;
% Z- h8 `" D3 l6 i/ O char res[64];4 }, d! \8 b2 R: ~$ o
float result;
. T& j+ b. ?+ } while(1)
6 n( p% a7 n5 L {
# c& c- V3 U+ A! H# D5 V result=compute();! v, a P5 ~, d2 i
printf("\nThe result is:%s\n",killzero(res,result));
$ M* X5 v( j+ c6 q$ C { printf("Do you want to continue(y/n)?:") ;
/ K6 o( j( M: j' B& E% a f ch=getch();* t! ]* c; O$ n
putchar(ch);
/ L3 J: z' o7 {; s9 r: j7 E if(ch=='n'||ch=='N')( ~5 K( \ j( A. i7 W8 W5 Y; `
break;
; r- Z8 }/ |* B- T$ ] else
# Z1 q j' S+ u# _ system("cls");4 N0 e m0 ^0 B# Y' W6 @
}
1 |0 p$ Q- S9 [" s" q return 0;+ K! K; L9 q* `8 n, _
}; c$ J4 B) t+ m" v2 E* d6 j
) D3 ], b0 K3 r[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|