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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.. S0 m) i* C2 ]8 ]2 D
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=! \8 I: ]% v0 r" m* G
/**************表达式计算器************/
5 V( X8 Y6 B4 c4 [) `#include <stdio.h>1 J# \" R9 m5 b( F1 s, T4 c4 T; X
#include <stdlib.h>
% z" d/ z( |6 Q# a; x8 W) A7 B/ T _#include <string.h>
7 v3 w% a! E5 m x2 w! x- v* X/ G#include <conio.h>
9 o+ j0 ?9 M' N. S# Y#include <malloc.h>
/ t! t1 p- A' M8 \7 D; T4 i4 M; ^$ g. a' ~
#define STACK_SIZE 100, M& n6 |- W& W) s. o$ n" a
#define APPEND_SIZE 10
, m) u% T% V, e; |$ T5 K, ^0 W2 z: C/ O o+ G2 ] |4 j
struct SNode{. A, r T: m7 ~) C
float data; /*存放操作数或者计算结果*/8 s4 E7 p, K9 c6 s' w: K, S4 s! Y
char ch; /*存放运算符*/
) O3 f9 `& c0 J};. M; L# A+ b: t4 F) C) t: r
- i1 v* V9 @1 z( [1 j7 Tstruct Stack{# B. { Z6 f( S% K) X* v
SNode *top;/ m2 V" t+ n' ~9 B$ m- Y1 Y
SNode *base;
/ `1 s' z m! P( o int size;
2 m5 [9 Z$ Y( [( F# ?1 n};8 {5 m/ G; [) g; I: Z9 [
( X3 A$ @0 ^8 [, F! b- p
/*栈操作函数*/
2 }) n- ^& y# M" \. X3 t6 j( Gint InitStack(Stack &S); /*创建栈*/$ Z& b" Y. a1 ]* w5 n+ e
int DestroyStack(Stack &S); /*销毁栈*/5 b2 k# H7 T1 U& H
int ClearStack(Stack &S); /*清空栈*/5 ~% J9 i& D1 P# X6 Y" C
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
% l" N* Y5 R1 {- b0 Qint Push(Stack &S,SNode e); /*将结点e压入栈*/
/ f% s! c3 s0 x- M8 x2 K$ Q6 Fint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/$ K. @4 ?' F4 o3 j8 O9 F" H m
2 l( E: c. Q/ i v8 n0 _% N
/*表达式计算器相关函数*// z8 C2 B5 S5 @) j4 f
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
- V. g; z4 t9 n5 w" r E; s, Qint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
; t& v% B0 N3 ?float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
. p; M1 B0 m/ p( Dfloat compute(); /*表达式结算器主函数*/
! `* a8 \" [: ochar *killzero(float result); /*去掉结果后面的0*/
2 W, M; T8 W' s- i8 J5 L [9 H6 K* v; N; h
int InitStack(Stack &S)1 r! D; A2 b# L- h
{
. g1 Z9 q: f1 m/ f$ ~ S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));$ f! u* T/ D, u/ T1 D. Z" O
if(S.base==NULL)2 X5 B F5 g* E' `" V% G2 ?2 \
{
7 [. l, @! I" C' J; F/ w Y printf("动态分配内存失败!");" ^( Q$ q/ ~! a! o1 s4 z6 A8 D1 w
return -1;
* T7 z" [! \) C1 x0 l& W) [ }2 Q! i( P E) o' o" I8 o/ Z
S.top=S.base;
$ d# j7 Q5 T: g6 H! Y S.size=STACK_SIZE;) H C- ~: L4 l5 @# t3 S( H0 M+ X
return 0;
6 C/ y8 N# K# ?8 O7 m; R}3 [ w+ l% r0 _
+ r/ n9 L/ L1 S Y' r' Mint DestroyStack(Stack &S)
. x( Y3 Z+ p& R0 g$ ?{
9 x, G4 F, O' ?6 r# u free(S.base);
1 {1 p2 G. b5 G return 0;
: D3 ^7 ], w* {2 u) H}
`# {) d ^1 `0 n9 C) [6 J, R
# N- o- P% W" G! ?; w8 D1 j! kint ClearStack(Stack &S)
' s# k% \" |. g3 n{
# p! q7 _" H6 T4 ^ S.top=S.base;6 S |) J7 H0 q6 e
return 0;
7 b1 R7 T& f- i' A5 T1 b' W3 l& a}" `% c4 _. J7 B; B' n
0 X! G" q c) y3 ^/ Aint GetTop(Stack S,SNode &e)
9 f. Y7 ]6 W- M! c: R. X{
. _; d1 q1 i# P9 m5 Z if(S.top==S.base)
2 Q4 ?5 h- C- J( f: r. q {/ u3 |/ y- v# F5 [1 U9 r
printf("栈以为空!");) I3 {$ d& {9 x
return -1;; ?) {: r8 d4 w0 X; |. m
}/ v: D; e* S ]1 G' w- a
e=*(S.top-1);! _ Q9 D, t1 d0 } g
return 0;. e" z. e, W/ m0 `. a& B6 Y
}
1 @. r+ D4 b& {, w: m4 C0 p3 S
8 P. U% p: G! G2 g) Y$ q# Q/ Xint Push(Stack &S,SNode e)" F( }: b8 `! a8 L8 v+ A& L
{
* T3 {9 x- U% s }) E- J4 ? if(S.top-S.base>=S.size)+ t1 ~; @, V# f \, Q
{
4 e W- _1 l. K% Q9 i" t S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));, o9 w- c3 M0 K2 ?& h
if(S.base==NULL)
. n) v O' Z, d! z7 a5 W {
D# x* L8 F( M6 ~' I3 v+ y8 z2 a printf("动态分配内存失败!");* C2 p c2 w+ h
return -1;+ P, |- r' j1 V% n
}
" h1 }9 l( H) w7 M/ L S.top=S.base+S.size;
" B! W; i3 k( e8 d Y( I( H S.size+=APPEND_SIZE;
( E+ p: E& U! Q3 V# g# q: I& i, N }
* @. A, `- ]% S1 r O" ~ *S.top=e;
: E$ i- c9 N# l S.top++;: B( S$ W [7 X' C) T5 m) F4 q
return 0;- X& S' O( L2 {! i2 C: R5 M& O
}
/ H; @2 l" W2 N9 @) o% ~ S3 \4 s
int Pop(Stack &S,SNode &e)
8 x6 `3 j0 K# w+ T" m' t+ ~9 k{
" O. X6 W, v6 ^. _ if(S.top==S.base)
. i' Q9 o8 I d8 }- f {6 d) T( X" t5 T' _- k
printf("栈为空!");1 q* ]; ?. j! p
return -1;
P8 W: G& I+ d4 P } y1 O. p# }7 q% o1 N
e=*(S.top-1);" t$ A% F5 L1 M" W
S.top--;6 v: [- N" L# G A
return 0;6 |; J3 O6 v p) J( j$ e
}9 A( U3 x( m4 ]3 y. _6 v) d
9 P- }* _& d9 P! Z
char get_precede(char s,char c) c/ A( l. e# {9 M
{* M1 c) K c# O
switch(s)
- m( p, Z+ o( m4 a/ x$ |" N {& w! E: p0 Y9 a# Q* b3 X, h" W. z
case '+':
0 R* t4 t+ C) R3 K case '-':
: Q2 m7 X8 l' U7 h9 Q3 W6 p if(c=='+'||c=='-')5 ]& y4 L6 i2 J0 a; l5 B$ Z
return '>';* n. S! n' F4 @, K
else if(c=='*'||c=='/')
; n9 j. w4 c; ?+ C! p' y return '<';) U1 U' i% ~0 o9 Y) T/ ?6 P
else if(c=='(')
# B) N# n% v% ]: J& G) K/ g. s return '<';
6 |( {6 P C3 K) ` else if(c==')') L7 q3 F; @; z5 ~. D" ]4 B. _
return '>';& D, L$ e) m$ L7 }
else ( Z7 K1 K3 @2 p/ G( O) g
return '>';, B0 e2 b$ u5 U' M" l
case '*':7 b# ]; l" ?/ G/ @% l/ j; n; ^
case '/':* `; N* T- `1 d* W: K
if(c=='+'||c=='-')1 h% l8 D/ b' o7 D2 D% F7 ~, p% \- l
return '>';
6 k% G- P, J! j) \7 m: ? else if(c=='*'||c=='/')
! v+ C- ^( b" a" S& g# \ return '>';
( V" e( V5 B9 e% y* Y. C else if(c=='(')3 E* ]) |0 B) t0 P: h. g* | e
return '<';: E/ o+ S, K* S' T$ y E- u
else if(c==')')- Y/ S: \# ~; l- E0 |+ X
return '>';7 R- p! w% j+ @/ \" q$ c( v: r6 _! [, [
else
+ J2 p, b& E; r3 C/ p return '>';
! F" h8 T7 i1 E case '(':
" c; @5 y/ P5 E4 m if(c=='+'||c=='-')
1 B! T" I8 Z# R; h* b return '<';( K( d# ?; e# d
else if(c=='*'||c=='/')# ~; M# k, ], q9 r" d' A( K
return '<';
; k' g" t1 j' `" l5 o& R3 ?, U else if(c=='(')! @ e0 H C8 D( B
return '<';2 c* @8 D4 I! I) k u
else if(c==')')2 f/ T1 H4 @! q" g3 Q) {
return '=';! F* B$ X0 f( H' Z& x0 Q- R
else
% z% z; T1 `. ?% l; I return 'E';
- p% y+ b9 C, ?: }$ ~ case ')':
" Q% w: B+ _; {0 Z if(c=='+'||c=='-')
3 U# F" G% Y- D8 ~7 h- t/ e% k return '>';
/ |* \) X9 m: l# P4 v, X1 i/ m0 B else if(c=='*'||c=='/')4 Q ]- ^# Y, z. Y. {' j
return '>';+ C9 u$ c, h4 l: u6 p
else if(c=='(')3 w% K$ O' e; U# X8 @5 |3 y4 a& R
return 'E';
: r& y0 v4 X' p( _/ v else if(c==')'), A" j- b! q9 U- M2 s9 N
return '>';
3 d( v0 D" K8 k' a& T) Z* N else0 s) T6 Q' h+ y) k; | x1 ^" C/ |6 I
return '>';
+ G0 ?. P* x- q2 z, o b* G- e* W case '#':- q. c$ ~2 k! m% l; v3 {# M
if(c=='+'||c=='-')
- |/ a% W6 [4 L9 z return '<';8 o8 i6 m( F8 E) i; T
else if(c=='*'||c=='/')
: o4 M: z! L6 b' r/ b! V return '<';4 c ^& \" A. U3 {2 e" Y; ], X
else if(c=='(')
; t% a' b7 H, a return '<';
5 z3 ~/ d0 x' D& ?4 b else if(c==')'), G) f0 C2 U# P. n; `2 @, ?
return 'E';
# h* f L7 x9 ]* t8 A' H' | else
0 q7 K* V- \9 N% f return '=';
$ q' [3 x4 N, _ default:
* y4 g5 U# {8 \' Q break;$ V7 i/ x4 T9 B7 ]: b) z
}5 d% m6 L( _! r2 O
return 0; 2 l" i" T. F+ {
}3 l9 M% v0 N6 k
# f& b+ Z \3 r6 K
int isOpr(char c)% w& B$ v2 o$ j- _8 ?1 j9 B& h
{+ Z3 v3 U3 q9 ~5 `$ h( a
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')7 i _4 Q( n$ ?1 v( t' Q8 y S
return 0;4 x0 Y- v' a, t: W$ i3 ]( ^0 [3 m
else 9 P4 K0 H w3 N( J& G7 e
return 1;( ?3 w |8 k. [7 C# q1 ]% d
}7 s7 I" r: P# z
3 V0 @. E) O3 ?( i/ w! r$ v- ]
float operate(float x, char opr, float y)
( P+ X5 K3 s* _; E9 u{& y4 R' C' S1 A) v# ^2 m# Q3 Z
float result;
, h9 O$ V" X# g( b switch (opr)
5 n1 ~/ Q( [' s9 @ {
# b. o$ W# u6 R! p8 M d" j case '+': ) v' f9 s7 B7 C) w( s+ q2 B2 w
result = x + y;
8 ^/ d! |" g, b' O5 c+ _7 m break;
* j7 m9 c$ p9 f8 t# z. }& A case '-':
0 c: `6 b0 M( i8 ~% v1 b. Q result = x - y;
) n. \$ L" `4 q$ G break;# X' G( M+ b. H( ]
case '*': 7 x. t) v- H2 G% ^1 T3 f. G5 o
result = x * y;9 k- x& y9 Z `6 f
break;9 z7 `8 t! T! U4 C( `9 J# q; a
case '/':
5 u+ T4 V6 `- Q3 e if (y == 0)
, W% Y: a$ O' E" T6 g; D. L {
3 a; y* p& c! q9 D printf("Divided by zero!\n");0 n3 |& U8 F9 `; x
return 0;3 A; I/ X) U- t& ?+ }2 ^
}
: ^# o4 `4 C8 e( w9 ]$ @ else: t, h9 |7 Q" t# n0 J8 _2 K
{
, X% r+ }8 J7 {7 }8 h+ z3 D result = x / y;9 Y g+ L$ U% R/ A v$ G: W
break;
$ ]( k) v, \! t4 \, }. R8 P3 v0 l }. z4 M: U9 s! J5 s6 P7 V
default:
% h d& n: W! v1 X1 f. L \( A printf("Bad Input.\n");
9 m( `: T H% @! n3 C return 0;- ?# F0 N; l% C! u. D
}
$ Z7 l) T1 Z) x return result;
/ A0 ] r! z. ?: o" \) m( v& J}
6 [1 q( v0 v, b
6 _/ j' C- L2 Yfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/1 `6 P: u* U+ b9 k6 R; X
{
S: ~0 y4 `" A& b3 ] Stack optr,opnd;
/ O! ~+ U8 j7 W: G- Z struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;; n4 O6 j" q& \$ F3 F/ @
char c;) l1 H0 `4 A- v
char buf[16];
0 n+ ], o8 Z+ N, M/ z% ]* c int i=0;
' N4 n6 `# q. P/ s# p
( P6 P; v% Y/ D3 p7 W InitStack(optr); /*用于寄存运算符*/
, r7 ~& W! }2 j8 p InitStack(opnd); /*用于寄存操作数和计算结果*/8 a0 c' e" |7 u- t. ~0 n& ]! _
memset(buf,0,sizeof(buf));
Y T/ C4 K' t4 ^7 j% ` & p j" V- r- L- `8 l
printf("Enter your expression:");$ S9 F8 D. L6 E8 ]
% @8 a+ u( b3 ^8 L opr_in.ch='#'; B4 d# `! Y8 M4 E# {! L' y2 X
Push(optr,opr_in); /*'#'入栈*/
7 f' s% }# ~) I s4 w9 R GetTop(optr,opr_top);0 I& F% c: I! Q- J, |: e" g
c=getchar();: w8 h& q9 A6 o2 G9 a9 }
while(c!='='||opr_top.ch!='#')
4 J6 V" Y: p" Z+ s: v {
0 u% ]" M6 t: S' C if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/4 s% \1 N4 `8 ^! D8 y4 U
{ R U/ G+ x8 X: ?6 v i0 o
buf=c;
0 E2 |6 T% v4 n) K) j S i++;0 s+ ^* {6 L& ~7 c3 ?
c=getchar();/ m% i3 E4 X- c9 I1 W# c
}
, V+ i1 I1 f: k6 Y8 P0 P else /*是运算符*/
5 L) x! m6 G$ Z, z. R7 u {
% [1 D3 S" n6 v3 _ buf='\0';& h9 a4 Q# c3 D* E3 |; z
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
8 `5 x& F- i9 A E& e9 o% ] {
; C1 n# p7 S/ D1 P opn_in.data=(float)atof(buf);
6 C' [' e1 x# A+ X0 ]2 V) w Push(opnd,opn_in);
4 g! I; P% e) P( s9 w. g9 m+ _ printf("opnd入栈:[%f]\n",opn_in.data);
- A2 J0 V& W( N$ m; d# {% ^7 a, k9 \- [ i=0;+ U3 P, G p1 S7 W0 o' P8 K! o) C
memset(buf,0,sizeof(buf));" l0 o7 }% |7 a
}, F: J8 o" {6 C9 I
opr_in.ch=c;5 T8 a2 {" b- r$ v
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
5 G3 f# D! `: t5 }: t7 r' x {4 M8 n& X: e" ]5 H5 c
case '<': /*优先级小于栈顶结点,则运算符入栈*/
0 Y9 ^3 ~( r) S) @6 c Push(optr,opr_in);# J" \: w% A+ R. O J$ ]. H7 @
printf("optr入栈:[%c]\n",opr_in.ch);
( A' G. \- [; M4 Z( D- f8 Q c=getchar();
0 M ^" M/ t* f) S% C break; T2 Q: W# g; |2 G5 F. u6 i' U" F
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
6 P* J# L5 e% |% s3 g$ n Pop(optr,e);
0 F- J* ~0 ]3 o, e* j2 B printf("optr出栈:去掉括号\n"); ^/ D) D; g( ?7 v8 [$ ?( s- r
c=getchar();4 A' C( Z: @/ f% Q( I' E
break;$ Q3 H. H d# v
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/: I. L7 K4 B9 m+ P' ^/ d1 {" v" p
Pop(optr,opr_t);
# f+ e* X9 a- A, e printf("optr出栈:[%c]\n",opr_t.ch);
+ ]1 ~- N0 C0 _: P4 `. e if(Pop(opnd,b)<0)& m! t; K" e# s+ z: K
{: W: C! m3 t9 V6 ^6 p0 K V
printf("Bad Input!\n");9 v3 U) K; ?, C6 F, M( @# m
fflush(stdin);
& Y) F1 k" C! D# ] return -1;
1 j7 \! p7 X- O; x4 u7 t }; J8 V) O& Q4 W& [# D
printf("opnd出栈:[%f]\n",b.data);- i( |0 k& u: O+ h2 u Y
if(Pop(opnd,a)<0)
: S+ S6 q9 A0 i. F {
. F) ^8 G- d( U4 n printf("Bad Input!\n");1 o; f# R7 e. K% P) a/ O( T
fflush(stdin);
+ m5 a7 H6 N# G return -1;- s- X8 ?0 I& z g! s( {
}
3 j+ R: ^8 C' M- M& } printf("opnd出栈:[%f]\n",a.data);
/ h4 V: h! C+ S6 b& j8 d opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
- ]2 x' u" R( C* q! B Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
8 l5 J4 `* x3 a printf("结果入栈:[%f]\n",opn_tmp.data);
4 F6 `" F" Q2 a; T/ c n break;
* p5 X* |+ E6 k& \/ I- K- G }1 j2 p! A4 T1 s$ S
}
. g# K% D; z/ E, o) [$ i2 \ GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ + t9 x* s, A" h3 k/ t- ~5 I6 t, R
}
0 V$ i- g$ t K$ I GetTop(opnd,opn_tmp);' ]4 k/ j- G# O- ?
DestroyStack(optr);
0 m) ~2 W7 }; l7 f" ~ DestroyStack(opnd);4 n Y$ A0 o2 }7 J, K9 k4 w" a9 e
return opn_tmp.data;- `" a' i/ |" c% f
}
% O3 c! X! [% y' O; L
9 R% I- ~& z. O! x( Ichar *killzero(char *res,float result)" \, Y) x; n3 P3 Q2 h. y) o
{0 M$ e4 t* l. C, w) u* [
int i;9 H- c+ R0 ?) l% |5 h$ X
" \. b0 e- e( s6 ?
sprintf(res,"%f",result);
: d/ ?" `8 O9 ` i=(int)strlen(res)-1;
# O8 |! p, L( S: [5 H2 Y4 v while(i&&res=='0')
6 r5 L3 \- e3 {2 i7 Q {0 \1 g% h ^4 {& M6 a' [: i; k- A
res='\0';5 x7 r6 P4 _" X1 \# D3 j; H! J
i--;" {3 m3 _) H) _
}
% f3 V8 S0 K r9 g( r if(res=='.')
/ y f# {) r- n8 Y. i4 D res='\0';( c% v6 I& h: J$ c0 ~$ J4 _* C1 v! W) Q
return res;
* s, y3 \/ { ^2 j i}
; }2 ?9 m6 Q5 B' H; @
$ W" f8 m# v; ]$ m/ Gint main()0 G9 A9 e( {- ]0 Q0 A, F, \
{
, h. t# L; w, J3 ?- w+ X d0 _6 K char ch;9 |, G! N3 F0 F: {& ~
char res[64];9 X5 X. i9 c- }
float result;; q# C0 `( d" U& S! c( h5 b
while(1)
' s+ E- z# Q- q, v {
- a; X' y% v9 D5 |: S' B. K- `' @ result=compute();+ F0 A4 ~: y+ T; n5 j! b* j# S1 y& V
printf("\nThe result is:%s\n",killzero(res,result));
4 `8 R- O/ e4 {2 m5 w5 O printf("Do you want to continue(y/n)?:") ; n Q+ q! `$ @8 k
ch=getch();0 k9 y! i% |& P8 M! I
putchar(ch);2 \3 A {. z% W0 [
if(ch=='n'||ch=='N')
$ R$ A+ s' p5 t( o break;
7 |, V! o* O" u" [ else
2 g6 n" v" E3 S5 B9 F0 s6 @ system("cls");
# @, j) a. }, t8 b* R }
' }* p3 e! D& {6 k return 0;4 `8 ?! H* V2 }- P
}
a7 o( |% s$ ?3 J+ {( e; u v. ^3 h) A
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|