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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.5 m8 v" F: o8 [/ X# h* G
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=' j4 C, d5 B, B* ~+ j1 F
/**************表达式计算器************/
1 R. |4 ~6 b0 B7 s#include <stdio.h>
' M) b. M( ]+ o1 W4 X#include <stdlib.h>- R2 U' Q% P" Q
#include <string.h>/ z. M0 y6 C% P8 N4 |
#include <conio.h>9 W5 C7 e) {3 _3 |/ L8 \
#include <malloc.h>
! K _/ g5 U$ |' U& d% m( M
1 Z1 h$ n- y/ G d' l#define STACK_SIZE 100
' Z& F3 c& C4 V) R7 |9 P#define APPEND_SIZE 10, N- p/ ?+ x3 w0 m, v6 d$ a
$ M8 C0 {1 Y+ E4 F: }. Y3 ?struct SNode{
$ D1 a- V. k* I& h float data; /*存放操作数或者计算结果*/) [3 Z1 a Z) w# W C5 h
char ch; /*存放运算符*/* A6 h$ ~( Y- Z' {' Q# D& S
};9 `* \ h/ Q9 _$ {; X
) P7 b ~* `; A6 w9 v, Cstruct Stack{4 I& ^" h- K# {. v3 Z4 D+ r
SNode *top;
1 C' B( B7 B3 r) }3 |* k- B SNode *base;
6 `1 M0 W3 L' L; f3 s+ @ int size;
3 E0 j C# Z3 T5 M$ c: {};
, E* n2 N" _+ l
. _4 _9 W$ g2 b1 g q/*栈操作函数*/3 Y1 {: p- A+ E9 \- n# c
int InitStack(Stack &S); /*创建栈*/
- w2 \. ~0 r& V' v+ ]( |int DestroyStack(Stack &S); /*销毁栈*/( y0 [' ]" ]) T
int ClearStack(Stack &S); /*清空栈*/
3 G- z, d! M4 u, H- z5 u1 dint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/7 e% S+ E( v7 O$ V* V
int Push(Stack &S,SNode e); /*将结点e压入栈*/
( l* f. U" O7 f2 _5 O% Hint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/) b! y9 |% m) T2 u" B
3 k) \+ L/ B4 K2 s" O, x/*表达式计算器相关函数*/
* e) Z% u f( _9 ~, Zchar get_precede(char s,char c); /*判断运算符s和c的优先级*/ z# O! r% t9 i6 z4 J1 ~" x
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/) y/ h6 |+ y; k7 Z+ Q- ~# k8 {
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/6 U( k; y9 Q" i9 A/ q. @
float compute(); /*表达式结算器主函数*/3 Y2 B7 _! A; y2 [
char *killzero(float result); /*去掉结果后面的0*/ ! ]: n: U7 b+ l. P) V, q2 Y
, P& i w: ?$ D& d( Vint InitStack(Stack &S)
+ p. j2 j; d0 V* g{
* H8 O9 J0 ^1 X) n8 c S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
; u ~1 W+ |8 W if(S.base==NULL); A6 {4 R, A4 E r( x. i! z `
{
& e, }& x+ ^0 H# P. c2 |2 O, [ printf("动态分配内存失败!");
+ [! @9 ?: U& r7 a0 x" \, ? return -1;
4 X/ g' Q) p5 Y8 {3 b. W6 B6 |" ? }6 g( }" [9 t, \7 S( m
S.top=S.base;
" o( J4 S, s; O0 {% I# R S.size=STACK_SIZE;
/ n! u9 ]8 y- d, f3 `; K7 | return 0;, F7 `! d. u* x" y
}) ^6 w9 T# ]0 H% a4 E# W" x3 x
9 b" Z( O X1 r5 s
int DestroyStack(Stack &S)
/ s! n$ I- P8 l: E* E' Z4 t3 V; S{
, l* m" V' t ] p free(S.base);
: B. N% w6 i2 d9 G return 0; l; X. s0 T+ p% p$ V; F
}; _" d/ T9 d2 s5 R7 R w1 h
* j( }/ [3 _4 a7 _int ClearStack(Stack &S)
# M# F+ \0 j9 W7 R{
, l% Q9 H' M0 ~0 @ S.top=S.base;
: t2 O4 t/ K' D; i& Q2 G5 K return 0;3 @2 B: A$ t' N8 J* ]
}6 F, Z1 p# U# a; U- E" j
- T2 c* |9 h. j; z) ]int GetTop(Stack S,SNode &e)" c; w1 j5 n, D1 k& h% M( B6 m
{% {( @5 R1 q) b3 \$ n
if(S.top==S.base)- z% V8 L) N, H( I0 J' S4 k! _& l+ i
{
# n9 B5 T5 Q, F2 Y printf("栈以为空!");7 u$ `* r3 a9 [; o7 t
return -1;
2 c6 `( O4 w) e; O6 o }( z% F: v# s) C4 f& w) U; r
e=*(S.top-1);
* z; v# l7 L/ K5 g) g3 m$ z- y) S return 0;
7 ^3 }9 Y8 f( p8 y y2 U, }}
& O, o+ Z; W7 z$ o7 K8 D0 H4 r$ w) ]* u
int Push(Stack &S,SNode e)* ]. n$ F' x0 b9 V$ P. S, w8 e
{4 A# [" P: ^2 U& J9 P- z1 Z
if(S.top-S.base>=S.size)
' [* j6 v9 F* F2 a* q9 a- v: z. r {; W) }( s, l' ? m; y8 V+ |
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));2 C# w; m8 X# T4 V& {: k# \) F
if(S.base==NULL)
, Q4 r7 {- X& T* B' @, O {) e4 M3 g) I+ ] C. y
printf("动态分配内存失败!");8 r! p4 ^& O: y) \: j1 K
return -1;
+ b9 [+ ?, o3 s }& v. ]9 b& [9 E0 w2 g
S.top=S.base+S.size;
. B( Z" c9 H+ `, d& ?9 X. S S.size+=APPEND_SIZE;
7 z8 f4 C+ ^# m- f$ | }# P0 `# @! k: K; M3 D
*S.top=e;5 n4 L$ X! b) |- u
S.top++;
% D. g) G& U; I/ i9 J; [! o return 0;
5 Z" W2 T! g' x0 n}
$ E! V3 U( t8 H( ~$ ]* y
0 [. z& o4 |$ I: X. Uint Pop(Stack &S,SNode &e); V) v. g3 B, q. R
{
+ ?/ \- ?, e3 f% C9 L if(S.top==S.base)
* F. w6 E/ ^, R$ r {
, g' d6 R: ^6 i9 p/ c4 n printf("栈为空!");; X+ M$ l& c' \% ?/ G! b
return -1;9 f% x. T3 f4 h: K
}* R7 \" L- Y! g! {/ r6 J, ]9 }
e=*(S.top-1);
X6 _4 S8 x3 H# H/ N- u S.top--;' w- q1 Q9 ^: g, V( S3 j* x, {
return 0;5 `& q# u8 m9 J$ ^9 y1 J
}
' ^$ K( m L% C; ]/ u* h+ G( l2 X0 b2 h2 F9 Y7 m; |
char get_precede(char s,char c)
( B( f# _! D- V- V- d! m{
; S* ?9 Z; x0 ?5 n switch(s)5 W/ R5 Q. P' P, b5 R+ O8 c& `
{2 T+ v% r5 [2 O1 H w3 n
case '+': 9 c1 |1 f! W) Q ~7 r
case '-':
7 @9 w# J7 W' ` if(c=='+'||c=='-')
0 f, o4 a& ?6 z return '>';
& Y C# A! }2 A6 P else if(c=='*'||c=='/')
) {. I# c( ^. A return '<';
3 o( d. M: T, m, e else if(c=='(')
. R7 g, @4 H1 E7 D6 z) O, z return '<';7 d5 j9 H- X9 E8 q3 Z4 v) F: m; b
else if(c==')')8 p- E/ p& A- J7 S \
return '>';
2 X* [9 Z9 ^' d else
( z( I4 F4 Q) M3 F: a& V return '>';2 e! B9 ~5 y) M z
case '*':( c7 x& x& _, [( r# h, Q7 O
case '/':
, [/ b# U+ ?6 m; `" Z6 v if(c=='+'||c=='-')
+ Q$ o" H7 i# M6 s7 C. H3 l return '>';
; h! I9 A% y' C6 P0 R" x else if(c=='*'||c=='/')/ a" Q( c( W% Z9 f9 ? C3 C; G3 t
return '>';8 n8 ], t5 `6 Q" c0 h! _. I
else if(c=='(')" m. P! b5 T- z& e
return '<';
+ M$ F; Z- B7 N& R$ U, E- F) \ else if(c==')')
' ?; A+ o1 i w; ~ j @# }$ B return '>';2 P. R/ N8 o; E
else8 {# O) S. p! M7 g
return '>';
a; R' n$ i, h case '(':
2 n2 m) l. u( p$ [1 q% q( G$ W& j if(c=='+'||c=='-')
! H4 P9 i! W2 Q! E+ x return '<';0 Y! A+ l0 j x; q/ v
else if(c=='*'||c=='/')6 {* s4 ^- V x2 Y* ?/ f
return '<';7 F7 s6 K W4 |0 A: H' c7 Z0 Z! w
else if(c=='(')9 q# e- T3 @5 d2 i, U; H
return '<';
d d" E A/ j else if(c==')')
" T0 a5 C: \ J4 o' A. m, x return '=';0 W: F D# ?7 W3 j0 @9 q) j
else
. g( p7 Q+ \9 E5 M" w return 'E';
; |( w2 }% [+ y* @/ G case ')':* V! G; a! ]) E+ e/ J/ F" N
if(c=='+'||c=='-')
( i- t) ~' r2 F* A return '>';: L) `9 m: }; E! J- n- B
else if(c=='*'||c=='/')
9 @$ O; Z/ D2 w1 w return '>';# b7 E2 H/ R8 ^2 Q% [' Z
else if(c=='(')' }* |4 ^. e: ]5 n
return 'E';
$ j% j& `# A/ V! y/ v/ ^ else if(c==')')
, G* y) y- x0 c3 Z4 b5 Z/ l" @ return '>';
2 {; Y0 ~* ]0 \# h, y9 a m else/ }* P# r8 O/ \+ c( q* g
return '>';2 T6 z/ v0 I' e% \% v- J* Y/ n
case '#':/ V6 E% m; }- n) y
if(c=='+'||c=='-')
. v Z g. `* h7 \, g" r2 ` return '<';% q% p( q2 R: }8 @3 Y' r: p
else if(c=='*'||c=='/')
; t! e, q* j& L- G$ o+ R return '<';
- F! [/ Y: X ]4 ]: ~ else if(c=='(')+ z" Z5 e0 H! w- W7 S) A& U' {: T
return '<';& g) g7 e7 }4 K; |6 f
else if(c==')')
. i$ A$ f! P: A3 t! R4 q return 'E';: M' F( z) {! @, F& Y4 k
else
, B2 i5 k* F0 j0 U! G return '=';" w4 e# d8 @+ s# r4 e
default:1 L* B% v$ {8 ?$ @" R0 n# b
break;
5 X2 K1 n. Y! p7 k }% ^5 w9 \& R5 r. F
return 0;
! D/ o. o( k1 k5 a- z v6 |}
/ [9 \( V* ~# }0 @7 _0 M) i! @0 M' \
int isOpr(char c)2 ^! d$ |$ n3 @
{
3 R- }$ w: d# L# L) l" I6 d if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
7 r2 ~9 @& g v c return 0;. G6 q6 m; u. t0 }1 ]: _6 K, j6 L, f
else
/ v: o0 h" w6 h) V& t Q return 1;
0 e- S9 P* t& A# F5 ^& v0 [}
3 \* g6 a( Y! L8 t1 N& ?
4 [- U/ x* W, G/ jfloat operate(float x, char opr, float y)
8 d4 l. J! n: h+ F3 S. R{
7 K; H2 ^! ]; B) @ float result;
6 Q8 O9 h- U( y2 r9 C switch (opr)
* C" C2 T4 ?, N {
: k' \8 k4 K- D/ t4 r5 p" M d! d case '+': % S. K5 t( P5 c$ a
result = x + y;9 S" ]$ l2 E6 k1 m
break;
* u8 K! ~ N% z. l case '-': + S7 _* P4 Z( ]$ ^4 ]9 }# d3 s
result = x - y;6 P9 C3 ]4 x# B- O3 q
break;$ Z5 G! u) }$ l6 U+ d9 h6 i" O* X
case '*':
9 ?) x* U2 d% G# p result = x * y;
& ?! ]% X/ D+ V8 w7 k0 g9 f" C. a break;% A6 l- b( e g0 n1 h
case '/':
& H" r7 l9 m& k+ ]6 H if (y == 0)
, y' d7 h# j2 N4 N! N {, G: W0 L$ `7 v! y
printf("Divided by zero!\n");
) h( x3 t% X' y return 0;7 S5 A) n) T/ c X. C! Y
}: K( G+ [0 \+ y J
else' [- [4 i+ N4 t3 r
{
4 `, c3 [% g1 l- h. `0 } result = x / y;- w0 x6 E& W) B4 a9 ]
break;
8 {5 V' [" j+ l# i! Y0 Z* \$ X }
4 K# ]& `/ L2 J# \ _& k8 T6 T default: + B, Y" w1 f/ O# A8 k3 p" J2 x- f. V
printf("Bad Input.\n");
8 W6 ~9 N/ h- `1 ^8 r3 z return 0;
9 T r$ {. z) A }# L5 n- F% A% a: f$ S0 T
return result;
6 I+ r0 s6 M6 U8 D5 B3 \7 V} 7 `/ n$ g! j& v, O5 D
6 E/ C3 [; L1 U3 `8 Afloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/9 J, } b0 R) j8 S$ j' B7 D' ^& \; z
{; ?" p' J- E$ F2 @/ S
Stack optr,opnd;
9 y% ^& h( o; u# A6 P$ } struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
, ^3 ]& p" k# S$ e* ?% j char c;
$ E7 X! b9 F- x3 q& { char buf[16];
7 L8 l0 c D* E' ^4 Z% c1 g int i=0;
2 L1 q: t3 s/ c [1 C
+ k6 a. k8 I) y1 Z! g InitStack(optr); /*用于寄存运算符*/4 X( ]2 }: r0 |
InitStack(opnd); /*用于寄存操作数和计算结果*/$ x1 n5 _' P2 j& J
memset(buf,0,sizeof(buf));0 ]" `/ ^2 d% @$ b! I# t
. s7 W" P3 \% i! D! c* j, V; V printf("Enter your expression:");
+ ]$ H7 {! |5 ` / p/ q3 L/ V+ R* A/ Q
opr_in.ch='#';
+ X, i5 ^; M i" v Push(optr,opr_in); /*'#'入栈*/' o5 I8 E2 I% U" _
GetTop(optr,opr_top);4 u( g1 \: [) H0 K$ W: C
c=getchar();7 O8 J& z9 F+ x O
while(c!='='||opr_top.ch!='#')0 X# y: b* p8 ?( m" b+ O
{4 r/ a0 [7 L, Z7 s$ {
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
# X; p1 N0 {: V, ^- C5 N; c {- N2 ?/ M& i7 z( `5 J7 ~& d
buf=c;0 b% R* b+ i* s* c( @
i++;1 b: T E& u% K( `, h
c=getchar();6 `) |8 K6 x$ @% {. n" f
}
: k% P2 R5 [5 Q. M' a* t I# w else /*是运算符*/7 p/ I4 t5 {' q; w! L
{) @% c% n$ G/ u# x/ K# u) s( Z# J
buf='\0';
) L' ?: o# n W, ]% i+ x( s if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/- B- I. O2 ^$ `" {2 @/ e5 j
{
. o0 ?# a u2 P) @1 e4 U; Q5 o0 J opn_in.data=(float)atof(buf);
' V9 g- A" J$ T0 t Push(opnd,opn_in);1 R7 Z& J' b+ Y U3 g% V" Y o
printf("opnd入栈:[%f]\n",opn_in.data);6 k; y4 X! n& V* S, E" Q! \2 E
i=0;2 c, d( o$ X- J
memset(buf,0,sizeof(buf));0 ~9 K3 N C6 G5 {
}
- c! N& Q7 l# F& p3 w8 D1 V' Y opr_in.ch=c;
! y. f+ L! m! Z; W switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
- r: I( o% W: j7 C; ~$ h) r( y5 P {
( y9 P8 J1 g9 ]6 _5 R3 [+ A8 c# F case '<': /*优先级小于栈顶结点,则运算符入栈*/
7 x; T9 E* W/ l9 W# T Push(optr,opr_in);
5 K) ~; ~8 F3 E+ J. j# U/ W8 w+ x) l printf("optr入栈:[%c]\n",opr_in.ch);) p+ ~6 E' b6 n$ p2 t D
c=getchar();% q' }! Y0 z& ?* h
break;
8 g9 X, G+ L2 p& I- z. c# h case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/1 k5 l, z( Q7 [- b! k* K
Pop(optr,e);
5 R3 A4 _+ X8 E printf("optr出栈:去掉括号\n");0 G% m6 I! f0 T/ }
c=getchar();
! m2 u/ Y. w! ^2 g# |' K* H, N break;
- ]! H' v' ?( \ case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
; O# L q! K2 t2 |% @9 r0 S Pop(optr,opr_t);( _# k% R9 R( y8 {
printf("optr出栈:[%c]\n",opr_t.ch);
; E0 }+ L- T4 F- [: ~. p, P if(Pop(opnd,b)<0)
9 v9 N3 g) S# \% h {5 V3 T$ I- ^# D v/ ~) x4 Q
printf("Bad Input!\n");, i% u' r. P( t8 |9 X# O
fflush(stdin);
8 N9 T: J; c" ?2 n2 R. @" F return -1;
; ?& `5 K. h6 T3 |- p }2 o* H% m- V( _
printf("opnd出栈:[%f]\n",b.data);
! m4 e" Z6 j* j7 m) \% F if(Pop(opnd,a)<0)
9 r# ?; M4 l# _ {
$ I2 I5 P9 @+ D* G* l printf("Bad Input!\n");
- P2 d2 Y- M7 f. l, V4 r: s I fflush(stdin);
! [5 _# T$ u( J$ w* G return -1;2 F/ d5 n! \* y) x1 n1 @9 C6 m. y' E
}
6 ^* y/ G q" K printf("opnd出栈:[%f]\n",a.data);
) n" _4 `+ y- r0 k- _4 K opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
% _0 o; O9 S! c+ | Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/: H) j, o) i% K$ ?: S( b5 D
printf("结果入栈:[%f]\n",opn_tmp.data);
+ @2 K' h" u* c$ M/ K1 ~ break;' n- c) J S9 M
}
) q9 T+ f) f! f- d0 m2 X4 p# [( L }
" F' ?$ b$ O: N" y+ ?& _9 c; w+ p) p GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
F8 \! F2 w/ N- n# }# [9 M }
. M$ H" i3 M- o4 f, n GetTop(opnd,opn_tmp);5 \2 y; Z3 _: T8 B" [
DestroyStack(optr);9 t. P# @7 V9 u5 n
DestroyStack(opnd);
7 n8 n; |1 A- {) }& g7 b return opn_tmp.data;
, D. E1 x L' h/ K' h; p}' [& K+ @( u' t! m( `9 `
3 {+ V+ v- O: ]
char *killzero(char *res,float result)
5 b, W1 a' N% K! e{
W( b! p" F7 J% K3 }! } int i;4 N r7 q, M- w5 I/ V3 ]# v
4 u+ Z7 ~* `+ H/ Y+ @9 S# E
sprintf(res,"%f",result);+ s& E7 X; v9 b- S. f, n, _
i=(int)strlen(res)-1;$ [8 C1 R& ]! j# i( P4 o6 X& w
while(i&&res=='0')+ ^. R% f3 X' O, s( s8 I
{& i% H" i" J' s6 ]8 S/ l: N
res='\0';
) A+ @! x9 T1 D) s0 ]& i/ q4 B4 P i--;# v' ]3 O( a: ~: \
}
$ C! i/ l H! `% n if(res=='.')7 Z+ ]1 j- _6 f/ [
res='\0';' R6 m! r$ D; C* [' |) f0 G5 N
return res;8 a2 b5 u/ A* M1 Y8 @
}
, U6 ?5 I% E) j ^ G) P, G; U B2 \$ W7 `9 n" D" n
int main()& a6 B6 h, c- L& b+ j; b
{
' D" |: P8 k: s1 R& L2 S$ r char ch;
+ L- m0 j9 f1 `& h char res[64];( `4 M- E% D% H" P
float result;
4 v* K% O( Y, F. k9 M while(1)" p, x5 n9 W, w; y4 Z
{
5 V. q" r4 F6 V( C E result=compute();
8 T# o( ^8 F6 s printf("\nThe result is:%s\n",killzero(res,result));. ~. q2 w5 A! T* h7 M
printf("Do you want to continue(y/n)?:") ;
- F9 I: C9 \$ u9 x9 z% Z ch=getch();
5 G4 R( g; b6 Z R, |' u% ^; s putchar(ch);+ R, y- F7 v3 |! Y" n+ o! C# k1 q$ i
if(ch=='n'||ch=='N')9 D1 X5 {* O/ D z
break;8 I- m+ k8 `* |( i, F0 d: V9 T
else* G9 r4 a3 w3 d9 _- a) X
system("cls");# V0 {6 [9 G% S( j4 s8 R
}
) l2 w" i2 ^" I+ R return 0;% X* G1 J2 E+ P0 X
}
8 z B. a4 f& U! [# o: i. j0 `0 Y- Y% K: Y3 ?
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|