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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
3 e7 r7 t A8 ?程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
8 m6 P V6 p# w- U/**************表达式计算器************/
5 L# ?) D* e) ~; {. Z#include <stdio.h>
& P v6 b" b Z8 F( J4 d& y#include <stdlib.h>$ w5 C" t+ q4 o: N% t7 M% _. p
#include <string.h>. K5 N* B: X# ?. J" n5 c) e" G2 g- X
#include <conio.h>
9 v& E2 b7 f9 N9 K& T#include <malloc.h>8 B% s. ?, s4 D" {
8 I& Z4 Q) B0 ~6 o! I* V+ f#define STACK_SIZE 100' ^0 G" ~/ Q; F
#define APPEND_SIZE 10
& ^7 m& R& T" {7 a5 S
( p' \& H, z; C4 {$ q0 y+ P0 Istruct SNode{% a3 g3 q+ j* j
float data; /*存放操作数或者计算结果*/3 s/ o2 @( g+ i: f
char ch; /*存放运算符*/) R9 J9 p: {) b; w4 k# f$ Y
};' c% c0 L- I5 W1 o
2 s3 ]9 R# w; Wstruct Stack{
; ?& X8 p% ]" X5 ]+ I2 P% h* m SNode *top;
* \$ E1 I* m# a: a SNode *base;9 L! H$ F* e. X' k9 r( ^
int size;2 \4 C o0 h- ~9 E7 _+ c! E
};
! c+ [% K) g" A2 |
5 j$ W3 [( v' }0 K+ l' m/*栈操作函数*/
0 W/ ^/ @( O: [4 M) B! Yint InitStack(Stack &S); /*创建栈*/8 w; k8 c* o$ Y) |' g- e
int DestroyStack(Stack &S); /*销毁栈*/
8 ?0 h; G0 Y, E7 L9 W) u- x6 M; qint ClearStack(Stack &S); /*清空栈*/
7 q6 M0 Y/ [2 [2 c2 jint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/3 N* r3 P0 y" Z5 Q
int Push(Stack &S,SNode e); /*将结点e压入栈*/
0 h1 |0 f- S5 Y4 _" z' k* Tint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/( U: z% M7 s, F4 X6 w
/ u. [# ]3 ?- X/ H% F9 M. T. F7 \" o
/*表达式计算器相关函数*/6 h1 J N, ?7 Q& K8 \3 z9 P
char get_precede(char s,char c); /*判断运算符s和c的优先级*/ Z5 w# W( s" I: B: k& C1 U
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
5 ]; }3 j# q: h! |float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
9 D$ E0 s/ r3 t1 i& t. @$ cfloat compute(); /*表达式结算器主函数*/3 P3 v9 R9 @$ n5 a* E3 K& H; |2 |0 F
char *killzero(float result); /*去掉结果后面的0*/ : j9 y9 F8 w. d& H ^
5 Y8 G; T# ~7 y! q+ ^
int InitStack(Stack &S)8 _7 F( D0 V0 p# |9 w! D
{$ q' U3 d2 k# w! b" N7 x
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
9 j9 m" s6 x+ U# X if(S.base==NULL)/ l+ r$ F |8 P- Q" L B" l
{+ f5 a# A6 I. D5 o4 X
printf("动态分配内存失败!");' u) O; G3 V8 I" B& M
return -1;
0 ^6 Y' `( j4 K0 O5 A }9 j1 r, S, r7 d5 N6 _* E6 Q- P
S.top=S.base;$ G' h' ~; X: A
S.size=STACK_SIZE; d0 k( E) w4 g( L
return 0;
4 b: Y/ R G* l b}- v& S0 H% [$ g& S& B
5 j: `( z/ n% @0 a6 z( N: ]: cint DestroyStack(Stack &S)
; B" ]" ]5 R# m1 U{8 [: S; n& F; H( F' i& Y
free(S.base);
% O8 [- T# R+ L return 0;
1 j0 O7 ?, m9 S- _ g; g9 P}
6 j( x; p5 b+ C; `4 n
) V8 b* u9 N& [" hint ClearStack(Stack &S)
0 n% u/ z, H# J ^9 g5 `9 u, k{& [# M; s! @8 {* p
S.top=S.base;! K9 [4 z1 T% j7 M
return 0;% X: _4 A, x9 d) T+ Z6 L
}4 c8 b6 w' D7 K8 h# a. k
: T- [' |6 \+ H. f9 q) ^
int GetTop(Stack S,SNode &e)
' Z! k% w5 K+ `- l' ^- k7 X{8 u* u7 W5 ` N& C4 T: z; k# m: y
if(S.top==S.base)
8 Y7 H: j0 L2 k" _9 O; D- G( E {
. J5 G( i+ Y1 `/ y' d printf("栈以为空!");
9 T: }0 i! I) A; Y, v- Y2 {6 ~4 ` return -1;
2 ]0 R6 y* U" O. d }
& r1 w" f, E0 H% m3 F e=*(S.top-1);
/ P/ @! \9 m4 B* d1 R return 0;% Z0 k! {% ]$ {, k1 D
}. |* B8 }! |# Y8 n" E- Y
. q6 o* i# y! H; b* ]
int Push(Stack &S,SNode e)% c$ r; w! e0 B5 I. ]
{6 d7 D. q3 X& S" @3 x2 _, O
if(S.top-S.base>=S.size) w# I2 u$ y9 _) Z
{8 X) p: z6 B, h) z
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));# x% q3 }8 P" z0 |/ t; y
if(S.base==NULL)
2 Q2 J: J4 Q3 Z4 | {
) b' U- }7 f# d; Z; N( P) q printf("动态分配内存失败!");
& i, z" u. }+ ^0 ?: i1 `4 Y' y. _# { return -1;7 U0 q& L7 w% G% m3 Q
}
! S) F% R+ w2 o" F S.top=S.base+S.size;
" U1 U3 h3 H+ ~! d S.size+=APPEND_SIZE;8 ~) S# [1 Z& ^" k
}
1 w' E9 y% `0 {/ s3 j$ J* E *S.top=e;8 _, \* T/ n% S1 f6 f
S.top++;
& @! q7 \( I/ ]9 ~) I$ h/ H return 0;. k, {& e- \$ `5 a! L
}# I: w# j7 p. \3 q
& I/ P/ ~% J, J; Oint Pop(Stack &S,SNode &e)
& M. ?8 M9 n9 R y, b{
; X+ |5 M! ?0 j if(S.top==S.base)8 Y/ E! ^- Z. B9 ~9 _
{8 k( b8 \. l0 e |
printf("栈为空!");0 o% y7 X- t/ ~
return -1;4 ^' u$ a$ c* @
}
5 c/ w2 D. u3 G7 o e=*(S.top-1);# N. F$ e, P1 v% S+ i: W
S.top--;% L' E/ {+ D- B5 Y, f# u
return 0;
5 N9 P8 p; q4 h+ M7 t/ k}
' l$ }% X& e3 s! ^# {: [: l. M7 P; r6 E7 K4 q' M+ N' ]" D" l" b' v
char get_precede(char s,char c)
2 e0 [$ x7 u- _{" {$ _) {1 s; A% L$ C/ c5 m& T
switch(s)
' n5 a9 h$ ^& V8 {' } {
: O* L! B% f; \/ a1 g. [+ G case '+':
8 d& q* K* O8 ~ case '-':
9 v7 V6 L5 R! O" ] if(c=='+'||c=='-')7 T/ _7 v$ b6 r/ Y& P' B5 I
return '>';6 i7 I: X+ A' e0 C3 P5 _4 R& k a
else if(c=='*'||c=='/')& E3 P7 V- _% i" c" ~" S a& Z, T
return '<';: |. p4 w; H9 ]: C8 |7 b; H8 y
else if(c=='(')3 H2 l. ]* z! T4 w8 N
return '<';+ N% w* ^/ g' p
else if(c==')')
: H" h7 j% [ Z; T _ return '>';- d1 R' j) R+ K4 Y7 i$ |! R
else
' S8 @4 h3 X7 \* B1 q8 K& D return '>';( T$ b- h @: }; H
case '*':
! {7 L+ y! s8 i- M case '/':& Q( z6 O3 k6 E7 c+ x* v
if(c=='+'||c=='-')
9 Z+ ]: v' Y7 E+ R* A d6 H% ` return '>';
- T6 A2 Z6 r7 D3 D4 d9 W c { else if(c=='*'||c=='/')2 ~- K8 z4 T% F% w. I( k3 p3 l# i
return '>';
9 r. g! B6 l) B ~& _ else if(c=='(')
: L: Q% I6 y) q' W" o6 W9 L5 l return '<';4 o |6 l4 p. K/ ^6 P/ |
else if(c==')')
0 j6 A# M0 u( l' [5 j; y+ S5 s return '>';' f! T% S% |! C7 Z- G8 l& A& m4 p
else# j) U6 S. X& O- f9 i1 C" D
return '>';
$ u, x- P" O5 c" W case '(':$ @) L# {1 S2 a; Z
if(c=='+'||c=='-')
! p% R: _0 \4 H5 O4 N. Q( Y return '<';8 U4 k8 E/ f8 D
else if(c=='*'||c=='/')! h- E+ H5 q1 K, M [
return '<';6 n! u3 g: W& r) c! R4 s6 ^, Q
else if(c=='(')" m3 A y/ m( z: m5 i2 Z- ]- S1 ` m
return '<';3 [) G7 Z0 M. U/ |% R# z
else if(c==')')6 k" D2 ^2 F2 b) J9 i$ T8 W- R
return '=';' W- @- G, p5 U+ s! b" B0 ]% n
else, G$ U' k$ f5 _/ l) I4 n8 X. W
return 'E';
0 m$ N* ^; Z% A$ g case ')':# V2 l1 c6 t! R% L7 A, C7 b" t1 W+ y5 p
if(c=='+'||c=='-')
" M, g1 w8 P) }+ T# P return '>'; m, g& r, d7 S1 @4 `7 A* `
else if(c=='*'||c=='/')' d5 ]( B5 J, |1 W Y( G5 N
return '>';" N* G7 x t# d: [7 i! h9 l
else if(c=='(')
1 c6 o) b- b" c6 ]- Y, V `0 U return 'E';
& D5 c. `8 P( l! S else if(c==')')2 x9 Q% A4 i) y G4 B, P/ `+ S, Y6 g
return '>'; v3 |6 I U5 |# m! _4 @3 h
else5 W0 Q8 P9 J) y( R
return '>';
0 D3 e0 @, o! Q, j case '#':
; o6 ^$ C5 E( _- ]! ^" l4 p4 b if(c=='+'||c=='-')- }- ~. O) K6 b/ V2 [5 c/ w
return '<';- `+ L4 X0 w5 l6 w) u
else if(c=='*'||c=='/'); L# D/ E) s6 t5 v5 _8 `/ g
return '<';
2 b9 I# O- S/ S% | else if(c=='(')
2 j9 ]& |! j5 s% M. P+ }% s/ P/ K% Z return '<';" I- Z8 a7 @5 q/ i% K# H( F' ]
else if(c==')')( |! w* u( q) D1 S/ M/ d" [
return 'E';
4 v; \* R( r- L# f" C else! v5 @6 N$ b# }0 U
return '=';
" S. w U' `9 J& F; g0 v/ ~ default:
# b- {) x, q- |1 c2 a/ Y break;
' X8 z( A1 r+ f, L; M4 g5 H }
, o, u0 u7 I" K$ l& A: [! I% | return 0;
+ d- t& I2 a h3 o* v# l+ w0 d* T% x} `9 \: N# @5 o; n
4 h) R' o" w! }* T4 L% Qint isOpr(char c)6 t& D% o1 k7 _ T
{3 n3 P5 _2 F1 a% Q$ c6 V: p T
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
/ g0 N6 |( {9 D7 ]+ ~. P return 0;( E/ N0 h! F# R( b, A
else 4 M5 z0 e/ u. u. b/ j0 B9 h
return 1;+ B- s# o+ @( C9 b
}7 h: g$ @# W1 E. }, D' V
/ S! B: M0 l: \
float operate(float x, char opr, float y)! p1 F. @& `. P) `7 g1 N
{
4 f D3 L; C7 ~ float result;( @" Y2 m- j% X8 A$ N
switch (opr)
( q6 n7 t' i9 ~2 w) x' f {& h% g% {- t+ |; I S! m. j- V
case '+':
" d D+ T" O+ X$ U6 {( t result = x + y;: |: n# h9 X6 K k; }
break;
1 J% _! s* X- [: r L9 C case '-': ( T/ L2 Y' V6 O) D, o; f( B
result = x - y;% H9 i8 y$ m; N( k$ \
break;) \+ O8 G$ X: c2 \/ z; X' q
case '*':
5 d" i0 ^. @+ d9 A result = x * y;! g% ?6 g7 z' r, B# L
break;8 ?3 j. M/ k; _* a. q# Y; n
case '/':
! P M" X3 u, f( L' H5 R. Z5 ? if (y == 0)7 D; @- E6 q) s% j: [. s
{- q9 A) O' o: r
printf("Divided by zero!\n");
! e$ j. w/ C1 \0 Q8 W0 z! h return 0;9 |/ B, D5 H( R% r5 ?6 V
}3 v3 x; a9 w9 f' `
else
: @1 y. o2 }) F9 F$ G {! @8 |% b" w# o6 u
result = x / y;
) P# F0 y' N, Z% [1 |( z8 B break;
% Z& M1 D& [; K; _6 j }; Y' {! ]# t5 Q( A
default:
, m+ Q& N' \1 R printf("Bad Input.\n"); ; I$ D3 D$ Z) {2 i% R0 ?; l
return 0;
m# J; M" Y9 q: P8 | }7 j6 A/ e1 N$ X( r& k" R
return result;
$ A' u/ r! m! L' \/ q" s+ c}
, G0 L4 T/ p/ e g( H! M6 o9 B \( g2 c% {3 j
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
4 l1 ~+ G3 C; w* V& }! b{" C6 r! R% t' x3 t) u4 k' K/ s
Stack optr,opnd;
3 G1 o& F' ^$ G struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
0 D' b' ~5 W' O) G0 o* Y7 a1 q# z char c;
7 `/ _9 X6 C f; q char buf[16];0 x# w5 O+ y z( x0 t: s
int i=0;" `3 c, u' C9 f3 K2 h* J& Y) L
( o0 Y2 }6 o9 O. n4 h; v5 P& ?
InitStack(optr); /*用于寄存运算符*/
" G9 \1 ~5 Z. v. z: J S InitStack(opnd); /*用于寄存操作数和计算结果*/
+ p' X9 T+ z3 C8 n6 b memset(buf,0,sizeof(buf));' p8 P( ^0 ~7 x! s
3 E# T% I% m1 d8 A+ D; z printf("Enter your expression:");
8 ?3 l0 _( Z6 R( g# d- [
5 r: U, I/ l1 t) M6 P opr_in.ch='#';
1 w6 g# f- [; {2 P4 [$ ]# N Push(optr,opr_in); /*'#'入栈*/! u% p" W! W( C3 D% g+ B% F# s
GetTop(optr,opr_top);1 }$ H" O8 t2 P0 f# \
c=getchar();- O+ c. x4 k1 F
while(c!='='||opr_top.ch!='#')1 B2 Q& N) e* r( C* ~3 t+ _
{5 Y7 w6 o/ q2 m1 p2 S5 J7 Q" k
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/% L) a! l* `$ o0 V
{, h# S0 `1 [/ d
buf=c;
, g0 {$ O& m( [' a0 G" } i++;
) j0 r$ H. l) n7 U c=getchar();2 s1 `( f6 v0 j8 ] D
}, A, J2 _: N8 R
else /*是运算符*/
1 V4 Z, V+ Y7 P5 [ {" S8 u& ~6 S2 m7 C
buf='\0';
( A: [& }. e5 p. q8 [% ?7 Z, g if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/0 s% I3 {' c/ n) W# Y* m7 w
{% e8 g* r& }( w" {' D+ ?7 x
opn_in.data=(float)atof(buf);
5 ~! w% W# p; S" m Z Push(opnd,opn_in);8 M% r" w( G& D: f
printf("opnd入栈:[%f]\n",opn_in.data);
* x9 M2 Z0 y9 h7 C8 z6 F. S! r I( v i=0;
6 j6 z6 c7 A: i4 u6 ? memset(buf,0,sizeof(buf));
/ u8 d% v! ^+ q7 ?/ t3 L8 y n }
( J) |1 ]6 S. o% l. R4 ?4 ~ opr_in.ch=c;
9 o1 F" L8 d" ~7 l3 G, L switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/ ?& U1 O0 n/ W6 {4 k" @
{8 J. @) |1 z% X8 z
case '<': /*优先级小于栈顶结点,则运算符入栈*/4 o5 g( \ U7 |% n; Y- \. S5 m
Push(optr,opr_in);
& x8 v' c/ r# K- F printf("optr入栈:[%c]\n",opr_in.ch);# {0 |; Q, ]1 n5 B
c=getchar();, w# w8 L9 I% k% ^8 U, ^ j
break;
; |, v0 L% t; R* V case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/+ s8 S) P3 P/ h7 n8 R5 {- K
Pop(optr,e);
; r- k/ ?) |6 R+ L+ Q0 R( @& Z printf("optr出栈:去掉括号\n");
" F; F. l' c% J, E c=getchar();" L# W1 c, O- U8 K/ l
break;' c' F6 c6 e9 x0 V9 r
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
" P) A& c& I& O0 e) N! Y6 y" t Pop(optr,opr_t);
' t# M, h3 i0 q" U. D printf("optr出栈:[%c]\n",opr_t.ch);4 `8 j, H+ S/ z2 v3 t4 @. J) H% e
if(Pop(opnd,b)<0)
$ E1 d7 B! o1 n+ y! U {
$ Z6 K+ N R Y9 _& Z5 |' _/ Z, ] printf("Bad Input!\n");
# c. ]! Y7 c6 ]# T& T9 M fflush(stdin);
# D& v0 A; e" N6 \2 z; ^ return -1;3 g H6 E# R4 E( P. y# W+ l$ J/ g
}
& z$ [. J4 t k; C4 I& k$ q, E2 X, g printf("opnd出栈:[%f]\n",b.data);
* |9 g0 }" i \ if(Pop(opnd,a)<0) k& _" L2 a8 f9 \1 n! I3 V
{
' }) Z0 V8 A, m& A7 @( q4 I printf("Bad Input!\n");" c7 Z0 L8 Y: Q# J! t# r
fflush(stdin);
% ~4 f, a9 k/ G6 N( X. ] return -1;4 a# ` {1 X, [& }3 X8 O% y
}( j7 n0 l& G" Y% Q% i% W- f/ a( k4 M5 J
printf("opnd出栈:[%f]\n",a.data);& U' J0 q3 t( H* @8 J6 {$ r
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/7 A3 y2 Q0 d0 K# |
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/) j' Y9 v4 E9 e$ w% ? n
printf("结果入栈:[%f]\n",opn_tmp.data);
" F7 I/ p# b. o- [* _* O: b break;4 V7 k3 f" |8 T# c
}
: G8 J; B: W; y1 n* Y( l( p }4 x# f2 F' W2 n, I W1 h6 b6 Q
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ , U9 O/ q- b+ J0 q. E- V
}
7 T( r1 T5 A7 I6 q. P GetTop(opnd,opn_tmp);
1 F; ]- b/ r: F) s# m& M$ O DestroyStack(optr);
# w6 f: X4 W: V$ r& z DestroyStack(opnd);
; q0 p8 g+ i) c+ J7 v return opn_tmp.data;& |# t z4 w! [$ J- t
}
" `" T! f5 ~* d! l8 ~8 c0 q5 g; N
3 S0 ~3 p* i2 O8 [char *killzero(char *res,float result)( J- F: N) ^% K; p% P5 w. `
{
4 c7 ^6 b) ~1 D. D int i;# i% O+ Z5 @! f, \ Y0 ` q
- h2 d0 n5 S; W4 b+ P9 W sprintf(res,"%f",result);
# B3 N/ ^: h5 S4 V# { i=(int)strlen(res)-1;& i1 w& @- D. s6 ^
while(i&&res=='0')
4 O9 v! `/ T6 u% X$ A8 b [ {
/ d! N7 P" m& X( N! n/ g! n res='\0';
4 X& g, v' g( ?4 N$ V i--;
( W& L- \' t9 I1 Z% Z$ ] }; x) M7 d7 i @1 G! v
if(res=='.')+ `" L3 u" d$ L/ f
res='\0';
$ H4 L7 V" K1 U8 D3 b9 E( B return res;
4 [7 m; s# r3 k5 u, S- h4 g& x, t. K}
+ h3 m, l7 ]- K, `
& [/ O+ k: e9 P& Z' ^) q; `int main()) u! S! h8 x/ a
{! l* T' Z, N- S( }7 w2 |6 V; v
char ch;
! S% N, y) Y# J( A char res[64];0 d$ H0 k: h; p, q8 @
float result;
/ m6 D; z* G3 h" |9 p- @% j while(1)
2 ?" W3 m3 F& @) W; d! Q {6 e4 g7 w3 J- T; A3 y& ~6 t# Y3 h
result=compute();
' |8 l0 e* s% Y' M. X printf("\nThe result is:%s\n",killzero(res,result));
( V8 {% F* C& y5 D/ r3 u) }" m0 V printf("Do you want to continue(y/n)?:") ;
/ j5 Y. o# M* D# J3 j0 u" v ch=getch();& d) P; i2 B& W
putchar(ch);" U/ z: N* u8 L6 O' g Y& Z
if(ch=='n'||ch=='N')
9 r) ~+ R+ _6 k* Z break;9 ]7 W* n/ Q, |, c+ M( w' @
else
; L3 t" B5 F, j2 D# `2 e# \ N system("cls");9 D# D' Q4 S4 r( D# r; ]6 N* T
}
0 `- P& Q/ M' [, Z1 T return 0;
8 Z+ C* {, \- e9 t# }; V}# m) c& g# Y6 A
3 K! q5 B& w3 {; S6 N1 F2 z
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|