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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.( K8 u1 i, q. s( @
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
F% G s# x7 ~! e; K/**************表达式计算器************/
/ r. F5 ^) _8 Q# W$ b( V3 s6 S) e#include <stdio.h>
) W: A' |- O0 x, L#include <stdlib.h>
+ p4 c- d7 u# L. y0 x' s7 g; i#include <string.h>. A1 T: V2 c4 {5 G
#include <conio.h>
! J" `: {' T0 K; n, L: A#include <malloc.h>
' T) R# p2 I; u9 q2 M+ Z, X. ?9 E+ U8 G! ]+ K
#define STACK_SIZE 100
+ ]- ]5 Y/ Z$ T+ d#define APPEND_SIZE 103 g8 W( C! h$ k( q4 H
" H" U" ?* @. z" d- L+ K
struct SNode{
8 A" ]# H T, p% _1 J, ?0 r, d" [+ @ float data; /*存放操作数或者计算结果*/
' Q+ J0 V1 u# x) t( Q- O char ch; /*存放运算符*/* N$ }. _ E+ p* N- z
};
8 I0 `( h; S0 ]$ @# i$ C/ B% ~$ G* U& W% Q9 ]$ l
struct Stack{
9 z! j: d4 ^5 d: u$ ], X SNode *top;
6 k' @. e# x& u9 o" o! I! u SNode *base;
: |$ n0 O% h. Z! r" x int size;
2 c6 |* S+ X' i/ h& e};- Q- ^- x g1 x
0 x4 l: {# d% ~- g5 ^" u- S8 ?
/*栈操作函数*/
4 M9 A; b$ j( i; D3 Bint InitStack(Stack &S); /*创建栈*/
5 [& {9 D* _" n0 h; }+ fint DestroyStack(Stack &S); /*销毁栈*/
; E9 d9 O ~/ Z$ w) Mint ClearStack(Stack &S); /*清空栈*/
4 d, B7 m+ C; _+ ]* T% Fint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
' f1 U3 X2 F. N: P/ F# nint Push(Stack &S,SNode e); /*将结点e压入栈*/
; y" X9 n7 W; L/ A5 M, tint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/! F4 _/ h+ J" a
4 b0 B& G! B2 e) x4 y8 `/*表达式计算器相关函数*/( C) F. j/ I" X4 x$ S
char get_precede(char s,char c); /*判断运算符s和c的优先级*/9 B- M! k) r# h
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/# z' s7 m# i: a0 y
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/2 L& L2 J9 r8 E* _- R) o
float compute(); /*表达式结算器主函数*/$ r9 x6 r% I! g7 j m
char *killzero(float result); /*去掉结果后面的0*/ & w5 w5 E( g6 `1 h
4 L; M2 j5 X) o6 e
int InitStack(Stack &S)2 O- f, |- n' d$ i
{1 ~! @* r6 m# r# x6 U4 c6 S0 a
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));+ O8 S, A0 \, o7 t
if(S.base==NULL)
2 i! ]$ e) N' F/ }8 [ I& ^$ V {
5 r- e1 T, X9 g/ V+ H printf("动态分配内存失败!");
/ ?7 c3 B4 Q! P4 C* Z return -1;
7 T5 z) [) G+ J$ g0 \- U }
3 R( C$ k, q) c& p S.top=S.base;
- M \0 u0 S- v7 m S.size=STACK_SIZE;
4 Y/ @" r/ v+ c# t8 p! ? m return 0;
! |, x( ^+ @8 t; T7 \) g}) }* H& m- G4 }/ u5 w- ^4 k
7 b0 Q3 S* U) U) T$ [( g" Nint DestroyStack(Stack &S)2 K' Y! m/ d7 `8 z& `, ?+ }
{$ G v* G+ X+ {& ~2 z
free(S.base);. b2 }* Z4 c2 h" U8 L8 _
return 0;
" i, O5 {; b$ G9 ^* i}* l; c* F k9 e! m1 o1 o# m
5 B$ F) o2 K3 I% e t7 `, [
int ClearStack(Stack &S)
6 n, U1 Y7 R( \' \- y ]7 T{/ b7 m5 {5 z+ k5 d7 Z" [
S.top=S.base;6 ~0 p% E( a+ Y3 o- e8 v
return 0;
( w! T+ Z' h+ X( } ^/ ^* A}
% ]8 Z1 O" f. V8 A0 I& k* m$ r% e, m" N6 f+ L( q6 k9 C% ?- P2 w, w0 E
int GetTop(Stack S,SNode &e)/ n1 [! [8 M, b( G+ ?, d0 i
{
4 P8 H2 `. m7 `' {" C" f if(S.top==S.base)
- Z2 r% J/ w1 Z% E {2 k/ x2 N5 E% C0 Y. q
printf("栈以为空!");
/ N8 z2 o8 J/ v6 T% b- W return -1;. J+ M, P: \3 H5 ~; T
}" r. y4 K3 B4 q2 Y5 G
e=*(S.top-1);; @1 i- {/ B( |1 l$ h9 Z
return 0;
+ u0 K& r1 u- O6 H( o}
5 Z, S+ b4 B/ w1 J3 x! j* i" y* G- V' r. U/ ~
int Push(Stack &S,SNode e)
" y5 Z4 x" T- ^1 F5 y2 u( h: J0 ~{
+ g% T! q6 n) u+ b if(S.top-S.base>=S.size)+ ~! y$ V6 u9 K0 Y6 a
{
V$ g9 H8 a% l5 b8 d8 A3 B S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));7 n r- T; S0 O' t
if(S.base==NULL)8 j" v$ t3 n1 w5 x$ R" n
{
a- A+ N. n2 O0 x3 ?: ~1 C4 b printf("动态分配内存失败!");
, M+ p0 y+ h8 ^0 k- u return -1;0 n5 n5 _3 N6 ?7 q5 o
}
Q7 P: f2 A4 e+ a3 _' h% F S.top=S.base+S.size;3 k3 Y6 @. A& a3 j T
S.size+=APPEND_SIZE;7 M- ]0 L$ T4 p' T# z3 n& @( i
}8 A( u/ M+ Y% A( M! N
*S.top=e; {; q2 n# M( Q: v. c
S.top++;4 x/ c6 O% K* t$ |" @, \0 c
return 0;* _1 n# E6 }$ x# {# _# Z
}% U% H; D* Q8 U& G! h6 I6 e5 o
- ]- R3 Q$ U' e" C1 Q+ Z
int Pop(Stack &S,SNode &e)6 w) i+ `# R7 `, z1 B+ q
{
6 y, C' N- @4 N2 I if(S.top==S.base)
^: `2 `/ m! b1 z. c3 I {
' v. r' H7 T& }1 W V printf("栈为空!");
1 b: O: F0 C( p/ R! @+ D return -1;" m* a+ F' ?' b$ B
}
! _3 E: c* g, X! f e=*(S.top-1);6 L+ F9 Y/ Q7 m
S.top--;
: u, Q# Q9 g7 ~" b( x return 0;
- a0 H. P5 q$ l( ]}
# v6 T$ P: i1 b2 M( I' t2 T. q
char get_precede(char s,char c); G* x% h" S" |7 h. M
{, C( m3 |2 k( Z0 N1 k A5 }
switch(s)
/ Z8 P* U1 C- w/ q$ z6 p! b {6 Y; G: G1 T2 M( H/ j0 U
case '+': 4 x/ r J/ j5 y7 [: ^
case '-':3 z* q, ]5 P1 M
if(c=='+'||c=='-')
- w4 |% F @2 D return '>';
; s' ~6 j( R7 [ else if(c=='*'||c=='/'). W) {6 \$ ^4 w' @% X; M
return '<';
! l4 @% [7 b% @) S1 B else if(c=='(')4 w% A( V0 h! D5 Z& T2 l* L! g2 k
return '<';. n* D7 {# w, ], |0 x3 r
else if(c==')'). \) Q2 o4 w9 t, G- F- F
return '>'; N, f) u( d4 Z9 S) F
else * c+ `6 j8 ~2 E* c9 ]7 G
return '>';+ ] }+ \: ^! O" V1 N0 _! H# j
case '*':
$ I; \) T1 X$ D: P V; ^9 A! C case '/':
* V: L. x0 W+ ^/ @7 x if(c=='+'||c=='-')
8 C0 |+ q) T8 I return '>';
) t) Z1 m* n5 _( l7 W. i else if(c=='*'||c=='/')! g$ d) \- V4 `+ I4 v a, p
return '>';! W0 e. }+ X, o& S {
else if(c=='(')
3 z& L" k ?! z( H return '<';8 N( Z: t5 A: r: o3 G7 E; i8 h
else if(c==')')
) x1 W! |9 W7 \$ o, ^0 j$ D0 y. t- | return '>';
3 x. A% o* u$ ~) U7 G4 ?7 m4 c else/ B/ O% O; n' c! x( I
return '>';1 Y8 W" B! u% T* Y( r; h
case '(':4 V% E+ B4 P. e
if(c=='+'||c=='-')
' Z' n" h1 t: @ c" A) T return '<';
5 o N+ e$ @4 e) u2 x% ` else if(c=='*'||c=='/')
# G: T- I( A `1 c& O! O return '<';/ `+ R1 n/ k2 L) k
else if(c=='(')
" }) F3 T k1 U b return '<';
: Y- t0 K: |- y+ h else if(c==')')
) A* D0 a$ j$ e4 f return '=';
+ m; y( y/ s# ~2 T/ ~4 P, F! U else* T% D% M$ a7 c; z; c
return 'E';5 Y' g( g! j; P% @) ~" E# B
case ')':2 ?; i3 R2 T7 H b1 j- U- ?* @2 a
if(c=='+'||c=='-')" k: P6 h; |% k6 y8 V# ]4 G+ m- J
return '>';
0 X& b' x* ]) d( B! z$ p$ b7 F else if(c=='*'||c=='/')
9 r6 K V. g1 I) ] return '>';6 P8 w' }+ P) K Q4 Y& I a1 g
else if(c=='(')
0 b! i, E. r/ X: y- N5 l* f/ I return 'E';
, \- I9 Z, q3 S else if(c==')'). `- n( N) m; V6 b
return '>';
5 a$ ^* a" E. D: N4 i% k else
7 k4 ~6 n1 Y% L3 ^9 M8 U return '>';
! f0 y, c b4 c9 d. o* x( b* l& H case '#':
+ ?- H( U% |: c" l if(c=='+'||c=='-')0 Y! A$ c& p6 b! t: i
return '<';7 M# {! s" p* \
else if(c=='*'||c=='/')
- C [. T8 I8 A. \$ R1 V4 v2 q1 \ return '<';
, i" D5 k$ U# b8 N0 K) d0 p! R+ _ else if(c=='(')8 e3 @9 d" [/ F( g% _: K3 X
return '<';
) ^( D3 ]0 y% r$ I: I4 M8 ~ I3 B! n else if(c==')')! F8 B8 \( G* K& I- i2 s7 }
return 'E';) [) _& c$ G) r; ]5 d3 J% K
else \% A1 y, U q
return '=';
- S/ }* i3 Y& q$ h default:
6 F. }5 d u T, n+ z3 @ break;) [6 G! h" ?( v/ m3 a( b
}. Z( C: I* v4 @# @0 R1 q+ o
return 0;
q' Q; o- G# w, _( D5 f' i) y}
' f( j0 S) e9 t4 a
- J- I+ Z8 x U' I. kint isOpr(char c)" @1 ~ y0 {0 B& ~- ~' }
{% {0 w. c2 u, p* Y0 d
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
1 k! h5 e* s3 R return 0;
$ S, x5 g& O! h) }6 F; B5 } else 9 V( c |* c$ ?0 s+ D
return 1;
. n6 U. f; K4 b3 z- A}
$ e+ V# N4 c' G2 m1 H1 [$ @+ a; _% w. I
float operate(float x, char opr, float y)
% d9 R: S& u+ U3 ]# }8 _{( ?+ W" B3 ~* \ u3 [
float result;( {" s7 s: ?) U
switch (opr)
6 c4 E' q6 w4 u: p( L' }4 L {
. d8 H+ |1 M8 ~+ O case '+':
, N0 g: a/ N0 J. H result = x + y;' [) t8 a4 @* G. f2 b+ z
break;
* {0 j; H2 F4 b, c case '-':
0 `+ W$ z% ?( E- u- N result = x - y;+ p$ V) M- y9 Z: K; X. e+ \& a
break;
* p; L, ]9 n+ R) P: u case '*': 7 Q e, g0 j0 L0 P% V; m5 {# k
result = x * y;
% p* ^+ ~' x! i, |" y break;3 e, x, u3 J) r+ I$ c ~
case '/':
4 j: q- P- i4 {0 s4 Y' E if (y == 0)9 k, r, G- |% z) T$ ?7 N' w& K4 @
{
! T5 [! L J1 o! H; v- r! h printf("Divided by zero!\n");2 P& u" q( I# @: N! N: p
return 0;
! }$ g1 J! Y4 X5 [9 K) ?- q; z }# J& d+ X* q( W; {' S/ A: `" T
else
9 }* n( R: U, C3 @+ @' ? {
1 L! Q( U. O* H4 J( \ result = x / y;
' N7 [; K8 p; M6 S5 @) [6 Q) d break;
* B( `) k7 H; i' z% m9 s- E7 } }
6 F0 \" r% r$ |- _3 N default:
# K- c* n: V# b' n printf("Bad Input.\n");
9 b, `: o% ~& }' ~7 Y3 V8 @ return 0;$ S4 b" \6 }0 X! o. V2 q
}
* v" s$ v7 ?( z6 @ return result;4 Z5 y, b# X; G5 h. d1 |
} 8 [# R" S. @* `' A G2 o$ m
% \0 t5 w8 h8 l E9 Nfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/! W+ W; |9 _; L' l
{3 A- B: h3 Z% u N
Stack optr,opnd;
* _5 p& B- W$ X struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
- M: o1 x* B& @0 R0 M" j4 b char c; r8 i) B+ x l; m K+ G
char buf[16];
; o& X( O, s0 q" L: z. X int i=0;
! m) L2 E8 V: j0 `- G4 J/ R! X
" x9 g6 c% X Z: C1 | InitStack(optr); /*用于寄存运算符*/
# ~0 k, U; ^ w3 l$ v InitStack(opnd); /*用于寄存操作数和计算结果*/
3 x ^$ d$ f9 e B/ M1 ` memset(buf,0,sizeof(buf));
) ]! }! @' P# {! g8 s; K ! _5 V% l5 r2 X; ~
printf("Enter your expression:");$ e7 c/ G# |: c6 \$ v. w% f
- H/ a( d9 c! B" M2 U opr_in.ch='#';9 f8 @, \+ B+ F# C& N; f% j
Push(optr,opr_in); /*'#'入栈*/
) }( f W0 b8 O! u! \5 w GetTop(optr,opr_top);2 C& y) u6 h: s" ]; H- W' {1 ^2 @- x
c=getchar();& |1 k. \ K: M, m
while(c!='='||opr_top.ch!='#')
# G! b# w3 }, {( u3 [- E$ M {
; X L. ^6 |% o4 ~% O* W' p if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
' M, I" T. D! m2 p5 p {
. w4 c& ~9 A2 d' ^9 o& U. t buf=c;
' K- Y8 ] _5 V3 F) y! M# U i++;" {. [" [. R. J
c=getchar();
3 j7 f2 h4 i- F0 Y% b }
9 t3 g/ _0 i$ Z$ B/ r/ j5 }# G else /*是运算符*/* g9 ^* s B, W, E- B6 l2 \
{
- U$ P) C S4 m! ^/ ^. _" H" l* j buf='\0';
: A9 `, d' j- U' v$ K; I( o if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/8 b" l" L5 ?8 Y d& B5 A1 P% J
{
( Q1 {. M" N* e# v; k opn_in.data=(float)atof(buf);
0 m- |# {/ M' V8 x4 i Push(opnd,opn_in);
3 i5 l; R8 \4 B8 n1 v- T printf("opnd入栈:[%f]\n",opn_in.data);% ]$ {6 V: e2 i9 K6 q( i" T+ z7 K9 t1 s* b
i=0;2 `: B1 X% r3 C5 U+ t `5 J
memset(buf,0,sizeof(buf));
& b# t" N7 A* Z$ k7 j5 ~ }1 `# q) o& P- @; }7 b0 L4 F
opr_in.ch=c;# J7 }" [; J2 l$ o
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/) s% \! N1 b% Y4 X( t
{
: B* ~+ A! b0 `# m8 p" R3 _ case '<': /*优先级小于栈顶结点,则运算符入栈*/ Q: W( U& A# k- Y$ E
Push(optr,opr_in);( X3 y7 ~3 c$ P0 C$ V8 F7 q
printf("optr入栈:[%c]\n",opr_in.ch);
+ _( e$ m7 c% F8 d: V! z1 n c=getchar();# c! X; ?1 ]9 ~4 N& h4 K
break;, J- H$ T- e! r- O+ F
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/" b) x# Z% }# q1 P1 B* f5 O7 |
Pop(optr,e);8 j* e& a( D; R$ c
printf("optr出栈:去掉括号\n");
* G4 d; u8 Z% b: W c=getchar();
0 m$ P w" ~* s/ _6 ^- d break;4 R: G, r9 l5 B2 r) I7 q. o7 S
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/9 G1 @; T' w, @8 T- b
Pop(optr,opr_t);
0 p& ~/ m' A7 C2 j" e8 i printf("optr出栈:[%c]\n",opr_t.ch);4 e4 U& B& m. t7 B5 c+ v9 q0 K
if(Pop(opnd,b)<0)
4 i! R" V/ V0 A% u/ L/ j2 w: b, E {
' |* u$ C/ F# p% S$ |0 G; A printf("Bad Input!\n");1 P& Z) D4 ?' e+ x/ P" }, R* h
fflush(stdin);
% m& D- p$ S: h' s return -1;
( T1 S; Z1 G# A8 {0 j }
5 j( h2 |7 `5 a2 W; H0 p& ~# e4 o printf("opnd出栈:[%f]\n",b.data);9 e3 @% w s9 N+ |
if(Pop(opnd,a)<0)5 [/ g( q$ d) g3 E( y
{
9 y3 j& z# J0 @. m5 f, k ^0 |; E printf("Bad Input!\n");
t) c: {/ K4 @, K+ I: y& a fflush(stdin);1 a$ I! U- C2 a5 ^8 r e# i6 }" N
return -1;+ ^' S# j9 o* h ~% i
}9 A* e1 r" Z$ c7 z
printf("opnd出栈:[%f]\n",a.data);" @; G% l+ c; e( n3 {# [% \
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
, t- }0 ~" \& @6 E Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
- p u- ~$ E/ p; b5 Z; U printf("结果入栈:[%f]\n",opn_tmp.data);
* Y$ Z) G, p% P3 _3 Z. @ break;0 k2 J2 B% Q' x& N3 l/ }+ N; [
}; R; v1 @; j8 @2 d2 M
}
) _( ?" O. v4 J! \. R K GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
' u4 z1 T0 b' ?6 k6 j& L5 A$ `; U }# C7 f" _5 |$ G9 v; x9 y
GetTop(opnd,opn_tmp);' \& v0 N; \3 ?! A8 I' [
DestroyStack(optr);7 i+ r* |/ Z/ D! C% W q, _+ [
DestroyStack(opnd);: v; e% O( y7 `( O* m& t; b
return opn_tmp.data;
4 }8 r% V7 H6 ], f" K7 I5 `6 h}
1 b+ L9 a& \1 C2 U
/ n% P4 |9 G) x: v( Q( R- p1 w$ cchar *killzero(char *res,float result)
9 z. K X4 s5 l/ B$ M{% `1 }- r' N5 ?
int i;
2 Y4 `( B& T+ }, e8 C' l. a+ I
9 i: O9 \. E- e& D sprintf(res,"%f",result);9 I# A! \; i+ @: J- s) C, Y
i=(int)strlen(res)-1;
+ P9 e7 i! F8 j( E% k" C% J while(i&&res=='0')
b. \3 `5 v* T. C {
9 {& ~/ A6 [% p/ P \ res='\0';6 U/ r* n# I5 r6 k
i--;
6 I, W6 v( v5 Z8 n+ M4 P }
/ s; T# c! C2 t1 e r! l6 F; h% S if(res=='.')
5 H7 h9 N S/ N: i/ o0 R res='\0';
4 V/ k2 |% U( z" j: R0 q) O: n) F return res;
' d! s0 }- O. Q1 e}* Q% C# H. V V+ h$ g3 ]
' T; [5 m+ b8 S V; h W$ xint main()
7 ?& a4 Q8 Y+ j- J{: B# s, n: F) R- z6 Q, \
char ch;4 f8 o |8 H5 _. r, l2 _5 k
char res[64];
8 l2 {& g0 D. j* u1 B8 M; L+ a% } float result;
7 X6 m- Y) y i while(1)- f% @6 E( x& o1 R, u
{
' b# j# z, o% l3 \' Y( g result=compute();
/ @) y5 {0 l9 |6 D% n, z" m4 R; x printf("\nThe result is:%s\n",killzero(res,result));
g* O7 e5 e/ E; P printf("Do you want to continue(y/n)?:") ;
4 e- ^$ p+ I) v% l ch=getch();
' @8 @/ e; Y. L% }# |; { putchar(ch);
1 n* s/ g" Y; w; ^% j. r: f if(ch=='n'||ch=='N'), O: I0 J* R+ H0 Y/ }( u2 o
break;
7 l! W. M0 w0 ?9 l" E8 W4 y2 B else1 `: F" A" R- y# v" q; Q Q9 }. t
system("cls");) b' E7 O; V/ z4 u, d T
}( `( r+ a$ i* s; u7 D
return 0;3 X6 R( C! q/ _7 a: B5 V; i
}6 m M! r: C- E4 B
) ~1 R( Y, a2 [. W! n2 i[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|