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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
8 ^7 C' z" ~8 `1 |程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=3 `6 X; m! q/ Z$ m. ?. g7 D6 B B6 P
/**************表达式计算器************/
5 Y' `" H, \# J* f T8 X#include <stdio.h>: ?( [# {6 J W/ h$ v. \: \
#include <stdlib.h>
3 U4 f( }* g1 }- o0 E; ~#include <string.h>4 T6 h8 N: f$ M- i
#include <conio.h># I/ y( |4 p- f f
#include <malloc.h>) q" Q0 ~4 p. g$ j4 p- f
4 u# c7 g4 D+ |3 L# E% w7 G
#define STACK_SIZE 100
8 v: S0 ^; m4 M#define APPEND_SIZE 10
' ?2 z3 b4 q, H u" T/ [
# K) D! I0 G/ T) kstruct SNode{
6 T. R* t) n+ p$ E+ P9 M float data; /*存放操作数或者计算结果*/
5 [$ N! k- t; ~: B- Y char ch; /*存放运算符*/. c, {3 L: B4 C }7 n# m
};
0 c! T! j( N$ U4 S. v( G" X) p: D% A7 R+ z; E* X
struct Stack{
) o% w# d; X; Z SNode *top;6 A* b) b9 D+ R' [# g
SNode *base;
* _6 N5 M8 o: R) V# L+ ]" M+ a int size;
- O/ q8 L k2 w; K, U" d};8 s. A( }5 ]- i
! k7 W* r; I$ ?$ T) f2 v: p' o9 y
/*栈操作函数*/- j/ r0 x& _ x* k! `; O
int InitStack(Stack &S); /*创建栈*/6 j" |/ c5 Y# D* A
int DestroyStack(Stack &S); /*销毁栈*/' r) {; @3 ~ U+ O
int ClearStack(Stack &S); /*清空栈*/8 ~: A6 B, K S) a$ c$ b, s
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
: Q P2 L* B) Z* A, l8 t3 Qint Push(Stack &S,SNode e); /*将结点e压入栈*/
1 V& K" G: g9 K$ s. Zint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
# u @% `. b' y. R$ ?1 {: [; l' e* c0 m1 ^
/*表达式计算器相关函数*/
& }7 C) f/ l7 [+ ~3 Rchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
% L, `# c' F- ^: Q* R( y1 u# q5 J$ ]5 fint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
3 T' _7 m& d7 K) V4 Xfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/% }* Y5 z4 b8 L2 { k( b' C
float compute(); /*表达式结算器主函数*/
# O! T$ t. p; J3 j( z6 M! T0 Z dchar *killzero(float result); /*去掉结果后面的0*/ 8 }1 w7 b- h" H T; F. h, M/ ~( ]
8 d' V/ R+ W6 F, t; A3 o% {1 Z
int InitStack(Stack &S)
' W+ C' v ^# d: _2 A; f{6 Y% J- X O: O; M3 p4 ~
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));& L6 d+ r: z9 A( V4 M
if(S.base==NULL): S( D% t3 {+ j' ?4 r( m) ]* ^( {. k% }
{
" s( J5 q' ~6 M* T Z, H printf("动态分配内存失败!");9 O+ s( c& J8 x) r# s
return -1; T+ p# U- d6 S8 G @2 p
}
) f( ` d9 |0 m% O+ @ S.top=S.base;& l, w( R7 C- T2 }' z' N
S.size=STACK_SIZE;
) e% S+ C4 W! C$ q8 F4 U e return 0;- n( A0 Q+ C5 @2 C* L) b0 y
}; K, c( O3 S$ Z8 `
. l" Q8 M) r& C
int DestroyStack(Stack &S)* x( z8 Z/ ~- n# q. U$ i! _
{4 |4 m+ w" X) A" K' J( d7 Z) {
free(S.base);
?9 y) x' c9 s# L return 0;3 g/ _# K1 H% ]* @4 K: ]. e
}9 r- [# B" W8 }: C/ A' S6 v- W
+ l# F, r4 S3 d7 _$ m2 zint ClearStack(Stack &S)
5 ?7 m3 P0 I: Q" O9 b1 L{
5 H( G c4 l1 Y5 z0 a1 l S.top=S.base;
. L6 J3 ~5 g# d$ O" [' {; k return 0;; j0 W. G5 H f
}' B+ r; S3 T* F' A) m
* U b/ S7 T7 |& \/ B& u
int GetTop(Stack S,SNode &e)
$ }0 s# q0 P/ v* t9 S0 R2 Q{
6 a. }$ X" W) F, Q7 j6 I2 G5 B- C if(S.top==S.base)
9 N) }( _! C' s {
F3 ]8 G% Z1 a6 O. d printf("栈以为空!");( C. k( Q% Q P; U Y* Y0 g* j6 Q
return -1;
, [6 Q; O2 X$ `' F: p }
$ x J# d- z2 k L! Z- ~: P0 w e=*(S.top-1);. U" W6 [( d. j% s1 ~( d
return 0;- ]9 c7 s' O2 A6 ^
}* k ?- u7 `+ m0 R! A, b( Q
0 G9 [ S* j6 w1 l: N9 D# K
int Push(Stack &S,SNode e)) ^9 s0 A5 B. T% |7 O }9 U# m
{ {+ l$ V3 U8 P" K
if(S.top-S.base>=S.size)% {& _9 G# H$ X6 M5 v3 e
{8 [6 y4 r" v5 X" W
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
" k0 R( s7 I* T2 E% s4 F) f if(S.base==NULL)
; _7 b1 S9 W( z5 E B {% `$ I$ b$ w# ]* T" o
printf("动态分配内存失败!");
7 G: x" j( s/ P7 F z3 m* b return -1;8 Q5 u' f5 `' O9 Y* F2 ~8 i
}
- k2 [$ U5 G8 e# D8 e* I S.top=S.base+S.size;
& ?) _+ h% Z( m( c S.size+=APPEND_SIZE;
7 B6 N, v; u- z6 J }" A7 _4 B0 ^, `+ q1 X
*S.top=e;
+ Q5 m, Y3 a# } S.top++;
; T, I: u" _$ D2 K6 |( I( }4 I7 Z+ L return 0;
- G' f; @% F& A2 v}7 m) J5 `, L8 u/ k s' g- T
7 b/ _& x3 K/ gint Pop(Stack &S,SNode &e)
& A: W& O$ `( C' |( e9 i{
. w( N; {& s, p5 |6 K6 m if(S.top==S.base). y8 l' y( r% O( j8 \) }3 z# n2 ^1 a
{6 A/ U0 h* j/ J* t+ i3 O4 h/ F" j
printf("栈为空!");$ ]% H( u m; s4 q6 ~0 y
return -1;
. A' u" t* {( Q/ t# g/ b0 h }( R( Y: k* C" a+ ^, M& `
e=*(S.top-1);
% Y/ F/ V; `/ p& C& k S.top--;
* o; w* K6 \" d6 K, G return 0;
' n1 M; q8 R0 O. w6 i" c6 S6 E}' L6 \# Y! b& p" n" ^8 {
" N9 @& D9 v5 B- i
char get_precede(char s,char c)# ?- k4 Q; `4 g( b4 u/ }! g
{+ w6 A2 i/ v5 r+ R* e V
switch(s)
" v% d* L1 q+ e' O5 Y O {( t3 V' i* e8 r5 l+ G$ S$ y7 B# s
case '+': X. ]( P) E4 p8 ^; S5 k% i% ?* f' f9 r
case '-':
p( z( e# Q" z# O+ L# [( @. r if(c=='+'||c=='-')
J0 T; Y4 T; L return '>';$ H+ S: p0 w/ U( z+ B; }
else if(c=='*'||c=='/')
# p! | \1 p* `1 `* N' i return '<';
% `6 z5 V# g$ d! H$ L7 z g+ j else if(c=='(')7 G) m% Z8 \2 F3 b4 A
return '<';$ y. a5 b( p2 A9 f0 U% q
else if(c==')')) x2 G! I l! G% V/ I
return '>';' s4 U3 C( x" y7 Y0 F% B! P
else
/ C" ^: C* F5 l' h+ A; h return '>';
* G; y |9 _% Y+ G+ @, v1 g case '*':+ u9 n% F# Q' S8 a; d% g/ Q
case '/':) j0 U$ s% Z; d3 l$ z0 F" L
if(c=='+'||c=='-'). e5 i4 W) h" D6 M
return '>';
- X6 h# B0 F8 I else if(c=='*'||c=='/')
* I) w& T, ^$ C: A return '>';( V) w0 G+ \' g' h0 n& p' W8 [8 l( Y
else if(c=='(')$ V) U0 V) T7 q! D6 s+ K" r
return '<';
, L) K. z* I' H+ R& @, D else if(c==')')
9 J& _; s5 N! Y1 }7 h: O; w8 D) b return '>';" A7 ~( a" C: k; Z! c$ ]; J3 G m
else0 n6 t; J- G+ U, Q% F9 t J; O
return '>';8 z# n5 I% V3 W _% M$ g4 Z
case '(':
" p5 A5 O8 Z6 |* T1 t if(c=='+'||c=='-')6 E; b$ [$ k5 o. R0 u% j
return '<';
, i. {& S9 E/ @3 V else if(c=='*'||c=='/'); h4 m# I* c6 ~/ b" i: O) K
return '<';
/ D! {- l% t4 C else if(c=='(')( l$ O- W6 c$ k5 |# _) x) w9 H. {
return '<';7 v1 z' Z" {( g$ ?: G7 ~
else if(c==')')( c' S- f3 B# ]0 F& U) G
return '=';/ r- G6 V* H/ `7 q4 Z/ G
else2 W! a5 {% y% Y3 V" i" T" ^ ~
return 'E';: c0 X* p! p& P; O5 z
case ')':+ E" Z( s8 X0 F2 p2 V, f
if(c=='+'||c=='-')9 A a" r F( ?0 B( H: ?
return '>';
4 W; D6 }( ^) B: r B* d8 l8 ^3 E else if(c=='*'||c=='/')! N7 i0 u0 ], Z. J- t" v* U* G/ S
return '>';
3 o4 P. S) N4 x% H( H& H8 e q else if(c=='(')
7 \! B' @& r; z: I& y' \ return 'E';
$ @" E) }. ~" ?0 A else if(c==')')! J) [; A2 M. G) Z
return '>';0 Z1 V3 @, F) y$ D0 u
else
/ a3 p) S! j7 a4 b3 n return '>';
& a* W8 r/ s, O. N case '#':- D. m: w1 [; _/ p4 j: k
if(c=='+'||c=='-')
4 ^2 \5 U$ J! r3 o7 J9 h! @; O return '<';7 L8 Y+ o& R* S5 E
else if(c=='*'||c=='/')! A+ p6 _5 a/ H m
return '<';* S9 k: S5 t9 m" s2 Y) Q$ ~
else if(c=='(')7 u6 ?) p2 q( Z4 P% q# ~
return '<';- {( }1 w. A" ^+ y, o3 x
else if(c==')')
- ^$ K% S4 S+ e' y8 I+ C return 'E';" ~* b" M: H/ C% n
else
+ V8 s# `. v- f" y6 | return '=';+ I0 T$ n) G$ E1 u" X, R% P7 {
default:
& T9 r$ g8 D/ `7 p) k* }& r break;: K+ Z& W. [7 ^' }& i. a0 Z
}9 T, T& F* t5 A" E, R
return 0;
/ @8 k0 d( G* V) v}
9 A$ n0 U6 m0 ?6 _1 G S* c. l! [' p3 y u$ G
int isOpr(char c)
5 Q2 |8 K- A' o0 F$ v5 j{
1 Y' e% G6 W; }8 z if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')9 ^( y$ b7 A% G
return 0;
) ?7 \0 a# G- G' i/ G6 @& h5 Q else / ~: V: v$ e) p' ^" y
return 1;' a: @+ ^3 y8 J' k- Y* D, ?5 s
}/ N$ a i3 W+ q2 f
- |* \' d+ Z0 V9 e
float operate(float x, char opr, float y)
9 c% Z+ o. v; C- ^! m2 ]+ q+ y( b{1 F e: K$ O9 e( Z9 l/ }
float result;
0 e) M& K/ k2 P9 V switch (opr)( @3 F" S5 u0 w% z4 H- X. Z3 v
{
! p7 l; e, p; L case '+':
$ H0 `$ ~! c( t0 b+ M+ @: e9 I result = x + y;
$ N6 f* V/ @( N: B break;
! h, U6 |2 w) b4 T! t: G! \ case '-':
) t0 ]) Q1 l2 r5 @ result = x - y;
; u( s( C9 p% ^- g- I! }/ v break;
, ^2 p0 v/ I9 _! e+ i+ e2 D case '*':
, D' P; Q) L- P" f; E result = x * y;
( l% T0 F `$ a: G' a N- O break;) s" T: j, U! I0 C( v( o
case '/':
2 X$ q' F( z1 t6 U9 B6 o2 ?. f if (y == 0)* ?& O- D8 t3 q' K
{
% T/ `9 p- {* I( i- L* U1 B% c0 i printf("Divided by zero!\n"); M( n/ l* D* G) j
return 0;
4 ]% p+ u, h7 M: u }5 P3 o7 e0 J' K7 Z5 S: `
else5 Z0 ?! V% k; }( X" b- x4 _' {
{. ]; F5 P; r/ A
result = x / y;
" X5 Q( U5 v0 j" H/ b break;
+ J* s. c# _6 s; J }; X1 ^+ t( I( x1 {6 `* w
default: , S& T+ |, B% a) v
printf("Bad Input.\n"); * \3 A4 m$ M) o. @# b
return 0;8 d: {; Y T" r
}
/ ]& e6 d& B: H4 b5 k return result;
) E5 y% D6 S3 v2 E} ; D2 z! e, n) J0 r
: t$ O& S% \# s: x; B% ]
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*// e( w, C3 L! u e: e l6 G
{
4 a% ^9 m0 u1 E! e! Y! i3 M Stack optr,opnd;
: l! V1 M$ ^ H3 ~; x( d* s struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;- z$ n. i" V( E
char c;
+ P1 z! `3 D9 d. @2 y/ y- ] i char buf[16];0 Q1 [5 K2 s, y* M% i% F' g/ [/ Y
int i=0;
1 Q6 ]5 b7 j0 y
: @1 _3 g. b7 N InitStack(optr); /*用于寄存运算符*/2 R3 @; d! j9 s. s6 Q: K% W4 Y
InitStack(opnd); /*用于寄存操作数和计算结果*/8 G/ m5 z/ n2 O/ [+ @
memset(buf,0,sizeof(buf));
7 l- w# y# U# k3 [7 d" O% a9 h
6 i! j' B# D3 [ M printf("Enter your expression:");, t2 ?1 N4 S* a6 V- F8 O
P4 O* x0 B/ S7 Z' V
opr_in.ch='#';
6 a5 U- o' Q2 M/ P7 X3 Z9 a8 z Push(optr,opr_in); /*'#'入栈*/; ~/ P- t5 V+ ^6 D4 i8 \3 I) P# E. q
GetTop(optr,opr_top);
+ p5 p. i7 z6 K5 M3 K% T! M c=getchar();
" U) H- w# b) H* j5 H% d: n* ^' F while(c!='='||opr_top.ch!='#')
! G W+ ~9 |; Y1 R {% F7 k/ v) c7 x1 t r) U. V
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
$ o4 o0 r. [- B/ P' ^ {
. n: S1 b2 k& r1 R `% l% | buf=c;
% U9 n7 _! r- a6 h- I4 }; U i++;6 L! \* z! ]/ _' G+ l$ R
c=getchar();& T+ U8 W$ W+ I5 T _
}" B# W: h2 k$ W1 v) z
else /*是运算符*/+ [/ t+ o& W: i* _
{
: P( S! ^! M, t Y# V& r7 Y5 ` buf='\0';3 A6 D2 X9 @( M, g; X
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/. D j4 e8 w2 V- o! J2 G
{
# C+ ]9 G& s5 D4 w0 H opn_in.data=(float)atof(buf);
6 _* i% o7 l0 ?8 F l# l Push(opnd,opn_in);
9 G5 ^/ [9 d" `% i printf("opnd入栈:[%f]\n",opn_in.data);9 y7 \! `$ s! L* |
i=0; j k# y3 i& ^2 i; p
memset(buf,0,sizeof(buf));
^9 Z9 o# ^; K( q# v0 T }
& O2 c+ Y. f* d0 ? opr_in.ch=c;
" n5 p7 P9 r; y+ c0 X7 `. M9 ] switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/! N% ]2 M% c- B+ h" v. ?
{4 i+ @' P5 {" a L, h1 P6 {
case '<': /*优先级小于栈顶结点,则运算符入栈*/! f8 e. X( o' g6 }
Push(optr,opr_in);
+ c7 T$ A0 k3 o2 H8 @! i printf("optr入栈:[%c]\n",opr_in.ch);
: v5 v' H/ S: H' S c=getchar();
I/ I( J/ T6 f* P* I. t9 k break;
" w/ _+ J4 S3 |4 F case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
& i- B; x( B2 a' P3 D( Y& B Pop(optr,e);
6 E0 R+ Y) R# _ printf("optr出栈:去掉括号\n");, J1 f4 S- |' T% Y
c=getchar();
( v+ x9 Q1 M% I) j* } break;
8 y. ^! x5 _6 [' j case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
$ S; X7 l) V+ n: X0 Z, C2 u- E Pop(optr,opr_t);
/ G |/ J, B* @7 i. b- l printf("optr出栈:[%c]\n",opr_t.ch);; w( h- x: x+ N) }/ w1 N! m
if(Pop(opnd,b)<0): |1 J* U- @. }* a' N
{, u6 o. q7 ^+ i3 S
printf("Bad Input!\n");- l8 W+ Y1 K D. K' d
fflush(stdin);' v% h0 |0 k# H' s
return -1;
7 O V4 J* V$ F+ n+ a% C) R) z }
! N7 y: i4 a: V" E- w/ ?- w printf("opnd出栈:[%f]\n",b.data);
4 f: y2 @- D5 A6 j0 ]' J if(Pop(opnd,a)<0)9 S& S& k: y1 y4 v" e/ F1 I
{, r3 p9 _/ m) z0 A5 e' S
printf("Bad Input!\n");
9 Z# \' ?7 G p) V( @ fflush(stdin);$ F, S+ C- Y# `# a" O. f; p
return -1;3 O0 E' `! S' y+ Q& V' ^% e! M/ b
}( {1 O4 o7 C* ^' k; I/ L2 C
printf("opnd出栈:[%f]\n",a.data);" Y4 D: D: n8 |" _) g! F& N
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
$ ]. q6 A* }$ H( g* y& l Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/ I7 U+ s+ x U. G- Q
printf("结果入栈:[%f]\n",opn_tmp.data);
! A0 E3 n$ J/ E: v break;
3 O+ m9 C0 t4 F' F }. f a6 J. ~; I9 U& ]
}
4 Q) F7 F0 w$ @( _+ ?! a GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
5 O8 R6 k$ t4 R3 t; j8 R }$ u1 P- [+ ]# A# w& _
GetTop(opnd,opn_tmp);) M% R/ J4 C5 @: K
DestroyStack(optr);
( Q M$ W7 g. R* U! @* _. G3 [* ] DestroyStack(opnd);
3 C/ Q, x) E0 Q4 R return opn_tmp.data;
4 d' d: j3 I1 p! q, k3 u% M5 N% G}
$ c" a% c! s4 d5 [" g4 C& |! D3 W" C+ w1 L& y3 S% F9 {8 H5 V% W
char *killzero(char *res,float result)- Z6 z& E4 M* t) \
{4 ^$ }0 q2 s) L
int i;
) n/ X7 S4 j `1 b$ C( l T: F6 w4 G! x! L) m
2 n$ P9 x1 X. K0 h! T sprintf(res,"%f",result);. M# v5 H" p! z) ^ ~* N9 r
i=(int)strlen(res)-1;- _& d5 y' Y+ J- Y1 W) @* r
while(i&&res=='0')
% p a1 }: f, }' n/ F {0 X5 @! \4 ], F( P5 z" Q4 @
res='\0';) k) J* N+ R u% B$ m; B! a
i--;1 m* h0 `! |. g, X
}
/ Y4 e, J- d* x if(res=='.')
& g0 i- s7 a. n- _$ G res='\0';
5 v9 _8 J0 M! z" K: J5 }5 ]5 W; I% N return res;" c4 r4 O3 l9 {) s' d, a# s
}
( Q5 r4 R- B1 Q) l; q$ A0 l' P
/ a" F @) b8 Aint main()
% h; ?; @3 \" K" q$ `" y& t{
# y# Z8 O) S; d$ @* G char ch;9 U0 e- M9 ]$ T) M2 ]
char res[64];; J, n; t6 G" V+ o [6 U5 S
float result;
2 b8 C# R& n8 z. `( M4 o while(1)/ X' o+ o8 m+ S( f' I
{
0 B5 i9 e" a. z4 T result=compute();
* z2 B. R3 j8 Z printf("\nThe result is:%s\n",killzero(res,result));
& V4 r1 W N5 F+ g, f8 V printf("Do you want to continue(y/n)?:") ;3 i0 A# R; }$ @$ f4 c
ch=getch();
* _+ L4 W! r/ o2 S) G$ S putchar(ch);" D8 N+ t' ]! m$ ~( S
if(ch=='n'||ch=='N')1 P/ z; j. i1 y5 B0 z3 f
break;
5 p8 S0 N# D% a3 L+ g) J( ?6 k- f else: i7 Y4 @ B; E
system("cls");
3 m0 W+ @; O( Y* p4 H, \2 R( s' O G }, E' C3 l: g/ I7 {- Y: ~
return 0;! G. Z8 U4 Y9 z0 i' l) D
}
% H" H2 r( u. d o, X
. n7 x/ M4 [" v[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|