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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.1 x l) I& B; l$ Y- n3 u
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
! |. T6 g: l# S$ n1 @/**************表达式计算器************/
' g, A2 A/ H& {& @2 P/ w, F#include <stdio.h>
% f* Z! w5 @) |' o#include <stdlib.h>
, P7 m, ]) c% a# W5 h#include <string.h>
6 A! `5 W6 [ @0 h" r& |#include <conio.h>
' c+ r, ]" F9 B8 D$ N. {#include <malloc.h>4 O5 \+ w' B) K
' q0 G5 `+ W f% k! l8 t
#define STACK_SIZE 100
: t$ {9 ?3 Y- r: U#define APPEND_SIZE 10: A& T, M" d+ g. R; b4 @
$ T+ ]: ^4 t. K p! n& o3 R& z
struct SNode{
0 ~, b% s9 D" \& Y float data; /*存放操作数或者计算结果*/
& u- h' C3 R# c0 d char ch; /*存放运算符*// \9 \+ E5 L7 K
};
! U$ z5 J, G# N6 `# p3 Q8 b( ^7 I- B5 Y5 i- c3 T
struct Stack{( g$ O: Y& {+ J4 f& }8 m
SNode *top;
8 _* L$ G8 F6 O" b( z0 \ SNode *base;
4 Y- B/ S0 e% v6 Q int size;
# b9 c$ M. M1 N% y};0 E5 l) h* f# ^+ \. i( D
( W {* A: j: C9 Y; ]
/*栈操作函数*/
; D( [; V6 C. |9 ]2 V7 ^' gint InitStack(Stack &S); /*创建栈*/7 f" k9 G+ n; G: D$ k+ z
int DestroyStack(Stack &S); /*销毁栈*/
! P, r3 e+ ~0 @ ^, M% X4 ~6 fint ClearStack(Stack &S); /*清空栈*/
: L. C$ n. J- D% L0 U' g7 I8 v2 F( `int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
, q6 Q+ t8 d3 Gint Push(Stack &S,SNode e); /*将结点e压入栈*/% I4 @$ T: h; M/ D5 p9 d0 F
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/9 i: x6 q/ S6 J
2 b. E# a0 h% r0 a. L2 z
/*表达式计算器相关函数*/
5 K! y0 g* Y* [* O* schar get_precede(char s,char c); /*判断运算符s和c的优先级*/) |1 g6 [% H& ^8 d4 ?* `. M' j8 L/ P, g
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/9 }, R8 _+ M5 j k3 r4 Z/ H/ V+ l
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
4 ]( O2 _% ~/ g8 |float compute(); /*表达式结算器主函数*/
! i" Q: p: j Nchar *killzero(float result); /*去掉结果后面的0*/ ; R# h2 f L) ]) w' ?
- c0 w$ f( o: b Iint InitStack(Stack &S)4 p' Z3 t4 g! G& K
{. N2 K7 J4 @, J
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));! j2 ~5 ]3 G4 i. Y7 }
if(S.base==NULL)
: h- T( l9 r9 t0 p" t6 K8 B {* O3 |% t/ O- X0 j3 p" Z6 }
printf("动态分配内存失败!");' c' h" n3 ?" z; z
return -1;
, N/ z5 L/ J) H# q. h4 ^ }# v# a, H5 }. X) r3 \1 g6 x4 ^
S.top=S.base;% B: V2 A& o$ r, @ R0 t/ C9 h/ h
S.size=STACK_SIZE;
' }1 k; C& w7 w7 d return 0;: k2 L% _! W# ^. d9 C5 T; m8 V, E" F0 E
}
5 j8 h8 s3 V' F, l6 l: B4 C$ X+ {, Z5 R
int DestroyStack(Stack &S)4 C( d1 ` q, X
{# j9 w( x% w1 a6 l4 i8 d0 C4 V
free(S.base);; P! ^# l5 `- ] W0 ^% ~3 x
return 0;% R& Q3 p% z8 s& a: k: `. w
}
x0 k3 _3 ]2 S. D) D
5 J! l5 K; j* g2 O+ rint ClearStack(Stack &S)
0 d* n0 D3 T1 s. e{% t8 [; }9 K: M- h
S.top=S.base;+ n; C* T- Z4 Q+ v. u0 v) N$ P: T
return 0;. H1 E% X% S; [& X1 B
}, A6 s% E2 t9 J
: l/ i9 D4 {: a- _9 f8 ~7 dint GetTop(Stack S,SNode &e)# v7 B0 G1 O3 ?+ C" a! Q9 x. `
{
/ t! V1 A+ U3 F if(S.top==S.base)2 x# O; L% o1 Y; s5 ~
{/ k U( z4 U9 e. s3 t" h. w
printf("栈以为空!");
3 _' q8 W2 N3 f s" k* D return -1;' {" [" G; G5 u3 D/ |
}
% X4 O4 G4 @# a9 ` e=*(S.top-1);
7 U0 r0 ^" _) } return 0;
; l$ G8 d/ z& B7 M U x( X; f/ x}6 H3 _* j& q. i' j. N. `% W s9 q
v& A0 x% _1 W! [1 B. V
int Push(Stack &S,SNode e). A5 v. \( e- M, ?4 a
{
/ h6 l! U9 w3 _8 C7 Z" [& h% I* o if(S.top-S.base>=S.size)' c/ ~5 b, o! G. @
{5 F, ~/ f# r% D& p) I
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
Q& S8 W9 ?4 w; L0 f6 V) P. b if(S.base==NULL)
4 H5 ~4 y$ F3 }4 s {
; J0 s! m* ?" _0 p2 U- ^ printf("动态分配内存失败!");1 W9 F# B% Z; m/ s0 e \
return -1;) d1 W u0 ], `4 c% k3 K
}
( T. D5 w0 X, S4 Q, W9 ] S.top=S.base+S.size;/ h0 R. M2 B& j7 N, o" \2 T
S.size+=APPEND_SIZE;% v0 b3 V& b# _* L) V
}8 R3 T1 u* e, \2 b9 H7 Y! [
*S.top=e;
# c# |9 T3 ?9 D% E8 b S.top++;
9 ]. e+ J. u Z) P. v- h& y return 0;8 b$ K0 g4 _; ]. o" l0 n( A# t
}! j0 D* p$ J \
- S. I: S- `7 v9 u% U3 _3 k; U
int Pop(Stack &S,SNode &e)
# i- W- u6 `* J. Y5 G* S{! G F/ u B# _8 d
if(S.top==S.base)
# r- { i. h) ]& ]& M$ r {2 |' F: K3 B7 `8 T$ u7 l
printf("栈为空!");
! c1 ~! [4 m. N1 m0 Z5 L6 F return -1;" Q7 F" p8 ~4 x2 J
}
# Y, t5 g/ B1 K' k1 `" d& x/ p e=*(S.top-1);
o! ^1 p! a* J) O) | S.top--;
8 [2 J( k- V! o) I/ U3 m return 0;+ `2 |4 h1 k0 C2 E: @
}
! ~5 x M: f' R% N
6 b) h( Y3 {- I& lchar get_precede(char s,char c)
3 {% R; p1 ]3 J3 ~5 J+ i{7 a( m( G/ |9 u# j- ?9 o8 x
switch(s)0 ?$ X( @4 m( r, w! w4 z
{
5 D6 |9 j+ N# B& B, U0 S5 Q+ r case '+': & f3 s* y, o8 @6 A! _ ~4 `
case '-':
& {$ _" L* F6 v' C6 O. ^7 K' \( } if(c=='+'||c=='-')6 P% t1 D( D( J; d2 B
return '>';* U3 h' N' s. w8 q. v w
else if(c=='*'||c=='/')
% h* p$ [4 [# {( ?' p( O& ^ return '<';; K( X; t& D2 z+ O: Q
else if(c=='(')6 r6 i. n9 Y+ b) l8 _
return '<';
6 x* c; \' \5 N$ b else if(c==')')" s* {2 b) q% g
return '>';
: e- U- O1 J4 [# } ` else ) O7 Z! b3 z/ L x$ q& C: j
return '>';
# F p( T. R" a- n& ] case '*':1 u. Y# }0 {$ B: I# `7 k
case '/':
3 |- K; u y4 s; O1 ] if(c=='+'||c=='-')) W, c2 D. d* }' b
return '>';
5 ]; Q* k7 D6 a6 I; h8 S8 W else if(c=='*'||c=='/')$ [! i; Z& J: h; v! v
return '>';2 Q+ E& L% F$ f
else if(c=='(')9 ^ O1 z4 Z4 U1 l l) C" N1 J4 h
return '<';
' ]' d5 n7 [0 w+ V; E' U" \! n else if(c==')'), ^+ i2 }& w& j% A, J
return '>';9 V7 N+ t6 v! A7 I" \. H3 x7 @* m
else
: z! r: S. F! C% w return '>';( P( x5 N8 {4 \* E9 J
case '(':
) `) N, V5 U( L if(c=='+'||c=='-')4 T9 F4 R& H* }9 W8 n, G
return '<';
4 v q; ~, m+ C7 m# s2 q else if(c=='*'||c=='/')
; g& H# s3 k" P return '<';
- J/ t4 ]0 ?+ W else if(c=='(')
9 _7 ~/ _& _# w( J3 R7 A return '<';
" w7 \) t" H7 [1 @ else if(c==')')8 e! _7 {5 ?2 D- {/ {! D/ ?) n
return '=';
; D3 Y8 X* E# I% G else; Q: A% _0 M5 l
return 'E';- K% k$ Y$ `- k6 w2 R
case ')':7 M5 K) z8 S; |7 T- V g) I
if(c=='+'||c=='-')$ S, o; m1 F6 g/ @! J2 g" x! l
return '>';5 c2 T8 H6 N0 m" f
else if(c=='*'||c=='/')
; R! {' R3 l" e8 ~/ e0 m( ` return '>';
: r1 X' A+ y" f0 C k/ K else if(c=='(')
5 c b) @# r9 O* D9 N3 U return 'E';
1 b7 I' N! i3 R. k. F else if(c==')')6 y" X! X0 }' r* a# k8 [
return '>';! |2 w7 E6 J1 u
else
% e% N# b% O7 @ return '>';
1 {9 n! J5 T9 ?! U" ? case '#':- y+ @: k! y8 l- d1 |1 I) s! |
if(c=='+'||c=='-') h) |* x# X7 m- R, ]1 [+ a% q
return '<';
+ z2 k4 t+ Y/ D3 U. e7 H else if(c=='*'||c=='/')1 S" Z J; K. ^) D
return '<';
3 G" G9 S F) C; `5 D else if(c=='(')
' G6 J. w7 u+ w% E return '<';
% ], w9 {1 c0 z1 V7 u' |6 ]# ] else if(c==')')
! g9 ` o u+ N u6 k return 'E';
$ P+ l" c% g$ [0 |5 p" B+ ] else
$ s1 a6 T. `; U return '=';
/ f! c" s4 x7 D0 V% g( F default:
6 j% Z9 j$ \. x break;
( z# e, i/ J7 k+ [ }
: w' w4 t$ J6 ~# p: b# Y m, f return 0; ; F# h4 V/ r, e
}
9 X: r: Z' l0 w" X' l( U1 W4 J# r* F7 I& v! S0 W7 l2 u
int isOpr(char c)
# g- _+ `1 U J: x{
& x5 o. U" P6 h3 s1 x( R5 _ if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')" C% {5 \' b N+ t
return 0;6 Z: q! z: M9 w
else 2 [/ h3 z: K2 T2 r
return 1;
; \$ x: B; o0 C, ~- O: s/ A; O) T}
$ |# b+ }- L# G5 Y2 q* T, S7 n& H5 q I8 }
float operate(float x, char opr, float y)
& \+ l1 H3 Q8 O8 @# z; h{
7 p$ I7 O/ N* {( K; P; T float result;
7 B2 J4 J/ R/ I/ V u switch (opr)
: W$ X' K2 y8 D# u: y* Z2 t {
% I" @. Y$ d' v case '+': 0 Q# W- [* S, ]' S& L d
result = x + y;- _4 M- [; m0 T$ W: l
break;
3 ]9 S" M& s' m- t case '-':
% l$ y: Q/ ]4 d) h: M# i& F result = x - y;
/ H5 r$ K( e/ K* F- W" q" z% e0 o break;
& o+ C/ E9 a( X4 ~+ p7 O, m case '*':
, D% Y2 i" Q% L% r9 O: V9 F p3 r result = x * y;
" o; l! d' A9 t5 x5 l break;8 w: x4 J) @# O7 N. a2 w Z
case '/': 4 `7 ]4 Y: N6 [/ I. J7 g5 Z, [4 w
if (y == 0)3 y6 ~$ `# K1 u1 n2 v# `4 v( c
{
9 T6 l3 ], x: O. Z0 w e; j printf("Divided by zero!\n");& A/ x6 K* b& D3 ?- c
return 0;$ ]5 k% o3 L) v+ \3 N/ [" a' T' a
}
. A! k& _7 k6 s3 O; } else! j4 D6 q1 ]& b. Q
{0 o2 b8 u$ {: k& K* m# t+ B
result = x / y;
7 Q" P+ K. n9 Y/ q$ t4 h5 e break;7 V% O" q* m1 a
}
& E* M2 c4 ]0 x5 M. N6 ^ default:
2 @8 F, k$ P" ]. c, ] printf("Bad Input.\n");
4 f9 e& N6 u' ^. y- t return 0;$ P/ O+ G& C# P% r, r/ E
}" U; `# \0 P5 e# [0 `
return result;+ @; F1 b0 U$ i& O" ?
}
" O3 l* |7 i; K0 k! \/ V
4 t* D0 Y& z1 Ffloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
. A8 f" x0 D" s* t5 I4 Y{
5 G: L% w3 w$ d7 m7 V9 B( n1 q Stack optr,opnd;6 z9 _0 d" J) o$ m( F+ h
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
$ I |4 Z; j3 I- Y5 E% Z; M) h char c;
6 S8 ~( H' L0 e* g- A char buf[16];5 l3 F0 r6 ^2 D* l
int i=0;
( ]8 k6 k+ Y& v 8 v8 @+ E+ A- E9 s
InitStack(optr); /*用于寄存运算符*/% I6 `' V% i0 e% I. X" ?0 D6 j
InitStack(opnd); /*用于寄存操作数和计算结果*/
2 |" X3 w) v8 f% ] memset(buf,0,sizeof(buf)); c! Y) v* @& Q
0 U1 u8 M9 P# d2 x( | printf("Enter your expression:");1 S5 A5 u) [' u! e' O
?. W# O9 |: e# G5 i opr_in.ch='#';
" _, y$ v7 m4 B8 V! S Push(optr,opr_in); /*'#'入栈*/9 W- z# I0 `3 D8 i/ _ u
GetTop(optr,opr_top);- I p2 k- I0 E
c=getchar();
& t/ s( m8 n. T* E while(c!='='||opr_top.ch!='#')
# T) A7 @# B' s5 q# B: c {" e) Y/ m- A1 S# w
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
& a- A9 A( ?- x9 K* Q {
' ?% c' u2 X$ B' Y" k9 v buf=c;0 ]" f0 V9 y5 N. Z- \8 t
i++;
9 @' k; M$ g- u8 e3 W% u; _ c=getchar();: y7 R" i+ Y; V; U1 E; E
}3 n- W e9 P, N6 o2 o) v
else /*是运算符*/
; _" g' h" F* C& v# S {6 [% p+ a; X- u0 {
buf='\0';
/ Y8 u8 O5 e1 K* W. J0 b if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
+ B7 F. j( K3 @0 R9 X9 L6 ^# } {
7 `3 q7 L; j& ]) i2 X opn_in.data=(float)atof(buf);
8 K8 o: L/ x- [* F# v( a# K Push(opnd,opn_in);# _8 ?( ?4 e" o
printf("opnd入栈:[%f]\n",opn_in.data);* w- _% a6 t3 j& l
i=0;1 u7 Z7 i2 k6 C& ?* m* w1 |! N
memset(buf,0,sizeof(buf));! [, g- r6 |3 J: q2 V
}; f! P" R3 c' Q' m, l. h4 o) }; Z
opr_in.ch=c;
- {& ^; p+ C' d+ H( ~ switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/: P0 k. R I6 k" u
{
3 k1 {% g5 z3 _! j case '<': /*优先级小于栈顶结点,则运算符入栈*/2 ~8 ^4 y7 q. u6 S8 V( t. X# a
Push(optr,opr_in);1 W1 y- y6 o: k! A# H
printf("optr入栈:[%c]\n",opr_in.ch);' E) B1 g' H! T+ D4 _& F
c=getchar();
0 \& d2 ~- [2 f8 C break;
1 H- Y8 S, u* p$ y6 R) S# l case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
$ a# M# P+ I; g% H, ?% O4 F Pop(optr,e);4 \( G& f, X2 `0 A2 T o9 Y
printf("optr出栈:去掉括号\n");$ d2 n) f$ t4 m2 y5 d
c=getchar();' I9 `6 E8 ^! D) ]
break;
6 W* C; ~' P4 A' ?' K# n3 i& M* D case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/. C4 b$ t3 X5 I3 ^2 u+ z- u, |
Pop(optr,opr_t);& u! W% p7 J7 ?" D" A
printf("optr出栈:[%c]\n",opr_t.ch);
( \* X& b0 n! Y( H* M if(Pop(opnd,b)<0)7 P/ ^$ C/ M; O( y2 |
{
" \2 B: j/ k5 _ printf("Bad Input!\n");5 f7 |# ^) n/ d: v3 ^! v: A
fflush(stdin);8 f7 W; m A8 E d! W
return -1;( m* ?: e* m4 i
}
% W+ d+ w {3 f$ z printf("opnd出栈:[%f]\n",b.data);
+ _0 W* V! l1 i/ ?& v+ |1 ? if(Pop(opnd,a)<0)
1 {8 ~( U! W i5 d {% I) u) A1 v/ ]9 Q7 G; t
printf("Bad Input!\n");- h$ d- h) O }+ E i4 R4 A0 I
fflush(stdin);
# s' @& q2 X: ^# D) r7 D8 e return -1;
2 H7 ~: T# y, }5 Z: |- j5 [2 n }
2 ?' ~4 Z9 Z/ y6 k# d: [ printf("opnd出栈:[%f]\n",a.data);
7 B, r4 A9 A! X: X& E5 \) s opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1 D e1 e' `, C Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
; S( f T. s# l; R& x% v printf("结果入栈:[%f]\n",opn_tmp.data);
8 q8 U1 H Y! z6 I' A6 S break;
8 {! p5 A/ m' d& E6 K* ~% M }
8 X# {$ H8 N( h6 z }
$ M/ p+ a3 |0 s1 ?, i1 U/ J* w. I GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 5 H8 F a" @ [# i5 b4 d
}
- w7 S y1 q$ d% I! v3 D3 P GetTop(opnd,opn_tmp);" y) q) y" @9 p0 b. U5 }' c) \' ?
DestroyStack(optr); A7 x/ U+ k4 V* d" U. _
DestroyStack(opnd);
) g* d" ~# c @! Y9 \, Q: m return opn_tmp.data;3 p4 W& o8 t* _0 A
}
: @7 K. y. ]% J1 a0 n0 N4 c( A4 e t7 u. D
char *killzero(char *res,float result)
$ X# D% x R% o: M4 X _0 d8 t{
# }, e, B: `/ n+ o+ h: ] int i;6 ~( z! R4 v- g% V, Q
: T' i8 s, z3 F9 Z6 E$ O% k sprintf(res,"%f",result);4 Y7 j+ I' i# J1 M- o8 c
i=(int)strlen(res)-1;
$ B1 l8 ?, ?7 k while(i&&res=='0')
* c' x, ]7 V4 o6 ]" T; N {( v6 S* F4 ?; ?1 k3 y" q% e/ g g! {
res='\0'; o- a9 j; i9 D) E- M' M
i--;# F% O) ]/ Q5 k9 b" s, @
}
+ m3 X7 b. y/ Z; U2 u if(res=='.')
1 Y O3 ]3 M) X' _' B; N0 Z/ h res='\0';3 q* f0 @- I' ]- i4 P$ N5 M" F4 Q
return res;
3 _8 n; i6 w/ d) K0 I) `}7 [9 T* m5 q! O
4 U. T! k. M$ S% A U
int main()- P6 k1 W. J2 f/ E( f: a
{+ c3 Y4 Z, o, @3 q# u
char ch;
& z2 Y* u# t9 b0 E$ y" V char res[64];
: Y1 Y( o% w1 {' X: E4 ? float result;* h1 N0 X& [$ k% l1 e+ j4 F
while(1)
) J: y8 u2 X" ?3 ?$ f% n {# q# B: ?8 `4 w( B: A$ ?" T
result=compute();" u. W! g+ {+ A) q' ?0 o/ M
printf("\nThe result is:%s\n",killzero(res,result));
8 ?8 v. L$ h. `+ e5 @. J printf("Do you want to continue(y/n)?:") ;
1 S2 N* R+ |/ R2 A: {4 x ch=getch();+ ?4 R% [3 B' r- b( N: t+ G% ^
putchar(ch);
8 @, w8 B: K5 D, _! R6 f2 Q if(ch=='n'||ch=='N')
8 A( P; ^+ }: H0 s' R6 } break;# ` |5 d' N4 |; R% P- Q
else
+ Z5 Y+ ]2 _1 x6 f$ c system("cls");
# c5 p J6 k8 w# P* h }
y% Z9 y5 z5 i return 0;6 u6 Y1 s% K+ H: O& e8 G) }
}8 n1 @4 L0 J7 ]; `* O) Q
! {4 x: T5 n% E[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|