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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.4 e* _ G4 u# H# O) j
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
% y% n% W3 b/ I% C( `9 `* D/**************表达式计算器************/' N; \% z1 b# T2 y. F* R# t
#include <stdio.h>7 O3 w+ q0 m; B. T- p
#include <stdlib.h># X4 L9 G$ z+ b) t. v* D) e$ z$ c
#include <string.h>) X, j9 d, `0 ?
#include <conio.h>
& y1 S) [# W0 \9 z) D4 B- U#include <malloc.h>
7 n0 ~- M8 T$ w2 H1 J3 x$ w# P) \3 t' t5 u* Z" D ^$ U% J& A
#define STACK_SIZE 100
9 j# W* w0 z# e0 y2 ~# J: r/ u3 X#define APPEND_SIZE 10
- {9 Y$ R$ E; N2 q- Y1 \, R5 P. }% f2 q$ h
struct SNode{
6 A+ K7 y) \: n* I6 u8 Z float data; /*存放操作数或者计算结果*/. V" e4 P( d( @+ n1 r q" b6 l
char ch; /*存放运算符*/
; h- x0 u0 N" D0 Y" @3 |$ U0 T# M; c};; b+ y" u' c* N: P/ {8 Z
2 c7 f( M! R# n/ B% N. z% Rstruct Stack{$ j, B1 v& g/ o& q8 R% m$ J
SNode *top;
/ p8 r# v& W. r SNode *base;
* Q3 x2 Y1 H: A* c int size;
6 F- {* [+ w/ F* c};
; V1 H. t& [! m. M+ H, [! \8 q2 A, E+ q" c+ q& C& F( r
/*栈操作函数*/
; U. w1 A) Y7 t s0 _: a/ [* \int InitStack(Stack &S); /*创建栈*/5 D7 B4 Q& ^# A3 r1 a
int DestroyStack(Stack &S); /*销毁栈*/9 Y$ P' Y2 I2 A$ M0 O/ D' h
int ClearStack(Stack &S); /*清空栈*/' b6 U- i T2 v$ I
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/. Q' X/ k6 c1 r. E! F R
int Push(Stack &S,SNode e); /*将结点e压入栈*// r4 B; V" Q* f& `
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/' Z! ~1 [- C) Z9 Y$ @/ I
8 J, i5 m4 `$ G, p8 B8 [/*表达式计算器相关函数*/
3 w( u' b, W+ Cchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
* H& n" Y4 `. T4 Oint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/) ?- z9 M* R# T- y# E4 y7 V
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/# N" ^' g' L' y9 {$ I+ j0 u
float compute(); /*表达式结算器主函数*/
' K( w. Q1 c% F9 \5 j' ]char *killzero(float result); /*去掉结果后面的0*/
' E" P- u- W6 K, V+ `- e9 f& x
int InitStack(Stack &S)
! c: p! a) g+ J3 r7 F{
: m5 P7 \1 F: Q# T$ X S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));0 Y; M- m7 H, T. S' w0 B: X
if(S.base==NULL): y! _% X) \2 o7 l6 a6 B
{+ V( u! p$ K" T7 O
printf("动态分配内存失败!"); e! K( {/ j* D7 I/ Z& V" x: c! T* F7 @
return -1;
, J) B' q# O* ]# u# g }4 j' I/ B9 r9 l' z. N) N1 @
S.top=S.base;
+ H" W, J; q# U, A9 k S.size=STACK_SIZE;' e5 T$ @. `: ~- u/ U2 O% P* \
return 0;
3 d0 S% D# J! \$ l: z4 _}
; U2 C- l$ L& h; O# W$ C0 p. M7 e; ~4 u# L! M5 z$ D
int DestroyStack(Stack &S); ^" G( Q# r, e% T% v: Z7 g Q: Q! l
{9 S( d) T' V) y/ q8 f# g2 F# Y( o
free(S.base);' {" R! c; f/ }: ^
return 0;& i' ^1 u' u% n6 p$ {7 Q
}: [2 H; \8 @! V
* x2 s% M5 @& ~( D( w
int ClearStack(Stack &S)
s6 f2 [$ X( X- |3 N{
+ n6 K! R' a$ T* D! V S.top=S.base;
1 A7 |& o w0 J7 Y8 e( W return 0;4 ?* I$ k0 u4 G
}
! z$ _6 ~+ T9 O8 s+ {
, v1 B: E8 v1 u: n5 Rint GetTop(Stack S,SNode &e). P o1 G6 o* ~7 M
{
& D4 n& D v* z if(S.top==S.base)
8 ^! ]/ T' E1 c- h% \ {
4 \6 I9 D% y- z5 z$ E printf("栈以为空!");
. a& B3 |5 R# T5 V. Z return -1;
% R. a6 \8 q2 i }; o+ f' `4 Z% M
e=*(S.top-1);7 _% f- ^/ U2 R; O
return 0;
' k+ j2 l1 F4 D c" a$ A}
5 B$ t( z6 `$ o, ~' D; L: b# G G, ^2 k5 U
int Push(Stack &S,SNode e)7 n) O7 y' f' W+ ]
{
% I9 g3 h0 H5 \ B1 h( ?! u if(S.top-S.base>=S.size)
- J( P5 `0 s/ |1 C0 ] {
B2 I4 k ?4 i7 w" t( C4 k( A; ? S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
4 Z+ y/ c, S' K4 `6 _/ T if(S.base==NULL)( ?; K* N) j- M- s9 J
{
9 ^# B5 J% k) Q printf("动态分配内存失败!");
) z% h$ G: X: } return -1;1 b: C8 {' `1 j; P+ j
}
) s9 j% n! { v! y3 h S.top=S.base+S.size;
( t9 s7 F- O$ O" D6 e3 F8 G S.size+=APPEND_SIZE;$ \$ W; z0 a m: C
}$ k" i/ v0 e1 y3 k$ r! @8 H; F9 \& h$ w
*S.top=e; B9 H5 F5 {! i& o& Z+ M
S.top++;* W" N2 U% I- \- X2 r0 V
return 0;0 t7 j8 G5 w0 g. b* @0 G
}
4 @5 P7 X6 J; v9 c
3 C( }/ b% }: N# fint Pop(Stack &S,SNode &e)
4 Q6 {0 D( X/ T{9 ?" U, w. x- A! K) U2 b# O
if(S.top==S.base)
7 l3 I7 u* K/ U/ \0 n {
0 O2 O# b; u* ?8 P' g% C: c( J' J printf("栈为空!");
8 j2 O6 ]2 R. U: z/ {$ D8 ? return -1;. u& D e) y. h1 u& S. D$ B2 ^: l
}7 {2 O4 J* P: d' v p
e=*(S.top-1);( S8 u5 d! X- D; I
S.top--;
' G' j7 ^0 k8 _8 _) x2 m return 0;
, { y9 W7 W( w: g9 ]' m0 z% Y" r}0 V6 m' c# o9 @9 U% l/ N! G
' [! e% d7 L% n: m- jchar get_precede(char s,char c)
; }# t1 k2 `1 {- t8 S6 v/ d{! u7 U+ X6 A. M v6 [/ M2 h+ s
switch(s)+ f6 f# ]! p6 @7 ^6 l: y2 m4 K
{
- n5 M( K3 ^" ~' t case '+':
. O4 @, a3 H8 h+ X2 R$ i T case '-':8 F/ s- k) k) {9 a# a
if(c=='+'||c=='-')9 s( k; O2 N+ T0 D1 v
return '>';
5 W. c, J+ p( a2 R, E9 w else if(c=='*'||c=='/')) B C1 ^% L% Z' I6 @, W+ z
return '<';
( r# \$ Y: X) D9 W4 f5 E else if(c=='(')
: _" H$ E- G# X+ Y* V) L return '<';5 F/ V' H P. U) h6 @; F5 A$ l3 i: i
else if(c==')')2 l! W) a" R. O/ X% A
return '>';
7 o) [) r, [. x* [9 z else 8 m$ z5 Z2 k8 V, X1 \( Y
return '>';
$ ~: t1 c7 s" A8 f0 l+ r. o* ~ case '*':/ e5 Z3 X) I1 f' w2 b8 S- @
case '/':
4 k+ Q3 E. J6 x1 n$ ]+ S; T/ r if(c=='+'||c=='-')
" G a4 z2 s$ E1 ~; ]4 P return '>';
! T) E8 w8 c- ^% t. Z" f else if(c=='*'||c=='/')
8 |- O& z# a2 I3 ~2 d0 g$ g return '>';
! @ U# B3 Q/ b: a" K else if(c=='(')
5 z* V" b) C1 Z: m/ [! G return '<';6 R0 v! ]( Z! M6 ^& Z
else if(c==')')
; K0 k/ x. F2 w. ~' E7 }) u, i return '>';/ P: Y" B' P+ \4 K8 S& i
else7 z0 g& ~! _+ U2 d. r4 w
return '>';; B$ s# E7 K9 l& G5 T4 t
case '(':
1 @# ?- |3 [* @0 @+ `! G if(c=='+'||c=='-')2 \+ K, D1 `1 B
return '<';
6 _& d& x7 b& l: a8 O else if(c=='*'||c=='/')' V, A, m) o3 \1 J1 z% A& n2 {
return '<';- i+ a4 \. P. ~' k% N# W2 U
else if(c=='(')
4 Y' ^2 L2 O6 ] return '<';
, }( _9 Q: c4 @4 d else if(c==')')
" T7 o$ V q/ S }& ^. d return '=';. p! f6 F- D9 Q- J$ ^
else; n/ X9 w1 G# H& q \
return 'E';3 u* H5 l& f6 G6 j/ o& r( |1 F3 y
case ')':8 ?0 s# N# V$ _' X4 u3 X
if(c=='+'||c=='-')4 O6 h! O# I* w. u, Y
return '>';
2 j6 J7 l- M4 _3 |9 F else if(c=='*'||c=='/')
: }% u! S, U' `8 g8 {$ { return '>';+ C8 T9 X: T0 [& W$ G( _
else if(c=='(')$ t4 ?/ r7 t1 w. u3 |2 I8 T o
return 'E';
' P3 x3 D& J/ L: T) i$ n* Y1 U* [ else if(c==')')
$ \# ^8 l- l% Y$ r( Y1 Z" j; A0 d7 N return '>';
2 M9 r7 B8 q+ L4 y' i else
- w6 S8 r) `3 c9 L. t return '>';
3 K8 ?6 A& p q6 e& ^ case '#':- W& Y' @# {7 V9 }! N, A
if(c=='+'||c=='-')/ |$ ]! z5 x5 @/ x6 J L2 o
return '<';
( y5 b; f8 w. M9 ~0 h: |# g# s else if(c=='*'||c=='/')6 f; [- w+ D' X
return '<';
: D) c' l. o0 J* i else if(c=='(')
1 t/ C: v* Q" m4 i" U5 A return '<';
7 _# v$ X2 V+ }; v+ { ~9 w: J else if(c==')')9 b! @' _3 h( R2 c* l3 d/ i. @$ z
return 'E';
/ r& w' p3 D) \% M2 W1 ^ else! {- E9 S( R2 D# ~; d3 L; X. \; `
return '=';
/ H+ L% J v8 c# \ default:9 G& h/ {3 ?- ?8 G. T4 |
break;
+ R; O7 o" ^* _, t }! d( g: @1 T4 S m6 {
return 0;
. y f' u0 `/ R$ v$ P7 G/ K0 J9 S}
/ ]9 L+ E1 l: s* W( K" B8 F o5 m6 L6 s" f4 v3 R
int isOpr(char c)
1 Q7 n* [+ _( x" u1 ^{
& {7 C% R3 Z& s4 u6 x3 S3 T) J if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
: h! j. ~$ P a, J/ ]4 A return 0;
4 T* s5 r# ?/ q* v _' O else
' x) J& B( k% f$ X& Z, { return 1;
" i8 g+ [' Y. l* A4 `2 }9 `}
8 m5 |# \8 i/ l( G) H
# c$ @# X) `8 e+ Bfloat operate(float x, char opr, float y)
2 j1 }* s9 v3 }( D& {+ p1 Q" ]" s{
: v# L7 \+ S. `/ J- Q8 Y/ m float result;+ p# `9 l( H5 |
switch (opr)
/ `8 g5 S4 h- X- W- b M, v/ } {- m1 t1 }# q) E
case '+': : l4 E0 r2 h- r2 N6 W- y9 v
result = x + y;1 n4 O6 G! _/ ^
break; s7 j; U& T# [* [
case '-':
7 }; e$ T2 B+ X* {3 ~ result = x - y;* e- N- Q( D: \. D: s
break;) X+ ?' I9 L/ v( @$ E% X
case '*':
$ h& r5 R% \5 L# J/ a result = x * y;& r2 P3 ]7 G/ C# P
break;$ Z W& j% w; S
case '/':
# u& w# A( h% | [' f. i( |8 P- \7 | if (y == 0)
" D2 l: H* [8 j$ B {
" C: s/ L+ d& t$ T, m5 G, q2 t printf("Divided by zero!\n");/ J# _) |5 f8 \6 x
return 0;
8 U% O( C. d" L+ Q }
" ^2 L! X& y- a% v else2 K1 s: G( q2 H ^- u
{
/ X7 j6 c+ b4 _! W result = x / y;% f4 L" W6 V' L% U, R7 W; A- H
break;$ {/ N" F7 P5 D" w
}, k8 Q) J' L/ I4 N
default:
) b+ w, z2 q6 u1 J" Q/ l printf("Bad Input.\n");
, E/ P5 g6 q% L( j. \ return 0;% A/ F- q, r/ N1 D( Z; a
}# n3 y/ W) G& Q- |
return result;6 I: ^- B! J% x/ g4 ~
} " k- `) ~) e6 a! R: `" {2 C
) g e- ]7 T: E2 q# u8 i% k% ufloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/! P [/ M3 |' M+ X6 M/ [( G
{* l3 ~% c; N3 p" d0 Q0 J% ^5 S
Stack optr,opnd;! J9 Y" K3 b1 t9 J2 t& A( N
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
$ D; s% H! |- e( [8 z0 u: E char c;' z8 W9 g" ]/ F: D* z
char buf[16];
7 P6 L4 u3 G2 X2 x% p q int i=0;6 ?" a' _& m5 W, u
, b# p; C* s- ^, p; `# ` InitStack(optr); /*用于寄存运算符*/) r! Z/ t& c" c* |
InitStack(opnd); /*用于寄存操作数和计算结果*/" i C2 Q4 i, H2 Y9 E1 {7 i
memset(buf,0,sizeof(buf));6 @2 L# D% Z8 X
0 E+ V1 s% T) G printf("Enter your expression:");0 S% m" z( v2 }$ S! L
. a6 ]# P# }6 J; S d% l6 f
opr_in.ch='#';
! Z/ l9 n, X+ j1 I7 n Push(optr,opr_in); /*'#'入栈*/
& { E; L: l; n) ]+ ?! i8 {# P GetTop(optr,opr_top);
0 b$ k0 w$ |1 Y5 G c=getchar();$ H0 k Y) f2 y- y6 M. Q( C
while(c!='='||opr_top.ch!='#')
g+ a6 L- x3 N {4 w, S }4 X/ D( s8 y V- W
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
q' B$ \/ R) V% h7 }- y& V {: V0 O) ]8 S: p: t! L
buf=c;' x$ g7 e8 l8 X/ A1 k" Y
i++;
5 R% w' T: @% ?& p c=getchar();
. H( X n& N( {7 m& E! B* C5 N }8 U% y4 P. h/ j' i1 h# O; \
else /*是运算符*/- X: }5 Q: M1 k' D( [0 K& A2 l) V
{
( H; V$ n) a7 k; q1 S$ W0 R buf='\0';
8 o5 }$ Q) Z9 \# b if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/' H# C) X1 Y, m- v7 b; p
{
) G% b. c" b# s" {$ e9 G opn_in.data=(float)atof(buf);2 W" J2 G; I( {% m. y9 Q5 u
Push(opnd,opn_in);. ?$ X8 ?, d) c" y: T
printf("opnd入栈:[%f]\n",opn_in.data);% y$ S8 K5 d3 s+ j! c2 ^$ s
i=0;& e5 ` g8 X* L R
memset(buf,0,sizeof(buf));" A9 m3 X7 p. F9 w, W1 Y
}
0 S& |1 U7 I1 ^( Z* k opr_in.ch=c;
5 ]0 J# V q% D6 F j$ c9 h switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/+ q7 i( N6 H4 s5 |# D
{% A0 `' G/ x1 ^
case '<': /*优先级小于栈顶结点,则运算符入栈*/
4 {! G9 q" U# f0 ~1 n2 |9 e Push(optr,opr_in);
" S7 ^* q0 X) k$ |7 } printf("optr入栈:[%c]\n",opr_in.ch);
# g6 U6 c( z5 ]+ b& E- c* J c=getchar();/ E2 r& T4 k8 W4 @
break;
8 V0 }+ |2 V% Z* C7 Z case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
# i& I* G9 a9 d: h' h- t% V Pop(optr,e);
# t9 b3 r7 v8 _/ u+ `' r* r0 e printf("optr出栈:去掉括号\n");; b5 L% ] m4 f1 A+ a, q
c=getchar();
9 }& A( E. \+ e break;
; B8 ^" z5 G) z7 V8 n( y& m case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
) V( m# q' O% I9 L! X Pop(optr,opr_t);6 g! p3 b% F" n* S" ]* o
printf("optr出栈:[%c]\n",opr_t.ch);/ R% W# {2 U1 E1 |5 k
if(Pop(opnd,b)<0)9 ], _" N1 J' o2 U( ?
{3 f9 T+ O, |+ i+ o+ _" B8 o
printf("Bad Input!\n");' U0 P3 V, Z, o3 K; ^* ?
fflush(stdin);% t0 E9 o" }" U: ~
return -1;
6 C2 b5 }- @/ ]6 p; { }
/ a( l+ B2 `9 {' d printf("opnd出栈:[%f]\n",b.data);
/ ?: O/ m7 j0 V6 T6 T if(Pop(opnd,a)<0)
3 ]) _4 a9 f5 ` {
0 N- K8 X3 ~9 l- A- d; S printf("Bad Input!\n");
! c& ]) d0 k6 p4 M) _5 [ fflush(stdin);/ O x3 u1 e- P' z( p5 k
return -1;
. A* C O. e& }" R }8 ] l! x: U: e5 k9 d. Y0 V
printf("opnd出栈:[%f]\n",a.data);8 P6 G# F: @1 O; i2 F* s+ G
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/9 Y9 V5 k1 t1 I& t% j$ D/ w% y
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
6 `" M; [7 t$ ^/ u6 A% b printf("结果入栈:[%f]\n",opn_tmp.data);2 [9 r4 d! U( ~# `* a9 [: f
break;+ o* r0 ~( v. R7 {
}9 E r ?" \7 I, z0 Q
}
/ R3 [% M$ F4 O GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 7 E7 s. a' G9 n! h0 v
}
' j8 `2 k1 @( Z- k% ` GetTop(opnd,opn_tmp);
$ X, n# `" A, P8 h8 R' _4 S4 D$ U DestroyStack(optr);: i3 U# c+ }: O z; A+ W
DestroyStack(opnd);7 c! u& I- S2 |5 [5 U
return opn_tmp.data;5 k) W* x4 A9 `# `* m
}" p! ~3 g* M/ X
2 D0 n: P, t* N( Tchar *killzero(char *res,float result)$ l3 h* d6 P9 [% I& Z$ Y
{
; x: N* V+ e9 T int i;5 w) Z. H, `$ b0 H$ p9 z P
* s3 x0 D9 L; i4 @$ l sprintf(res,"%f",result);1 D+ D7 ?0 U8 a p( Y
i=(int)strlen(res)-1; G7 a! g& _' ` l- v& _
while(i&&res=='0')
& r% P( p7 J4 k; _- M. J, { {
! q- g: Z) v$ X% ~& M. c j res='\0';
& K* y) a- d/ O i--;, y1 J, o& N- N5 `
}
2 {6 L' P0 y& F$ e9 B5 C' R if(res=='.')
- w H- Q0 C+ [4 P1 b. D3 G res='\0';6 c0 m7 c" l- ^+ v# ]+ o' M/ a
return res;
0 \) }$ v! N- w7 X( i: f}# J+ s5 R$ m/ M4 N$ H O
& }. n* U% w' K0 N% E$ |: Uint main()
. C5 b$ w# h& q: M{
% R R2 E/ a s char ch;$ j6 u, N: E* }
char res[64];
! }* [# |/ Z3 Y5 _! X/ u float result;3 @7 r) E: R" o4 l* F
while(1)
d- |. `9 K, ]* a; a+ ^ {
# `; s' C* D) b) d8 C6 m+ q% u$ o result=compute();
3 S2 D- u3 V M4 c' g2 d& Q7 l printf("\nThe result is:%s\n",killzero(res,result));
& s. X6 v4 L; f' M5 a printf("Do you want to continue(y/n)?:") ;
6 W2 [. z1 H* i" X/ I3 A/ C ch=getch();
. h% t! k6 J' l: z6 D, z7 L putchar(ch);
4 a3 M! t) C1 n. | Q, } if(ch=='n'||ch=='N')
6 \2 E- ]7 r' i Z' a0 K break;
* h+ E" O) F. S( h else
$ S8 P( s) ~: V' e! G system("cls");- F! `0 |3 {. z+ e& P
}9 k/ R. P5 w7 E# r
return 0;
3 D r8 x) d8 V4 A( d; y9 V! O! z- R}
7 C! P* e3 m9 Z
5 ~& V' m7 U; h& O0 A L' U+ H[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|