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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.6 Z! G, H* Y6 p* D% W
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
- O, [: H+ k c- ~/**************表达式计算器************/% w7 P8 v/ S1 q" n
#include <stdio.h>
& ]% t, R3 }& x N$ w" d#include <stdlib.h>
4 y) I/ e$ H% |7 }#include <string.h>
6 w9 B9 d& H; ~: I& w1 n#include <conio.h>1 K- t' s' ]7 d: ]" w
#include <malloc.h>$ A& N* Y& J; \6 }" r( v
& q- e! [% Q5 G7 a, c% b
#define STACK_SIZE 100" |" `( U& e6 e
#define APPEND_SIZE 107 c2 { V9 i+ y- L4 o5 d
' y2 e1 Y- u W2 T' t( E a% R, xstruct SNode{/ }' Z" S# {8 ]7 {2 F; a
float data; /*存放操作数或者计算结果*/
! T5 W9 x! v1 U) v D) y3 V char ch; /*存放运算符*/. [8 L" u$ _9 P u
};+ \. N7 F5 N9 h) M& U: w; H
1 b2 x$ |! @" S9 C. G+ S% c9 _" ?struct Stack{
6 ^1 I- O G# k/ v$ e SNode *top;
- b2 z, l/ G! J! X1 F7 _ B) w, P# W SNode *base;) v$ N/ p% S! U! v) H6 R m, N
int size;* v) X( G7 {9 O# o9 x
};
5 X9 s. m k* ^9 x# e/ j/ w! L
5 Q) I. y* X) @/*栈操作函数*/: c! V' S; ]7 S. @; |2 b
int InitStack(Stack &S); /*创建栈*/
0 N# A: |' J5 Z5 g8 i# xint DestroyStack(Stack &S); /*销毁栈*/0 x9 @: n( c$ i4 U
int ClearStack(Stack &S); /*清空栈*/
7 e9 }# G# X4 r& i8 x. _4 \) C. dint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*// @4 V& `( [$ N1 C; J; L2 G
int Push(Stack &S,SNode e); /*将结点e压入栈*/% l4 b& X, p z' X
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
* U0 }' B7 r( Z" u9 R3 h5 E8 h" g* g
/*表达式计算器相关函数*/
8 e, {4 w# s* }8 o# F$ \char get_precede(char s,char c); /*判断运算符s和c的优先级*/
+ E- r8 j v t5 @8 n' aint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/* R6 \+ c, m1 S$ j7 M8 c
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
' L2 @+ v2 C8 Q/ s9 i8 ?float compute(); /*表达式结算器主函数*/
* k' L) z% D) W- D8 J% Schar *killzero(float result); /*去掉结果后面的0*/
1 @. m' G9 A" e6 k W' @$ O: Q) p1 Q0 l$ p2 N
int InitStack(Stack &S)9 `$ Y4 I& b5 r. E5 s! f, O
{2 E4 O I8 H* O
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
: k/ L: s0 {4 _. ^( F. A4 T/ s if(S.base==NULL)
6 d0 s; h! |9 { {$ _0 W, g( x0 P% Z
printf("动态分配内存失败!");
6 d" ?& n! I& l return -1;
7 x) z5 @+ ]( l& T8 D$ ~ R; { }
7 t- x5 y z ?/ T S.top=S.base;
1 ~4 ^0 p3 g' r; w( {( n1 X S.size=STACK_SIZE;6 d( K3 S7 V4 o/ i0 o
return 0;
9 @' r* E4 Y9 v, N}) \: G) `( k) q+ _ `: s
+ c8 ^9 ^" ^ @+ p$ h9 \- e9 |+ F5 S1 S
int DestroyStack(Stack &S)0 g) M- ]. R1 D
{
/ U/ T F9 w4 P7 y5 Q free(S.base);
' v$ w( j p# Y$ I" I return 0;% Q* N; O! Q, {5 W3 V0 O
}
& M. c( T( T R' N1 ~+ v" d- j' n7 \
int ClearStack(Stack &S)+ a% C( I: i4 _' [
{, Q H. h M M9 W- W
S.top=S.base;
) K1 `# i: \. B: X* u return 0;
% [' a/ o6 j" L4 U e}4 G) Q. [ {# M' n; J2 a; b2 Y
5 M. M4 `6 i3 uint GetTop(Stack S,SNode &e)
0 K/ }* q" @1 o% i. I# W9 `; b x{
1 P, f+ _/ [0 `: I" A, W if(S.top==S.base)
3 U$ K% d, z) @( k$ \% J {
) e1 [1 \! H5 x- e9 E7 F: y printf("栈以为空!");
8 i ?% u, F) R) F0 c7 \+ ` return -1;7 C, A1 m! o: I+ }5 K& @ r
}
8 Q; J7 X$ j! U) X, j: L7 X: d e=*(S.top-1);
8 P; f; \! ~: A3 h# V5 ? return 0;
3 `, w6 o1 d9 a3 F}
% x1 G! [7 M5 k) y% [, A4 ?
e+ d- M4 w9 B9 w9 ^7 j) U8 ^int Push(Stack &S,SNode e)2 s7 [# }4 a; i5 V. b
{! n/ B' X1 K1 c1 O. e
if(S.top-S.base>=S.size)
, f6 D# Y7 T$ i& _ B: f- s {
! A. z) Q! [) {( H- z. x0 K S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
4 Z, S7 H! N; H6 J, r3 z4 r I+ B+ D if(S.base==NULL)
7 Q+ y) Z6 Y) Z h+ e$ O1 _ {
0 I1 S& i& A: c. x* \. |, H printf("动态分配内存失败!");. O% s* m- f7 I. c! r$ o
return -1;
! S3 \: ]- w1 `3 @ }
2 d6 y/ [! @" g5 ?, A) w1 G! N \ S.top=S.base+S.size;) |) H( o3 \/ k
S.size+=APPEND_SIZE;/ e$ c. D* b; x/ V9 i3 f
}5 Q5 r" {& y% A3 m, g! n
*S.top=e;
4 m/ p0 D1 B0 o! ` F+ @3 ~ S.top++;
9 b9 A. w+ o& p3 @4 t8 i; b: O1 I. e return 0;
3 \2 h' J! J; l( r}
+ v2 u1 P' i. L
- G$ X' m: S" X2 @$ f8 ]/ tint Pop(Stack &S,SNode &e)* D1 i. k' T V+ \! A2 P& C; I
{
( q" x7 {: A, l4 L; G if(S.top==S.base)
2 L7 ?. |# z* G4 p8 Y6 e# B {
3 p$ K, I1 F5 M* ]" a printf("栈为空!");
3 u$ A# i6 A- Y" S, k6 | return -1;
x2 f# @5 |4 G3 P, ? }
! G0 R9 x% m; d: `. Z6 a4 } e=*(S.top-1);
/ r; B) I3 Z# z8 f6 @) S S.top--;
6 B" f+ H5 o* |0 ^ return 0;
5 n9 m7 ]5 f5 y0 C}0 Z) c/ o& z9 U; j; G) h1 K
0 u% @: Q: D' t6 Z2 a
char get_precede(char s,char c); k6 ` s. J6 |
{
$ G. I# o$ j) X3 \$ L2 m switch(s): h: a) G2 W3 j S$ G, z
{
3 R( }3 q5 R! d8 z( C case '+': ) B6 S- m' A4 e3 y; }- g6 D
case '-':
# [- O1 x, e% {0 O+ k" ^8 z% [ if(c=='+'||c=='-')
+ ?# c6 g T, Y/ v3 ?3 F m return '>';% ]; A5 |5 f1 y3 U: T9 k6 Q
else if(c=='*'||c=='/')7 B' Z1 h o5 C7 Z8 {' u
return '<';3 U) w' x* e1 O& D
else if(c=='(')9 ~9 w% M0 X5 h9 b8 s5 k
return '<';
y- p7 I. ]2 M2 _3 q' C else if(c==')')7 M2 p+ w0 m, Q0 o
return '>';! R0 W. c$ m( P5 N1 ^
else & H* T, Z' M% F1 h4 @
return '>';$ l9 L0 t8 ?5 J/ x% u
case '*':
* r4 I0 m1 T8 ^) q" k case '/':/ I: f, N+ P' S; u7 e
if(c=='+'||c=='-')6 Z9 D& n( ~( {
return '>';& k! G7 m/ r7 ]0 a: s+ F
else if(c=='*'||c=='/')9 Y* L: N5 c2 R
return '>';* E# i! }+ H2 I9 c% m
else if(c=='(')
9 i; {! }% y( C! T( U* r return '<';/ \, q1 V- l7 _9 q/ n
else if(c==')')
# c* A* o% A0 r( N return '>';* ^( [$ G; c7 J' E E4 K& V. S
else, r/ B: |/ n! Z' B% g
return '>';" z. w: k5 w, K5 n5 N: J( F6 ~
case '(':
5 l/ C; o2 _% U( ^ X if(c=='+'||c=='-')( |. u6 u% {, }# C V% V
return '<';
: e$ a+ t. w! [# ]( s else if(c=='*'||c=='/')! X! l7 f! g" U; r
return '<';8 g+ Z" T Q6 ]" x1 k4 o
else if(c=='(')" b5 y0 g& I d2 n2 i n# ~( W$ P
return '<';
6 S3 A8 l1 }$ g c3 o# W else if(c==')')
1 T9 N2 z9 y0 C$ J# v return '='; s1 o: ^* G! x- Q# }
else j. o+ F# b# H4 W5 e
return 'E';+ c& n3 K! j" p( h
case ')':) h0 O% j7 n( N
if(c=='+'||c=='-')
5 j. W, m4 m' g2 q6 L# F return '>';* V5 v; d/ Q2 P7 B- ~
else if(c=='*'||c=='/')' M- @" @" j. p1 H9 G d
return '>';
9 Y7 a) o. h) o else if(c=='(')' k; j5 r7 N4 V8 L+ \4 T E% b
return 'E';
: S2 y8 s1 k8 ~ else if(c==')')8 N9 T ]# k' d# F |' ^2 t& g8 R
return '>';0 [) u! t$ i; R6 \- r/ E }
else
- ?/ A2 f7 T8 y1 C return '>';
Q5 x3 S6 m: g case '#':' s6 V0 c2 Q: j7 \0 X
if(c=='+'||c=='-')
4 o; y, q3 O% P/ G4 L9 w return '<';) G7 j5 l3 `2 B; K1 |, f; p' A
else if(c=='*'||c=='/')6 I' i, r7 F( Y, m1 l7 c+ w/ g/ D
return '<';1 T! K7 U D$ g& z* ~+ w
else if(c=='(')7 P, i+ {* m7 e- U6 M2 f
return '<';
! }4 |4 {0 J1 F else if(c==')')
. ^. p" }6 ~0 r3 O return 'E';1 \8 G5 {7 j ^; Q
else2 C ? z0 q5 z6 C5 X! h V9 d+ g5 X+ S
return '=';# O! u. @, H4 M
default:0 S) C) ]5 ], T+ }" {
break;+ _# \* I. |0 W
}, A5 q2 T, i9 v& p
return 0;
. l3 }- E5 V. s3 @}# N( ^ e2 u7 M% U8 O3 n
- d9 w& t' V; Q/ ]" q
int isOpr(char c)
2 u4 A6 a) L% a7 M/ a{
1 l3 _5 X; \4 s R( q if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
1 r; F9 x9 Z7 L return 0;
2 G5 F% {$ k. n1 L' c9 x else
- q. t9 w- S: X' s& R4 n return 1;- D2 ?$ [( G* n: v2 r8 A! C
}
2 r. z$ @! W0 X) ?
6 {4 f4 S$ d4 V w5 X6 q$ }float operate(float x, char opr, float y)1 M7 c2 Y" E) B$ A# `& n
{) z0 p6 R% p& W) z" Q2 i
float result;2 _( R8 |$ e6 ?0 d. _' H
switch (opr)
9 c6 Z* {1 R. Z. C, u8 o4 c: { {4 H$ T/ X) s$ N* h. p2 t* q
case '+': 5 |9 `/ P5 A- c3 N$ N! \$ S6 k* F
result = x + y;5 R6 e" s# V6 c- d& B2 c6 O% T9 g
break;
; @! F: S, ~4 M& _$ O case '-': 3 v( i" Y ^1 } m ^+ N
result = x - y;5 C& A) w2 X6 W3 S7 i: m! Z
break;" g2 x8 ]+ N1 m1 F8 h
case '*':
% p5 q$ Q0 O; e# C& U result = x * y;
8 q2 [( F+ A) A" S+ z& A$ w break;6 B i# M- Z2 n* C [
case '/':
: ~. s4 K2 f \- @8 o3 o7 F- r if (y == 0)
) X' l5 q" ]7 q) s {
* S$ y5 C- r4 P# h0 i& w7 k printf("Divided by zero!\n");
& U+ \0 a8 a! M! Z) G2 Y return 0;( ]; h' Y9 L# X; g
}
$ i3 U2 e9 h# @" t# J else
0 M2 h p. r+ c6 p: v {+ K @3 I: l! S% m
result = x / y;
' q! x1 K% _( Q5 q- A1 Q. J break;
: }) V+ I) L4 |. p }
: P4 R# P, w: T' s default: 0 J; L1 [/ T b
printf("Bad Input.\n"); ' T- s5 s* z; v( B
return 0;2 p; f& d/ [$ |/ T
}
. \1 }$ H' Z4 a- r' q& b return result;
2 z' g( ^* a- n8 k}
# v1 \- F& H g! |4 C/ a( ^! |0 ~: Z
J& P( d1 b* d( G8 [) Hfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
& V+ p. P7 y6 Z# a- Y9 O+ P0 P) D{$ R3 Y" O. O& q0 V9 y
Stack optr,opnd;1 P; \! v! ]4 ~+ D. x1 a4 i$ y
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;6 ?3 A- Q2 u( R; D2 g1 _
char c;
4 |* k! R0 I& g+ N. Z& f char buf[16];1 d4 V$ P. v! s. ~9 @2 ^. W# n7 M; ]
int i=0;# y, B! |9 ]5 J" i+ P) }5 q
7 b" f6 @0 U$ m& k* p( r( a8 H4 D5 N InitStack(optr); /*用于寄存运算符*/
% Q7 e; y* C a% o4 Q( `$ | InitStack(opnd); /*用于寄存操作数和计算结果*/4 _) J7 @# J8 F& P3 B1 j' u
memset(buf,0,sizeof(buf));
9 S8 |6 f' k' Q: \+ z! q
6 z/ z; h7 C) ~& h( y' c5 G+ j printf("Enter your expression:");
7 {$ {1 |; w: k! B+ z- M* B m4 G4 A2 J6 S; ~. c
opr_in.ch='#';& U' m( ~4 ~2 [/ u
Push(optr,opr_in); /*'#'入栈*/
4 V4 ~ I3 `6 P7 x, O GetTop(optr,opr_top);
7 w5 [/ S5 p; Q# Z c=getchar();
8 W9 P5 S6 `4 H5 ~( K- U) K while(c!='='||opr_top.ch!='#')
. R3 w; h% K2 ^& x+ I! c {
8 ^8 F4 v! v( i+ L' [ if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/( p$ z; z, z" s8 F4 ~8 Y3 A: c
{; u, q6 l3 d$ c6 h" v2 N! t, ]
buf=c;: I9 H! Q4 P$ [( k: C
i++;, v7 W( x1 K4 u H/ {" `
c=getchar();+ I/ `- B7 a2 [2 k0 g% Q; c) V) n
}8 W, m9 V- j) o# `, _
else /*是运算符*/0 m% x( j* t# J0 _) [0 V
{
8 D. |6 j& } m4 k% C buf='\0';
) ~# f3 \, w( [; ^! {9 ? if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/4 Y) |3 e9 `+ d
{) T/ o; t2 F" v0 s$ j: v1 m
opn_in.data=(float)atof(buf);
! x% o2 m- R# h. g: j Push(opnd,opn_in);& x9 [) q. K J( D' Z& K
printf("opnd入栈:[%f]\n",opn_in.data);
6 O9 n* a! z6 j+ r6 H, O i=0;
! |, J u6 q0 H/ l$ Q5 P memset(buf,0,sizeof(buf));
+ R/ t9 h+ |; S }( Q8 N! L- ~+ I7 \0 [6 S2 P* v
opr_in.ch=c;
/ @/ z5 i! k, N( E$ r; j, t switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
! ` H3 c1 n1 g+ k2 ?' j. X {
# n) @* G* j6 |2 ^. @0 J case '<': /*优先级小于栈顶结点,则运算符入栈*/! [7 B K1 P" r5 R8 s2 [
Push(optr,opr_in);0 T. x# Z+ [/ i, `1 s
printf("optr入栈:[%c]\n",opr_in.ch);
$ a, ~& u* a- N c=getchar();! k9 I Z& i. v
break;
S7 b8 A J/ E case '=': /*优先级等于栈顶结点,即是括号,去掉括号*// J+ s7 S$ e& i/ c3 M
Pop(optr,e);
- ~ C; Z D0 p printf("optr出栈:去掉括号\n");1 V( T3 D9 }0 F$ J8 z; ^
c=getchar();; W; o9 x( ~/ ]* _9 J4 K
break;
% i' g( @3 S- ~2 T2 g* E9 j case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/4 B7 S3 m) x3 O8 B0 c- X- H
Pop(optr,opr_t);
4 [# c2 B# o/ I Q& o printf("optr出栈:[%c]\n",opr_t.ch);
9 b+ X& X3 _& O if(Pop(opnd,b)<0)
0 m t* z. k1 Y$ j- h8 N {
; U1 O7 ]5 @; i0 j3 E printf("Bad Input!\n");
5 f. ~9 U% h- ^) X" f fflush(stdin);
' m- O3 T* f; V0 w- ~ return -1;: I, h3 M2 ?6 U" F/ z8 w; F
}4 m& i; E% `3 ^3 W
printf("opnd出栈:[%f]\n",b.data);4 F& X0 z# C! h4 h
if(Pop(opnd,a)<0)
7 E7 r+ t, z, H5 L {
! n' q- n% ]: ~% y8 V3 j printf("Bad Input!\n");3 L" Q& \3 k' n( I7 F
fflush(stdin);
4 v. l/ G/ T7 ]2 T" Z, ^7 _ return -1;* D/ |" {5 M; l Z
}
5 }8 W% D: x* {+ n, { printf("opnd出栈:[%f]\n",a.data);) G" o3 @9 Z3 b# r/ R9 R; K
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1 i. p# F# c) y ], y& s* v Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/# W2 v; }% `: x
printf("结果入栈:[%f]\n",opn_tmp.data);
( _5 ~- T1 {7 ~ break;
" m9 o! Z8 c; R& O$ l. C3 X }+ x7 A6 l$ h( e# r w- f
}
" `2 t+ l; O+ x GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
( G& E7 L" e6 X7 k" L: Q, T }* r* r! w( U9 ^6 v2 j/ y, y
GetTop(opnd,opn_tmp);
' x- w3 A* `* k% Z. V; Z3 C) k; z4 Z DestroyStack(optr);
$ x" W' ^" S+ Y3 [: { DestroyStack(opnd);
" k# q9 a# F4 `. z return opn_tmp.data;
9 K/ r: X) P X+ y2 ]! Q$ K}
, l% y+ F- D: ?3 v* X. C' U
2 @. d- |& U; @6 Kchar *killzero(char *res,float result)9 Q8 _7 N4 b8 m3 U
{# S/ R" Y3 K+ C9 e2 J, N
int i;0 B% W% B, f& i! I) n/ J ]
: T. O% X6 R- {8 u; ~0 P
sprintf(res,"%f",result);0 W% O) j. }1 w5 k+ r( _
i=(int)strlen(res)-1;# \/ S& u `0 q; ]' E
while(i&&res=='0')4 S: l4 _# w- j8 h; g* w- n R
{9 C" |& J% R( F; Z. Y
res='\0';; L8 R2 s' ?4 S/ |9 k
i--;
0 K! K$ ~$ e. e* L5 ]* P; w }
* T. H' G# {2 ^ if(res=='.')0 C4 X) f; U& y9 }3 l
res='\0';
" j8 q5 _3 Z. s; q+ R4 K2 X return res;
9 T- U: ?( ]6 D& b+ ~9 g}
! H, l/ F7 h: j: X( D" _0 X9 G
; J8 ]4 U7 o# T: B. d6 b: X' ^4 uint main()+ s- C. r) ^; G
{
& P1 h8 s% C. k. Q8 t char ch;
. a6 V6 V% A8 |9 z$ k5 ~% t char res[64];7 O! h+ \. f5 K Q
float result;
8 l+ M9 P* f# I9 l, R, t while(1)0 S* ^% g8 m5 Y) N
{
1 f6 H) y- Q! K* O( l result=compute();
u6 x! ?, H& Q* [9 ~- |% k! g# ` printf("\nThe result is:%s\n",killzero(res,result));
( P X" K$ C5 _/ ]. T& o: _2 Z/ N6 s printf("Do you want to continue(y/n)?:") ;
- A/ Q: ?: P- k3 q% q ch=getch();) x9 E- U& E/ d
putchar(ch);
9 f7 {# t' g# b) l; p if(ch=='n'||ch=='N')
: w- M% g+ H6 H! Z: K, s break;
$ d- f8 U7 u, Y# X t else
: W: Z6 y; ~+ V& s, C. G# W0 ~$ {# W4 w system("cls");. b& C/ R/ }$ R9 `! L9 F- X
}0 \# n5 S- t0 [: k) k
return 0;
# }+ W- ^0 I0 ~! G}/ k! j: G8 f/ c7 T/ b- |2 d- }
) V; K4 C. V/ l' h* u. w4 e8 P, }* W
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|