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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.1 G; B* w; b7 u, l
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
% G, R; K/ E) A g( N* g t. A/**************表达式计算器************/
. x4 ~' R& T: H8 j2 J8 ]5 h#include <stdio.h>
/ y, {2 o1 r: n#include <stdlib.h>
7 C7 W: \0 i9 o#include <string.h>
- }$ T+ \; L, ~5 x& Z#include <conio.h>
8 u' k7 B" F. n \. p#include <malloc.h>" I: d5 R" {* Y/ ~( l9 }
) V8 G5 x3 L, O$ V( @
#define STACK_SIZE 100
! } ~" C; X6 A" |#define APPEND_SIZE 104 G; k5 K! J# a' m* @* j3 h
; H$ E6 [ a3 F" j& s$ i% @' Pstruct SNode{, _2 x7 C' V1 o- Q. a4 i
float data; /*存放操作数或者计算结果*/* N. R1 T( Q" c8 N2 g
char ch; /*存放运算符*/
3 V! N1 ] W" T4 N1 t, d# a};9 \: N z2 e9 W# Q
5 h% p! }' K9 s. c' w
struct Stack{
- o n2 d, j. t. W7 D" `5 ]% z5 X SNode *top;9 `& }6 \7 e* t- b& ~5 O
SNode *base;- V; w3 \3 J& P1 {; x% Z" K( C
int size;
: [# }. [8 c/ B, d- x9 Y$ ]};
! g7 n2 p$ w* S# G
$ C4 ~. X6 ?4 u. b, ?/*栈操作函数*/
( o1 n% B9 g) J+ N) rint InitStack(Stack &S); /*创建栈*/
& x" }: B+ n1 iint DestroyStack(Stack &S); /*销毁栈*/
* ]6 F$ D/ B9 k1 U2 M0 W% Mint ClearStack(Stack &S); /*清空栈*/, X5 M4 h$ Z G
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
7 @. X( V5 t2 Yint Push(Stack &S,SNode e); /*将结点e压入栈*/
/ o# Y$ }1 B1 b* F- eint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/3 A6 S, ~$ Q2 S
6 q6 z2 e. l7 Q: b" o; O
/*表达式计算器相关函数*/
# q Q/ M1 W5 ]0 ]char get_precede(char s,char c); /*判断运算符s和c的优先级*/" `4 @% J( F/ x) j2 E
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/0 l3 _/ q* b( H# H
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
! a( }1 R7 K1 }& G) m5 G( O: Rfloat compute(); /*表达式结算器主函数*/1 \ e [0 C2 w, y" V2 D
char *killzero(float result); /*去掉结果后面的0*/ 8 M0 M2 b4 Y8 H: t, w' x' L1 A
8 {" B0 q% S5 J1 u' H9 E- {int InitStack(Stack &S)/ f5 j0 {0 p6 A# Y3 n3 S8 e* E# Q
{
6 y" K4 f. A2 h: w$ ? S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
" D! i2 e3 d; P9 x, }! H if(S.base==NULL)0 o( B; X+ A( q n/ K4 K
{) F/ T5 O# [+ S0 Y
printf("动态分配内存失败!");8 w3 w4 s" O; k& Z
return -1;
8 [+ ?- W4 j% u$ c7 N }
' |4 u) e1 F) r- ?% x S.top=S.base;
2 C- U$ B! s/ n* m S.size=STACK_SIZE;
e) q' J9 u1 i& O' Z; c7 z, N9 v return 0;, X4 Q6 {: m- [% `0 @7 t( _
}
/ S; ]% P) c0 x! f
; X7 v- O7 q' a/ hint DestroyStack(Stack &S)
' b2 _7 Z, Y6 U- u{ X; P1 y; A$ }' k1 l3 }3 u
free(S.base);
( n8 l6 c& ]; ]) O return 0;$ T2 Z6 T6 t( @' w( }
}
) {* e$ G% A0 w% G& n0 R& o
* Q1 O& L& P) \ S5 E( Y( |! z6 z+ qint ClearStack(Stack &S)' B K! c& }# }) ?) N. `
{
( e+ M6 N+ F, V( z) L$ a1 R S.top=S.base;& p& l$ j% T$ [7 x+ ^. T1 O d3 [
return 0;
; H$ d# @. V. u; @7 h}8 [' Y- T" B: y. k3 `: M
: C: \- S& J1 C1 z
int GetTop(Stack S,SNode &e)( }4 y8 | B* |5 R
{/ r0 f$ z/ R/ V' j) M7 M
if(S.top==S.base). F: i4 o! I0 Q% g o$ S( ^
{( r$ e$ B2 X; n
printf("栈以为空!");
8 U/ A; y3 A, p0 H/ f& m2 m return -1;
. b: t3 j- W: M' ^. I$ @" L/ A }& D( ? h( o, D. v
e=*(S.top-1);
" O; \; W; q6 Y8 V, f* _ return 0;- U+ c! L- ~- M4 I U
}, ? y J9 ]3 u# H2 e! F8 @
/ e- U1 f+ ]% M' g- X& x$ ^
int Push(Stack &S,SNode e)
% l- K. |" k+ f% [! o{7 o) h; N9 ~, z: G+ X6 \$ B
if(S.top-S.base>=S.size)
- m# X; ^8 S U J {) R! m- r: i8 Z7 q( s( ?
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
! ?& _0 ]. {; l* |! w if(S.base==NULL)/ o* |- n) q/ ?% ]
{- z, I+ }2 T" [
printf("动态分配内存失败!");4 C/ x* w1 j; r9 B% w b: d
return -1;
1 M' s# y4 P( [' A }
8 D7 m# ]! l; u4 a" \& P3 f" q S.top=S.base+S.size;* \% O; l1 u" ]$ U7 k
S.size+=APPEND_SIZE;# t: g5 [. r; U, W* t4 A, @
}# A$ O+ V7 h# k* S
*S.top=e;
" K4 x- v' N7 @* ~( ? S.top++;& _& l! ~7 j9 S( k0 D/ f9 x
return 0;+ Q3 ~3 @* j }& p, `) J9 V4 z
}
* Q$ c% ^' N6 i" b6 [. q7 d. S! L7 s( A3 J+ [
int Pop(Stack &S,SNode &e)
: K; L! x. h! ~+ W& Q+ c( P7 D{9 p1 b3 u$ m: _: h
if(S.top==S.base)/ U! t% l' s- \8 N( q8 h
{; j) e5 D! W/ ]
printf("栈为空!");/ N0 b) [0 X/ w" J6 S& v) b5 F
return -1;- D7 N1 ]$ M4 Y* n+ W% g
}
; P7 O! ]3 p& ? e=*(S.top-1);1 j5 t# X( M! n, d5 D' n6 g: h
S.top--;3 N2 y% H# s4 D5 O! b7 L# B
return 0;
o2 u! |9 j( v$ j0 \* Z1 a}
+ N8 _5 e" H* L1 X0 o: s, b
# V& C# p/ a! U+ d. ichar get_precede(char s,char c)
1 V' \; m( x" K! A( A; k+ `{4 e) R& d a6 X' Y+ ]# Y
switch(s)
3 B& x) F- j/ h6 e6 | {! D9 ^, T! c% N! a, q; E1 k( o7 Y" [ B
case '+': 9 j$ Z/ a' W8 D; `" C
case '-':0 k/ q6 |" Q( e0 f6 l" V
if(c=='+'||c=='-')
) z2 M# u4 S4 b9 }0 e# R return '>';
5 G) m* f$ S9 n- G; g else if(c=='*'||c=='/')/ | n K x3 i. j/ s* w% m$ ?
return '<';4 V ~, Y; B8 @% e# C; f
else if(c=='(')$ i, l7 `& [3 P: u/ `
return '<';
: h) ?4 I- n* | else if(c==')')
# D: J/ Q! k- R3 k8 b e8 B, w return '>';
( [0 b7 }' d9 Z4 z& r+ {2 m else ! F, ^' O& e& `8 @
return '>';
' N: s8 C0 Z+ N" j case '*':+ z1 l. z% O# j8 j
case '/':
/ B- j- k8 j0 S if(c=='+'||c=='-')
* e& u8 K7 W) S" b, F3 b, p return '>';
8 ^" I1 p e# e _" r% D* y, q else if(c=='*'||c=='/')8 G8 l! H( K' G0 K$ w# Q8 l
return '>';: R* @8 Q2 F y2 y
else if(c=='(')+ u! k1 _. K5 W. q. D, e
return '<';1 e7 s0 a3 g% y
else if(c==')')8 `3 E4 x7 K9 T, u
return '>';+ O; V8 H( R( H# `% X8 ?% n
else1 j$ W) [! F! _
return '>';" M6 r/ ?/ _6 Z0 i
case '(':
5 q6 ?3 d& `4 s if(c=='+'||c=='-')8 u/ B5 _$ _- T- y9 E& ]
return '<';
1 D* i4 E: O C t9 C else if(c=='*'||c=='/'), Z e6 A% f4 i0 {* ^
return '<';
( |/ \. q- `2 t' \3 @ r/ ? else if(c=='(')
& v$ S. R3 ]- T& V. k return '<';1 ]9 J' f9 i! `& D* y
else if(c==')')) L2 c3 v+ J, A% H. b4 e
return '=';
* Y2 p& F' c- s% g2 q; M, r else
2 ?( K8 Q9 g p! G7 r0 r return 'E';3 r" \5 ~1 {) D9 U6 V" h- S) g" S: \
case ')':5 }: o+ r( C5 E( k# T
if(c=='+'||c=='-')0 H* y7 E, U! Q- o% ]
return '>';, m3 Z( [# ]/ o' U$ v
else if(c=='*'||c=='/')8 [* p N; ~9 E1 H6 F
return '>';
9 _: Z' M- Q9 J$ j else if(c=='(')
! {$ }2 D# _, L$ k- o* h) c return 'E';% ~" \$ R* W: H) {2 G. C
else if(c==')')% b! E( @+ ^0 q3 ?# T) n
return '>';6 G8 x2 G( Y4 C2 _/ T% H
else& `% U$ n. O! M3 u
return '>';" m) X. t- a& D
case '#':
! F' u2 x) @. P% N/ j1 P if(c=='+'||c=='-')& f0 w7 l% ?2 D0 \) t& y
return '<';: i+ T. W, u4 Q8 o5 v5 e
else if(c=='*'||c=='/')
: P4 m1 O: |. I8 p9 T return '<';" b( p" r6 g" D5 Z+ x$ ^
else if(c=='(')6 l0 H5 c. O5 V! e3 e
return '<';1 f6 O8 a7 q1 O$ F0 I
else if(c==')')+ w* i* G6 Z) X% ]0 j* j
return 'E';
" t& }8 E; g8 u* g( y8 H( m else1 w- F; B% M% B; x; @% ]
return '=';
5 x8 S0 I# Z9 H/ ?+ N default:7 @. A* T) d/ M" z4 \8 C& }! p0 t. b
break;
* b+ I5 y: e+ p; ~& G: b1 r& r }
5 _8 ?3 Z- S" E) | return 0; ' |1 Z0 H% }7 r0 ~9 j; M( P
}/ m! i2 q( \5 p2 l7 K
- U; ?- I9 ^- P5 Yint isOpr(char c)9 k6 S; q3 ~7 } j& K
{
4 L5 w3 {9 s# B9 Y9 S# B if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='); t9 _" h4 H) S8 i
return 0;
! t# G7 W i O+ r else 8 F3 ~. x) [! N" R$ h. b
return 1;# ?; ^7 L$ k B! Z
}
" P6 B2 N" h1 ], \. k
# Y3 U# }. I* l/ z, ~' y5 s- Cfloat operate(float x, char opr, float y)$ W" \' Z2 X0 `. a z" z
{
0 ^& D3 b9 k v+ B float result;
0 F- w, b9 G) B, b3 ]% v4 Z switch (opr)
9 G$ s8 j% N: ? x {& g# `3 Y& k' L( P k
case '+':
. X; o, J5 { T0 r/ V result = x + y;) q4 E, E+ ~0 o9 |
break;1 N" J$ n) G) h9 e, `& l3 l
case '-': $ v: v) B$ f' _- H5 t
result = x - y;
$ U% |; a6 v2 Y9 | break;
9 ]! O. g, a: _; l7 B% M. D& T+ F+ L* \ case '*':
: y% m; \$ z1 v4 m result = x * y;) a1 ^) J L( c, M/ S' @
break;% i; J: S5 c% ~+ e
case '/': / C' P/ f9 k" `. p, \
if (y == 0)1 v, j) [' a% A3 u/ G* G1 a2 v3 U; z* e
{& z& J) d2 j3 Q, _& P* X' I
printf("Divided by zero!\n");
3 o8 U) H4 l$ y4 ?6 F4 D return 0;& F c( L8 z& H: J. _) `' Q
}
+ D- ^) w, N) i/ N2 I else5 d" |" z4 E) z; @3 M& B* M
{* K0 l9 H4 P( |( S; E8 R/ X
result = x / y;
/ ]! k% i& W% r' s2 l break;- f, M) Z* i5 f+ W8 e+ }/ s9 K6 G
}
. y& c3 p1 w& J default:
& I$ P2 }& W0 W/ q) ]# O% [ printf("Bad Input.\n"); 3 l- W$ ^3 o, V: B' H2 [
return 0;
9 M. O7 v2 p9 ]* x5 X4 A; a L, [+ Q }
% a- `! c+ i/ u6 g return result;( h4 P1 p# c+ s) }+ I) A+ w
} , ]5 U( B7 F' n; B1 P6 ?
: j, C, L+ z$ x/ @7 ?/ Vfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
6 j( C% `8 }% @5 M{! ]" c! C2 ]' W- x
Stack optr,opnd; Y$ S- k% T4 z! D1 N
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;3 ^) y9 {0 C& `0 {
char c;# w6 A/ z( o7 F$ |5 Q4 v
char buf[16];% {" O( h( Z- w% R2 \3 l9 L
int i=0;* |- r# y3 l# ~; h$ c$ x8 c9 Z4 D8 M3 d
4 W% s0 l1 U& [/ P$ ]% {5 H2 _
InitStack(optr); /*用于寄存运算符*/3 Y- |. q5 |6 e4 x! ~8 z2 R' q9 c) q
InitStack(opnd); /*用于寄存操作数和计算结果*/
6 D, ^5 h3 G# o. w: B" Q1 W5 h, ? memset(buf,0,sizeof(buf));
! C1 \8 T! r, c1 C/ S" R" F- U
3 H% t+ I: F: C" f printf("Enter your expression:");. S8 e4 B2 V2 f3 _7 ?4 G0 K8 L+ h
# h$ t D5 {$ U, j opr_in.ch='#';
/ f; F6 {/ R6 g Push(optr,opr_in); /*'#'入栈*/
$ f/ v J' W8 ^4 l) J) q GetTop(optr,opr_top);
4 }) o* {$ t; h- S2 Y1 O c=getchar();- K( f, _9 h: ~' `) P: r! c3 I
while(c!='='||opr_top.ch!='#')* U" @. k1 w" |) m; N0 C$ H
{4 t( E/ g& g! f. J* @" |0 f: {8 m
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/6 ]/ D" C- t1 U. S
{
8 A5 x9 C* p0 U! S buf=c;
% m2 B0 X& U4 _+ C& u) f: }' u i++;
' u: k' h- G1 z. i! q c=getchar();, h8 v) b) f0 i2 V
}0 C% S% f$ p7 E' s1 z" J' G
else /*是运算符*/+ y% ~. D' H* _/ n3 d5 d) l
{
" _8 ^$ I. N! D4 i+ S2 A9 X) l) M buf='\0';. S5 f) b3 j1 w3 m
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/, k9 R8 r7 \: i7 P9 r9 t! U3 {
{
3 W/ |* q+ Z/ ^ opn_in.data=(float)atof(buf);
5 K3 o& L2 B( r! Y2 G2 S Push(opnd,opn_in);/ `6 \( n, @" ^. I" [
printf("opnd入栈:[%f]\n",opn_in.data);6 Q, u# V& {! p) n7 u
i=0;4 V' B8 p) q6 {% s& U
memset(buf,0,sizeof(buf));
2 S+ E; |* t8 O( h% H0 {0 n }( P/ Z8 \+ `6 b3 t% \
opr_in.ch=c;
- _; x, U. M9 s {1 r0 P switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
) j o4 @, x' g+ r: E4 j* N {; g/ W& Y0 w0 W% D. r: y
case '<': /*优先级小于栈顶结点,则运算符入栈*/
/ z7 Q$ b0 S' V& I h Push(optr,opr_in);, ^4 w* y- C. n: T) s) t
printf("optr入栈:[%c]\n",opr_in.ch);
3 k: p- a) `# I" ] g! h4 W c=getchar();
1 o0 Z" m8 m8 D; `1 g0 ] s5 q break;
9 G. [& H9 J& |( _2 _ case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
: B- H2 l3 O2 o/ | Pop(optr,e);
6 y; s+ D2 r4 N; h/ G printf("optr出栈:去掉括号\n");
1 v; K* Q3 g# s- Q5 ?9 @: a1 U$ ^( J+ O c=getchar();
, M$ l! A& ]1 O1 D; b/ U break;
2 P3 H) q5 V: d3 V! M2 v5 w7 H) a case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/: @% u' v( P7 @4 S
Pop(optr,opr_t);6 H ^: T t+ B3 j' y2 E) l+ n" B
printf("optr出栈:[%c]\n",opr_t.ch);5 l6 n3 }7 V( o) S3 I3 w. A: ]
if(Pop(opnd,b)<0)# d9 a q$ |: A! u
{ x9 I7 w( _$ u7 I+ `' A
printf("Bad Input!\n");
/ d! Q* V% Z( `2 U* B2 G- K fflush(stdin);
8 O6 D) w B+ q, n- h return -1;+ l4 t% Z t2 F0 b' ?; h6 S' y& Y
}5 E) L, @1 Z) ^% T* s: W
printf("opnd出栈:[%f]\n",b.data);% r0 S" k1 [1 O
if(Pop(opnd,a)<0)
. h- `& Q% y: n) C9 d8 T! ? {
& ~6 d- o! N3 ]& k0 y' ^* i4 X printf("Bad Input!\n");
. t' V5 M& D3 I. g; m fflush(stdin);% j5 d6 i. o% K2 n
return -1;- U5 I4 K4 f5 I! R/ N2 M
}
. n5 v6 W1 G6 H+ z2 C printf("opnd出栈:[%f]\n",a.data);& q8 V1 g: v) E5 ]) N
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/; u: Y8 v: C, r0 F6 E* O |" r- [
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
% u$ ?4 Q" i- ~* g/ F7 E7 F* t printf("结果入栈:[%f]\n",opn_tmp.data);
$ o) d( ` Z) q4 |* N2 [: J break;
. O" U# c3 K! e' s0 j2 }" { }
* r+ I8 N9 @0 h2 R5 s/ n }; q- N* y) ]3 ^" `+ @
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ : l+ ] K! M, u9 j5 d: ~* p, `9 k p
}
, B3 j9 e u! t! r GetTop(opnd,opn_tmp);( s8 x# \5 u5 q6 X7 T. N
DestroyStack(optr); b+ \% @7 r$ P5 T# j' T
DestroyStack(opnd);
) l7 @& C, y) P. `: u6 L) d- q4 w return opn_tmp.data; [! x2 E. J* W7 h+ v
}$ |/ Q8 h9 ?# [/ Z# `* s
3 n: T: h% ~# Y6 Achar *killzero(char *res,float result)
1 o! G+ h8 V* h2 P) l{2 _- y: v- t& ]1 l, m
int i;) d' g5 y- m- J+ G n
1 [! @, T7 g+ R. a E6 r4 ] sprintf(res,"%f",result);2 i5 @# D9 U$ x+ V) W8 r* |
i=(int)strlen(res)-1;
5 \' K/ c Y+ ~5 U8 y) { while(i&&res=='0')
* s X9 T1 [2 @, v4 L6 _4 ^1 e' L {. c0 s4 m* P! x' {+ T
res='\0';
" G% p- H9 l$ V5 L i--;
5 U; t8 M' I. o3 T }0 n+ w J7 B$ j5 H; ]
if(res=='.')
! R0 P9 Q9 y' r res='\0';# Q5 I. |! y7 W% q: |
return res;) d! m/ B& u# ^, w) r
}& k; X! K3 C1 y7 N2 f
" r. ]/ I: N! r
int main()0 b/ m9 \% q7 p. W1 ^
{
, L8 m+ i9 t8 o" s7 X char ch;
; t: A( v9 g# k7 H8 o2 Z8 U char res[64];
# @# _& A: f6 ^0 n0 H- M float result;
" V) L, c a* F while(1)
" J2 K6 T5 j: ^5 E, | \% i {9 w0 O3 l; r3 Z1 @6 F% J6 J! i- N
result=compute();
" z, V& e* M9 R) h+ g: n% ] printf("\nThe result is:%s\n",killzero(res,result));
9 q9 y* x* R( O6 k- }! ~) u printf("Do you want to continue(y/n)?:") ;- S$ }1 O2 D e( f' }; o
ch=getch();
7 n- N( P$ e2 ^7 l) i a) i3 P* y putchar(ch);
1 J& ?& R2 G) } if(ch=='n'||ch=='N')( ^6 [2 H1 n, G9 n) t0 f% E' F4 N7 Z3 P0 I
break;! L" O& A2 a1 n; O" z5 g
else7 D% }4 o* i3 B$ ?
system("cls");6 X/ \4 Z; _$ @9 M4 O7 J
}1 T4 z6 ^$ m- [# O: {
return 0;1 z$ a+ @: S0 l7 Z
}
9 `- n5 o& Z K0 k& M0 T2 X' r- q8 @9 N- n
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|