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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
9 N: M/ r$ y6 y2 V; T0 Y程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
# W& ?3 Z8 m3 }2 Z6 I7 ~* Y2 p/**************表达式计算器************/
- u# X/ d; [9 C' L0 }: r. A#include <stdio.h>3 y2 {0 u! h, H- g
#include <stdlib.h>
( c+ ^. c4 x8 p#include <string.h>8 F) B! z1 Y+ S8 I' C
#include <conio.h>: h* b( n7 \" ^9 H2 S' U0 c1 F
#include <malloc.h>
8 y# P, }8 I, H& G4 T+ d/ d) `9 I& }2 l4 ]. I7 |# L) D2 S7 c
#define STACK_SIZE 100# V9 \, L }2 [1 j( W% b5 V; j- e
#define APPEND_SIZE 107 v0 O* Z6 Q, E1 M5 M
; W* j+ w+ }! L1 }, H: c
struct SNode{) u7 ^: X' @' j' C6 g* s+ k
float data; /*存放操作数或者计算结果*/
, F7 s( H, }! E! K9 H7 Y% U4 I+ |" F char ch; /*存放运算符*/
3 I' j' z3 i, h I# S1 k};) z, F8 ?3 T- w5 y# l2 v
8 r: s- Z9 P' A$ o1 @. K
struct Stack{
) d: n" y1 V# A6 w SNode *top;' ~# D' e- e( {* |
SNode *base;
; n4 t$ W a/ O/ G* r int size;, X+ t% m2 G/ e
};/ T0 l$ N& l0 _
% a" r" w( j4 Q4 ` }- i' u; S
/*栈操作函数*/
" `$ n! Q7 S# G0 Q: l5 Wint InitStack(Stack &S); /*创建栈*/
1 r. e, U/ W% m' J" e9 hint DestroyStack(Stack &S); /*销毁栈*/7 k0 `: v) ? `! m- A
int ClearStack(Stack &S); /*清空栈*/# A" x* y- o A8 u4 Y. p
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/8 G3 y4 d; ^. |3 e' [6 b
int Push(Stack &S,SNode e); /*将结点e压入栈*/
0 _8 e, Q0 J& c" ]2 E! D( iint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
6 t& F9 ^7 {) H, F( ^# a6 }" Y& B) p! {7 s: w
/*表达式计算器相关函数*/
& N) P# Q5 W7 _( Q4 G5 H% Ychar get_precede(char s,char c); /*判断运算符s和c的优先级*/* }5 p- T5 C( v: l) H# U$ i
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
5 Y1 c! V, p4 z" W8 ?float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
1 C8 Y& C" ?6 o8 V$ Sfloat compute(); /*表达式结算器主函数*/
: U2 n4 y- e j3 cchar *killzero(float result); /*去掉结果后面的0*/
! D+ b+ s, p0 l
: @ i) I1 ?$ V/ yint InitStack(Stack &S)
/ F- J9 ~1 d# D. [{- m. y j- G0 P# p
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
2 J$ [( k" e" D if(S.base==NULL)
" I5 o/ I9 D. \& f8 J# Q8 q' R {: x5 g9 d% ~& m' e
printf("动态分配内存失败!");
1 w* V' Q' m: `6 R# n( t return -1;" c- V, N C3 l2 [
}
* x5 ~' W% v: Y; T& c+ O$ z; o, S& d S.top=S.base;
+ A" w4 v; W, H7 n5 i/ W S.size=STACK_SIZE;) M+ H$ E' A( E' S0 O; c4 f
return 0;
/ k# }5 C; q5 d4 @& \! v( U}5 b ], a" o( p
3 `" ? F( a' }) z( Vint DestroyStack(Stack &S)$ U2 N4 M# J. D. \, t$ f
{
1 Q" A7 ?6 z1 Z. e' e9 L& Z( x free(S.base);7 b% |- B: a3 u, a# T$ D
return 0;
6 C0 X9 }4 z: o$ e l$ j! d$ r}$ ?- u8 R2 e4 u: H5 h# D
! M6 N% T" F0 B, D4 }# ^
int ClearStack(Stack &S)
$ @% t6 U2 n9 _{
9 L1 o7 c( `+ U S.top=S.base;
L, G1 Y- h* R8 V1 }- Y return 0;7 F' z4 ~* b# E) I( y
}/ u3 B w% E7 N/ y$ C" J8 U
( {/ o; Z: ^$ M" m; z( g# X
int GetTop(Stack S,SNode &e)
! O% U4 k/ a# Z4 z- s, H" |{* O- G2 \4 e$ l( O& C) t( K
if(S.top==S.base)# [0 u* X- U# o! W
{. [& _; C! o6 c u. T4 [1 Q
printf("栈以为空!");! G! L' ?- ^- N( b
return -1;
2 H% f. d! m7 v" N& a }
: P) R) F" Z( L/ y$ G e=*(S.top-1);
3 `/ b9 E& ?- x% G0 L5 A/ t return 0;
! `* Q/ q2 F& J; }; l}/ f; p K- C% S2 J: s; [
6 W# F- x" P. U+ n- i
int Push(Stack &S,SNode e)3 x7 C1 x( k& ]& ?: Y" U) s
{
9 n- A1 w, O8 {/ W/ z! H if(S.top-S.base>=S.size)( F& K2 ~; J- `6 j4 Z6 f
{
( h4 ?2 D) H1 N1 p9 @ S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));% |) X2 s0 j% m
if(S.base==NULL)1 F8 a" s# i' s3 b& ]
{9 c+ a3 E5 G+ _4 E4 x
printf("动态分配内存失败!");, l# I7 X" g( S7 s6 ^/ O8 A
return -1;# X5 h" Q* p% L9 z+ c
}
& t" v$ }' W6 x8 C. J S.top=S.base+S.size;0 X) a* a- D, u$ T
S.size+=APPEND_SIZE;
( k& A1 Q( v; d# {6 b, _& k }
+ M* X7 L% U7 `' l9 J *S.top=e;) D1 |* R1 Q1 S
S.top++;" h% s5 P) ^% I* `" z; X3 H
return 0;
: \- i% f$ f, F, X3 q: B}9 z3 D0 y- h( F, K* m
|) a" t2 p* i; Xint Pop(Stack &S,SNode &e)
% r* ]* p t2 J V* {, T& x{, k3 q T* U/ M0 r6 [
if(S.top==S.base)
" ]/ c; O7 q* I0 h {
* W- o# a5 s; ?, o printf("栈为空!");$ J0 L# l1 h& R* e# Z6 h
return -1;
) C( [) E+ F- F6 ~: g* u }
% ^: k2 L+ r' k e=*(S.top-1);
% I' U; L) _% R w- f S.top--;
% e& K( ` ?' L4 U [ return 0;' Q) u. q4 f! C* g3 T( [1 r* v9 X5 t
}: k/ D& ?( g- j
5 P2 Q8 D$ M' I$ G, A4 dchar get_precede(char s,char c)3 c: r4 ]: n8 }* z( k
{ d. ?$ f- o" ]! c$ I7 ]! C" P
switch(s)
: J! e! Q& B# G: X {( f% ?/ a; H1 W( K" V$ t
case '+':
; A! q$ M9 _4 e case '-':( v7 U/ W: b) }! W @# P+ D: Z
if(c=='+'||c=='-')- X/ W0 d. @5 O! S a V O
return '>';
6 c$ J! Z" Q8 x `7 l+ O else if(c=='*'||c=='/')1 j) N: v0 \/ s$ l( P! v# n
return '<';
; U+ B( b: ?2 R9 V- Q else if(c=='(')- Y& y/ P" @) W2 F9 h: ?9 A
return '<';* s/ k A! c% I
else if(c==')')
0 o: x& s3 d# O$ E return '>';
4 n" f. K D; t0 D# O. h else 3 j3 j: v. d6 c5 s: n4 r
return '>';" X+ L' Y. d, D U% j% w
case '*':9 N' L) f i& y3 n
case '/':
& Q( U4 F) R' ^) W: K6 @2 A if(c=='+'||c=='-')
+ I' M3 E; E9 ~( ?# v return '>';# p. h. c+ x. d" s% W6 y
else if(c=='*'||c=='/')
q3 ?# b$ I4 h$ J return '>';3 `$ d; {3 W Z( r; F
else if(c=='(')
1 }8 s2 D0 _! b: ]! c return '<';( z0 B& @2 C- z7 p- }
else if(c==')')9 P# \* P: j: S2 K
return '>';
( Z J0 p) w e* y else
/ i. _9 m2 T+ u& h% ?& ]/ G3 S$ H+ j return '>';
- H& C. |/ a* V) n5 b3 R case '(':
5 H, i# @3 y4 U if(c=='+'||c=='-')9 S+ Z0 g# a; ]0 T) U6 F
return '<';$ V& y; z; V7 a
else if(c=='*'||c=='/')6 B7 ]* }' t- O/ j5 z4 l2 S; U
return '<';
; e `* R$ r, J m5 X) z else if(c=='(')
+ A+ d8 A! F8 J' V9 F+ k9 o return '<';8 K: E! V$ Z! r# d9 g3 s
else if(c==')')
( M# |+ f4 A' [' S return '=';2 P5 y3 O+ \3 l, L& Y! W% u
else
+ x; d. K6 X0 G- }- Q6 ?/ n C3 @ return 'E';4 ?3 @+ `7 `) ]/ {; X
case ')':
# L. I. V) N/ w J) A1 _+ h- W if(c=='+'||c=='-'), a, |3 {2 ]7 M! L5 ~2 Z% `; I
return '>';# s) ]4 Z! u6 }+ N* P& m; ~' q
else if(c=='*'||c=='/')5 {- H7 Z# q( \& z4 Z
return '>';$ q$ [) @% \" Y- S _" T1 w
else if(c=='(')
% f0 t/ W: G1 v: s& e4 I! s return 'E';$ i- I$ O2 ]' G! J* ?+ g7 x
else if(c==')')
& q. b. v- l* `2 @ return '>';
1 Z+ L* M1 W- z9 K else% R \6 @3 E! f* c
return '>';+ }1 e2 ]1 g0 j% D
case '#':
( v2 K5 F3 C6 P5 f! K4 U5 w if(c=='+'||c=='-')
4 A% ~" ~+ R0 w- Z2 A/ A return '<';/ t1 X* ]( U) o/ @6 u
else if(c=='*'||c=='/')
C/ Z. C) P4 Q& V: r8 ~+ ]! m return '<';
+ S( V- o& p+ Q! L else if(c=='(')& @- H. {: g, B6 X. K: V
return '<';, t/ W* h' F: }
else if(c==')')
* I& g8 c. I! C3 Q& Q6 M3 K& C: W return 'E';
. x. a" @) c1 l( z* s- \ else% {. p( ~6 s+ f
return '=';7 m0 x" y) S3 U9 w$ v
default:: P% C [ N& Z; p6 A
break;# d/ W. G/ l/ }( k
}0 t% J8 {! V. p3 G& b5 F
return 0;
2 h4 N+ ]* q; S0 |; q4 F0 G7 w}
0 }3 V0 `* f G$ i
6 N1 }% t0 J# D7 S4 |8 a' m; _int isOpr(char c)
; d3 O: F, F; J{
' c# Z6 p" K- k8 g" V" X if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
t. |3 A" j2 M( B/ b2 B return 0;
6 H9 ~# X3 y$ | else
8 P' F+ {8 Q2 x return 1;
* n) F+ ?; s9 n9 O W}! ]3 T% c6 K5 ~2 ?
3 @0 k& C" P" ~
float operate(float x, char opr, float y)
* D" A6 `* r6 a* E7 N b. R0 h{' r U9 ^; i; ~3 E k7 I1 f
float result;% T( E, ~7 E) m: b! Z1 }
switch (opr)
& H& M/ ^0 \/ T# Z- E2 ^ {) N) i- ~- S3 L# @8 q
case '+':
7 s6 l. Y6 L6 Q result = x + y;
6 D0 d+ n/ N) @$ b0 R" R. R6 o break;0 B* d3 V1 g( T2 o6 L( E
case '-': 8 T( T- ~8 S3 } j% d$ N5 @- w
result = x - y;- m% d! G2 i) z2 _# F- H
break;7 p: ^! H5 x" z, ^5 r
case '*': / h) C# i1 t! h9 i7 g
result = x * y;5 |8 m( x4 k e" o. i4 T9 r7 G
break;
) B: C. \! K# b! d/ F+ d3 ~ case '/': ) W7 q7 C8 D; I: R8 B: P; [
if (y == 0)0 [( b5 h( T1 \; l
{0 V9 J# `+ E7 b1 k4 J$ }( l2 T- [ T
printf("Divided by zero!\n");4 a. a% X1 O' ? T. B" z4 R
return 0;: C c" }0 g3 T: k
} i* \, X7 J3 i( p+ t# w" D
else! R/ [! @" L; _4 l' t3 P6 {
{
2 ~7 b( t1 @2 ?; N6 O$ B( W+ [ result = x / y;
" N3 P" z% r2 A( b: p6 c break;3 r& v* r3 C# c2 d4 h3 Z: K Z
}; k$ S9 U) F0 a, K
default: : H1 P4 K* v/ K/ w$ |8 j2 P4 B, n6 m
printf("Bad Input.\n"); 9 k5 ^# U* n/ Z7 [( H2 H6 y
return 0;+ `' _+ C$ E- E, i r2 q
}
L; g0 e$ {" ?' G* _2 K, j& @ return result;
9 Y4 K5 A$ ?' e+ p9 s} 4 Q2 M' [- X. R' P6 q/ K
3 q# w; F8 q; I2 p' B
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
& g5 H3 X3 }' Y# A% B- e1 P{
* a1 C { k: h1 X- ~ Stack optr,opnd;; f& c P0 z. U5 v C9 R
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;4 B7 {( m/ v0 d& A& V+ z) ~4 Q
char c;) g6 I. {" O5 [. M! v
char buf[16];3 Q% ~5 ?2 b' G
int i=0;$ [( j2 m0 B" Y+ V* q
7 Y7 ]' V5 e+ M! X& x
InitStack(optr); /*用于寄存运算符*/
% V M2 y. c+ i' ` InitStack(opnd); /*用于寄存操作数和计算结果*/& I8 D9 R1 C o+ R
memset(buf,0,sizeof(buf));
: g7 O5 h! \) p
9 Y3 b, Q0 m% W# x+ [4 ?" m printf("Enter your expression:");
$ I5 ~/ Q* A9 A/ T9 v8 A$ x 4 C! Y7 c5 y: v1 e) y3 I
opr_in.ch='#';
& U& x$ b; {0 I. L1 \; @2 W Push(optr,opr_in); /*'#'入栈*/
) [/ E% }$ m; @: i+ L: I6 d GetTop(optr,opr_top);
1 k7 v7 h7 c( A: ~" C c=getchar();' w, U9 \, m% o4 i0 V x
while(c!='='||opr_top.ch!='#')' ^9 c! q1 |4 ~. N8 y, J; d5 y
{
! X* u8 X4 w8 N; K if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
7 S" Z$ X5 ?, U; g! o8 G$ {: | {
; D) n) ~0 Z& ]/ N4 L1 } buf=c;
0 ^! s7 K! T9 Q' D% k- C9 {! m# ?/ x1 x0 s i++;
$ U) X. N* ~# I2 W& C c=getchar();
4 V M$ C4 A% m1 Z! g6 n7 l }; J* u7 h0 O( t7 x; ^* R, E3 ]
else /*是运算符*/# O. \3 I* l3 ` G' V3 [0 @
{
5 s4 c( S0 E* N. ? buf='\0';2 S8 U" X1 }. |% \/ K
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/2 p' Q( i4 O C+ L
{
9 w7 E$ r- r7 } opn_in.data=(float)atof(buf);
$ S3 y! P% d4 X I/ P2 x% _3 Y6 _ Push(opnd,opn_in);0 Z& n5 I& x; e* r# S/ ~3 i
printf("opnd入栈:[%f]\n",opn_in.data);* X ?& |0 P: K
i=0;
4 B9 X- z/ K& \2 J, e* l' { memset(buf,0,sizeof(buf));! r8 D6 Z9 x1 k% ^4 |6 t2 m8 F
}
5 n( Y( F8 Z0 J: s opr_in.ch=c;
- a( @) R% f9 [: Z( M switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
+ m9 d% q% i9 ^% t! z6 k, u {/ Z' E* P+ K/ D2 v
case '<': /*优先级小于栈顶结点,则运算符入栈*/
( w! b1 n7 |* H* j7 Y( c Push(optr,opr_in);
; `2 } ?( U# ^) p printf("optr入栈:[%c]\n",opr_in.ch);
; A% {4 G5 r1 G% s% r! m c=getchar();
6 K8 T. @7 ]3 P+ X break;& C: V9 p" L9 T& k9 x, c
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/, j% }$ c' G) L0 F; Q
Pop(optr,e);
7 ]' N# h1 r1 l3 _ printf("optr出栈:去掉括号\n");
+ w4 I4 f/ z# v2 }5 ^/ |# z c=getchar();' e! m* Q! D6 V s \/ b5 T* Q2 W9 j
break;6 Z0 Y% p4 l$ T/ ?
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
& K4 M( w0 J O r( V/ W Pop(optr,opr_t);
7 ]# X# Y" E [1 n& | printf("optr出栈:[%c]\n",opr_t.ch);2 ?4 @' t0 S% o' u; n$ G( q
if(Pop(opnd,b)<0)5 @% H; N9 `9 d$ Z+ F
{4 I1 p5 E' J( z% c j- `! r
printf("Bad Input!\n");" S2 c: K% M# A$ l+ q1 B
fflush(stdin);
, T- K# D$ X J$ O" r2 e return -1;
" w7 \0 S- I& n% D( G! F }
6 s* C! H; n, T# A printf("opnd出栈:[%f]\n",b.data);- s6 }. d' N! }5 O# U3 ^
if(Pop(opnd,a)<0)
' F* }9 W5 Y, p8 d) U! I {) Y% K, i' L: ~) {, l
printf("Bad Input!\n");
( y1 S c7 k( y0 D" v7 B, c fflush(stdin);; x+ z+ i* i' g8 q- N& m
return -1;$ f" E. G% A' \5 C4 y3 {
}7 D& u0 w, r5 }8 V" P6 {
printf("opnd出栈:[%f]\n",a.data);- l* n; d% S4 e d. n2 R1 e+ C
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
3 R7 w- p. e, F Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
6 `$ |2 O3 D7 j3 w/ p- [' x printf("结果入栈:[%f]\n",opn_tmp.data);/ m; U# H8 N7 i1 W' X5 J8 R4 c0 M
break;
# _/ _6 Z; M, }% V W: ^6 d }. N5 m$ [$ _3 Y$ K( ^9 A
}+ Y2 ]& x2 ]8 {* ]3 Q
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ * _3 m' y% O: [0 w
}
U- k- u" W s8 t GetTop(opnd,opn_tmp);
0 w; O7 R2 G* j M* a/ Q3 x8 f+ n; ] DestroyStack(optr);
9 z4 y3 d6 c" s6 U7 B5 O% _ DestroyStack(opnd); v* o5 }3 E6 i; D$ y
return opn_tmp.data;! v, Y5 V& E2 T& t) k
}1 ?" G* ~3 L: h1 W D
# m/ G; x. J% m- xchar *killzero(char *res,float result)
+ k c, ?4 U7 i _0 D{4 V3 k% G- s! A) r) o8 X; g; K
int i;1 Y1 @! \/ U" w2 x( O
Y8 @" l5 T( N& d8 ^! K3 I6 s
sprintf(res,"%f",result);
9 t S- x, M' f/ u. G0 N i=(int)strlen(res)-1;$ k8 |" p) v' J) m% A. Z/ L! v
while(i&&res=='0')
+ J6 P6 O/ k$ G' B; U1 A {
4 \( T6 f' Q5 W+ y/ _ res='\0';
3 A8 w0 n. p7 _0 @/ J! c3 ~. Q2 \ i--;/ I" K6 c! v: }" v
}$ R8 K' _. q6 [ g9 i6 A- s
if(res=='.')' Q. G- Z' }: B( T$ E; x, p. y, l) G
res='\0';
/ I5 R7 p* j' Q9 t return res;- m$ e# \4 Y. R8 G' N% e6 ?
}& ? Z* v' B3 d4 D: N
7 |* A/ o/ B9 l6 mint main()
4 U6 ^* t% ]. V: A, i' u{
5 S8 D R' @* G' |0 l char ch; C7 k, e# V$ ~& h3 }; @0 b3 o
char res[64];
6 T9 |2 v# G( Y/ y. D& } s# g( q float result;0 H8 A* n* W+ w) ~
while(1)
: C5 ^+ T: P+ \& ~$ ^% g {
( d& B( H& N4 [; f0 N+ O result=compute();$ t, h5 `* A) M' ?2 Y* L
printf("\nThe result is:%s\n",killzero(res,result));
8 ~) {- ?' z3 w6 k/ h printf("Do you want to continue(y/n)?:") ;" \" p& H) I h* F# Q; X ~1 B& P
ch=getch();
. S1 F& X, p* G; } putchar(ch);1 S( L! a# ^/ ~- [; g9 f
if(ch=='n'||ch=='N')! ?4 H; Q# s3 s4 @# m
break;3 X7 [0 X% x- o6 a w! H
else; z9 i( x) J. q0 I$ R
system("cls");
* k" D7 c3 U% G. t }2 Q1 Q- P# b: V/ k" u& R
return 0;
" ^5 s. @9 m" U1 V, |9 E- ]}
6 D2 Z: W0 x' G; u; i ]/ q3 j( b5 n6 K$ E
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|