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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
- M- r8 D! I; j: f程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
9 i/ Y1 b, N% D$ d4 h/**************表达式计算器************/
! L }, k' p4 l" a$ X4 ?4 `#include <stdio.h>
; R: P) T' |$ o" c#include <stdlib.h>
8 x- O! r* N8 M, q; _#include <string.h>) Y0 [; s8 ?; P0 y+ C
#include <conio.h>
9 ~) U$ f0 C& k. Y" H* f#include <malloc.h>- ^8 j6 V$ K# j$ n$ u
: Y, y+ p/ y8 _" @7 @" O
#define STACK_SIZE 100
* I: Y- }8 I6 i#define APPEND_SIZE 10
$ b R' `9 {* K3 G( x
- O: t; W+ w9 V! _ s: @+ Astruct SNode{
# M. H& }& V3 @7 j float data; /*存放操作数或者计算结果*/3 a7 @+ t& U( X2 }2 t Y+ v! C+ P$ [
char ch; /*存放运算符*/" o0 s: A: A- _. e% q6 y
};9 B8 X% K# l' F% e l4 V: S( A
, e0 a, j" v& `2 m2 y6 Y4 }
struct Stack{
: ?9 _6 K0 ]) @ v3 I; K* ^, I SNode *top;' a; D7 A+ Q' L2 u& F
SNode *base;3 P$ V/ r' H( y2 |' e
int size;
( t- F4 n. u! n};
. ?% \' f0 o8 X5 e1 o$ o* P* x+ C
/ g6 s; }6 M* H! g9 x' M- h/*栈操作函数*/3 ?7 O+ t2 c: z! S
int InitStack(Stack &S); /*创建栈*/8 v; O. l! _1 x' i6 [
int DestroyStack(Stack &S); /*销毁栈*/% h9 q8 x! [! `! ?7 m7 N
int ClearStack(Stack &S); /*清空栈*/
8 m! b6 f$ G2 F0 _int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
0 H% J/ {' v3 T: s% ]2 }int Push(Stack &S,SNode e); /*将结点e压入栈*/3 v& l' w1 e8 ], c) ~4 ^! ^" g
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
2 a# ?1 {! o0 j6 ?% X: M( V' J+ z/ X# g& m( b6 n
/*表达式计算器相关函数*/% x2 q* I0 \9 G7 ]
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
2 H/ `. M$ R. p4 o! D4 g- a; `int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
9 k! p" \6 Z% T- xfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/0 v4 L! W0 I; L- L! z
float compute(); /*表达式结算器主函数*/9 k, y2 z; R5 o2 g3 x
char *killzero(float result); /*去掉结果后面的0*/
; s% r- e% i2 Y H- ~! o
- Z4 q. p. l% d- Iint InitStack(Stack &S)
O0 U. K" Y+ g' @* H{8 A6 E- Q/ q# }" r
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));" w( j& v% `/ ^/ o& I' @
if(S.base==NULL)
( o. @% r1 U5 y% n4 l- D% X7 Z& u. i { o+ o/ C4 P8 c
printf("动态分配内存失败!");. x7 @# s h- I$ E7 W
return -1;) u- R+ c1 F! y. F% [
}) [% B3 W/ f$ \, R9 t$ @
S.top=S.base;5 H3 C9 I7 `4 q" `& r- c
S.size=STACK_SIZE;" E, Z3 Y+ d! @9 D
return 0;" i9 _% m& P: |; M" x5 M
}
$ S5 t: h7 _7 L' N2 d5 N
; L- b+ z' I# w J. J" rint DestroyStack(Stack &S)
* O. m9 f. T+ m( E' I{
) i! h" p& {, n: C3 U, Y free(S.base);; X9 [) Z1 Q2 r; |: E% ?
return 0;' { @" {+ R2 r/ m1 B: ~
}
/ Y) H L& P, j0 U; e4 R6 N4 L. O8 Z1 J; B# U
int ClearStack(Stack &S)
: M; u+ N# R, @8 h+ g" Y. g7 M{
' w& h) ~- E# J5 y1 K$ Q8 v1 Q S.top=S.base;: ~6 L; E5 A# [
return 0;6 _# Z) C, g2 s O' D1 z4 b- w
}. H9 h3 K+ T3 [' H
" i9 t7 O5 J5 |0 d, _3 {
int GetTop(Stack S,SNode &e)
- ]; B- h5 E. d4 C{
* @& \! o4 n- y% W7 O if(S.top==S.base)1 W4 C; `" z+ z" ~: f/ n: B; q& [
{
5 @; r. ]8 O0 @# S: s printf("栈以为空!");$ d# h0 a3 M/ Y8 }0 G- v0 N
return -1;" s# N; n+ P* R% Y2 q! } U
}6 h, K, a' f7 r' O' z2 e; W {
e=*(S.top-1);
* i0 r: D2 G3 c$ H. d8 m return 0;
0 K+ H! m0 k- P( Q2 Y7 W+ O! v}
9 I- j% `3 l' G S3 M4 \- [4 D+ S9 i. S& J' f
int Push(Stack &S,SNode e)1 Z; J, ?* T1 \" e& ~
{5 ?- A8 x* h& s8 `
if(S.top-S.base>=S.size)" f, ?1 U8 o2 j$ z5 f5 I1 w
{9 ^: W: P Y$ S& N* B
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));9 N( d+ t6 P9 P( X+ I$ M' V) N* w- K
if(S.base==NULL)1 l/ e: Y: @1 B" }$ t3 S: N
{
# { f" Q) x/ ?0 Y D8 Q9 B; E5 b printf("动态分配内存失败!");
: E8 r1 U2 W- {* K. B+ b return -1;
* x" D4 Z9 T/ y1 {5 g8 J }9 F. g% u- k7 p2 @- R, ?
S.top=S.base+S.size;0 W$ I+ P- [! L. ?1 }+ Y5 s9 V3 Z9 |
S.size+=APPEND_SIZE;
6 }, I4 K& T, d: j& E }
. O; f/ q9 u$ t6 `2 D# k0 ^! Y& J *S.top=e;* R% B j# v$ A+ e% \
S.top++; m# M" f! n3 a. K1 @
return 0;
5 \0 a8 U: {1 e$ g; Z+ H% }3 D}
: }) g7 O) t7 ^: I+ T8 g" \, j v: P- J
int Pop(Stack &S,SNode &e)
9 l$ v9 n N0 M2 C; B{) P* W9 x/ g4 q/ w- c/ n
if(S.top==S.base)- b6 S5 e$ K! m& c
{
; A7 N& d% ?2 z/ X, x1 o/ a; R printf("栈为空!");* ]1 G6 P. L% {7 }( {. W
return -1;
" f& a# b& B O! I }
6 V0 H8 g5 x, f+ ]1 v e=*(S.top-1);
7 h. ~: s. q. E: P( Q S.top--;
% ]0 O: ~2 m# N" C/ B return 0;
% V2 i. u! ~& b) G}4 ]+ \2 ~( ?3 s. o" M# h
. e; B7 k$ T. K5 h7 S
char get_precede(char s,char c)) z) ?& x! u7 f7 [) |3 \, c
{$ |" d1 i8 c6 j2 q
switch(s)4 N- e& x' _6 M# r* U0 X# b
{5 j: {! w% u+ b) Z; V( |
case '+':
' L1 [- O9 c# L: W! T case '-':- y+ P! P* Z) _5 ~9 F: j% T
if(c=='+'||c=='-') d' N2 {8 N4 ~$ ?
return '>';& z/ L" X0 G8 y1 u
else if(c=='*'||c=='/')
# z: A* J0 u; F9 C. Z return '<';! ?1 T& ~2 L7 D- k1 k/ `2 F0 w
else if(c=='(')7 A% K/ k; H' G- ?) }
return '<';3 l0 h" W& }2 s A" I
else if(c==')')
( C' s* T2 e8 y. Q2 ] return '>';8 E) {, Y) M8 S7 M. B
else 9 F9 O- q4 ^7 @) `
return '>';
) o% v% F2 g: g+ R7 Y case '*':/ `% Z; @* ] }- C; Q; ?( O3 W/ ~$ U4 w
case '/':: C& ~3 J7 b3 \( \# ~
if(c=='+'||c=='-')
% F! Q& o" |+ A6 u. m return '>';
. x# {2 @( u7 i( e: {' Y9 A8 k else if(c=='*'||c=='/')
5 e' @2 r/ }! \% U( ^' D" z return '>';
: V( O8 c) Q( J; Y! j1 G else if(c=='(')" V* Q8 y3 R5 n# \) d, b2 f1 P
return '<';/ v X- c/ L$ \7 U. ^
else if(c==')')5 s" ?' `: B: h7 l
return '>';. Q/ b* a* v6 w/ `
else6 D* O8 Z: [, C" o8 p; Y' Q
return '>';
3 ~( O/ Q( a9 u case '(':
$ Z I# j0 f; U3 E- p7 R5 J: X; Z if(c=='+'||c=='-')
6 A/ n9 H# u' @7 p4 J. C& Z/ x return '<';3 @1 c6 m2 z* y1 P. s- `
else if(c=='*'||c=='/')
- q9 L& v/ T, T" }) L return '<';
% h! M5 ~! g! @" w a2 S else if(c=='(')
+ G/ U/ q2 P D! H1 ?7 c; g return '<';$ d3 r' _. Y! @0 E
else if(c==')'). O2 K- X% n3 W- e
return '=';
9 R" X* x6 A5 y9 [ else* S6 s; l, t1 y4 i I) d; L5 c
return 'E';
. ~3 J: ]+ S7 W; L6 R2 i case ')':
1 [# @1 Y5 X( f) ^2 f: {6 p$ l if(c=='+'||c=='-')
- j$ [3 i$ B9 F. n+ ^& G return '>';
4 @) W8 p8 u& a2 T else if(c=='*'||c=='/')
4 {, A, q; E+ d return '>';
# x. L" I! o7 O* v else if(c=='(')- b6 t, n& o3 y# A$ {. j; a1 k. p
return 'E';# l/ D/ ]* i: {) g+ w9 Q( S# M
else if(c==')')+ U0 l% |' C9 B; X4 e/ d v
return '>';! g+ {7 D& J2 {& _1 o
else
6 t4 q/ l8 @9 V. v+ z5 E( I6 X return '>'; s9 v. h5 c9 a5 T6 N( `
case '#': N4 Q2 c b0 R4 @( C
if(c=='+'||c=='-')2 e' G6 N, @5 n7 X
return '<';
, O5 T2 ?, L& O3 J9 \ else if(c=='*'||c=='/') q q. B: V5 j! T: R9 {
return '<';
}% b+ C/ r; [: c3 w else if(c=='(')4 p7 v+ Z5 `2 C1 j$ o7 ?
return '<';
. ^9 Y1 g: F) ^( z& C5 z. x- G else if(c==')'): I, r) }) s# Z2 _
return 'E';% o4 c' m8 N/ y- X y5 m
else
! @& I% [6 R3 V return '=';+ O" d( Q& r0 A3 _7 h9 g; e) b- ~
default:3 C/ q1 H- x) g( a" N
break;6 H/ t {/ b* m+ s# J( v c
}3 h" {( Y; a4 G# S" J2 R( V
return 0; ( j6 J: a1 y; d, o8 I' g
}0 O- k; {% O* y& Y+ p
8 D2 O+ _; V( gint isOpr(char c)
: a* Z& u( o% q; S5 y' L{
) u1 z+ @$ E9 g/ l# P b9 b if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
) a t% I# g4 u1 x1 C6 H return 0;
f9 U1 H8 f: J8 h6 u else
% }0 w2 i( b3 \% P( R- r2 d return 1;8 E( e) j/ _( L% h- \
}
; m- J. Q/ o+ ?/ y
; m1 A, s! q6 A, M8 Q2 jfloat operate(float x, char opr, float y)9 d4 ?, i, w( |: y
{. q8 W/ F. h% ?" K& ~) P5 A
float result;/ b& K L( h s
switch (opr)
9 B9 J9 [4 V# D# o1 `" u5 p5 R. ] {
7 | X4 K; h/ { case '+': ; Q- m$ ~& @* R3 \
result = x + y;+ U. |9 o. w0 h p9 W+ ~
break;7 o& K5 R6 `: \/ }7 D& _- R
case '-':
" Z F7 G5 M7 t: _ result = x - y;- D) V2 l5 t! ]: R& k3 ~5 F
break;
, r2 r7 T1 Y/ R! \) g case '*': 4 H* J( k1 b1 n5 M4 C8 i
result = x * y;
" x6 _: V/ v) n2 ^ break;
- m2 t" k( i r7 X! O3 A case '/':
: {, M1 v, `; C& ]! _& C if (y == 0)4 p4 r* y. X$ A; ~& N# [' t
{0 T5 c5 F; y3 y6 w: T
printf("Divided by zero!\n");9 }- Z5 p: z$ x3 D6 u) B
return 0;0 u5 v( q; `: S2 I* s
}
2 C. r6 R6 _7 n& Y3 B' _: U0 C& P% u else2 C5 o- U+ D* Q0 C4 Q# O
{
$ W6 d) w o- c! ]7 M0 u" r result = x / y;
" _5 r/ l0 [- }% s break;
k4 t' i* y: H9 ~0 L4 B/ F9 h! V }. W. d! g4 O1 s0 x9 M+ _( F
default: & Z- H0 d/ y5 n
printf("Bad Input.\n");
( }' Z4 N3 X; l( K b return 0;
2 U- q4 Y8 j+ M2 j; ` }2 T A, X7 H# ]
return result;
3 O# |; D3 ~0 o3 \$ z}
4 h) ~ {1 U; s" M0 J) f' l6 k: ]
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/) i' z: S Z' z$ {/ I! L
{
$ b4 E; w) c& O- \ Stack optr,opnd;: Q1 j: C" F2 K, J* S
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;2 P8 N5 _4 P: j( ?$ ]
char c;0 P) w1 @: D; Y
char buf[16];
2 H' I- g8 O) G& I1 U0 q int i=0;% y$ C( I e% M& ^# D1 w1 R8 p- Z" F
/ G' }; V# Y: [' t# B- h) M
InitStack(optr); /*用于寄存运算符*/
! w% Q: ^9 i. k; \0 z InitStack(opnd); /*用于寄存操作数和计算结果*/' m7 f: u6 i [8 Y- J; z
memset(buf,0,sizeof(buf));
) E7 s5 F( j6 L8 W ; {* n! b1 X6 a$ [& A
printf("Enter your expression:");; r9 p8 Q( O/ Y; H1 p
. n, f$ C, C- P, X+ M4 T
opr_in.ch='#';; N1 K4 @0 y3 n8 T% h, r
Push(optr,opr_in); /*'#'入栈*/& L( N4 A; ]2 ]
GetTop(optr,opr_top);1 U0 M/ ~( N5 h0 W& J
c=getchar();
. {3 o7 @% l, |3 W! Y while(c!='='||opr_top.ch!='#')% S! p4 G( I* V6 z/ i
{( u1 D/ L3 U; ]8 ?* }- Q
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/! U+ R& c1 B9 J+ L7 y E0 q
{ W1 }: k: u5 j
buf=c;: D. I |' K; C
i++;% l% _* m/ |+ a
c=getchar();) S4 q" a1 |7 m- G! a* u1 D
}
* E4 [# h$ E7 R r& b9 n else /*是运算符*/
, G$ G0 ~# }& j+ i {
2 F5 n1 U- C1 v$ N# R buf='\0';$ v0 E0 w( ^# T; t0 O
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/6 m7 C$ \( L$ s% u- \' f1 B; S
{. i+ D/ T- L3 B# @: ~8 }
opn_in.data=(float)atof(buf);. I2 m: W; {/ H/ \
Push(opnd,opn_in);
# o; Y2 H$ z! `1 A) ]: b* H printf("opnd入栈:[%f]\n",opn_in.data);5 b$ v# z. W# U& S! R+ C/ h4 I
i=0;/ Z$ {) u6 v9 R4 {$ w" n7 _
memset(buf,0,sizeof(buf));+ i/ V: b, D& M6 v+ U
}
: }" F9 V/ f# ~3 s, V& x opr_in.ch=c;
7 g& _; J' j2 i/ H7 f6 H$ F1 r7 J switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
w) A" K: }" x {
8 M1 {6 M; H- @& C# ~ case '<': /*优先级小于栈顶结点,则运算符入栈*/
# P- l, u W7 e4 X9 r. y( k7 J Push(optr,opr_in);6 d* _6 a: s) k
printf("optr入栈:[%c]\n",opr_in.ch);( y! F8 r; h, h5 w
c=getchar();
! ^6 b+ q7 M8 X break;
1 l# m! ]4 [% {) T4 t9 j case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
9 C, J8 O/ I3 W! ]; c. a1 _ Pop(optr,e);
" T, m# ]: @" ^4 g printf("optr出栈:去掉括号\n");" W, A7 c, T5 @2 H9 m1 r) L. B [' u
c=getchar();' I6 I, [; y- y8 t' p2 G3 G
break;
5 t& T5 ~ i, D# H' d, Z+ y3 _ j case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/. q0 A# v: ?! h! J+ Y
Pop(optr,opr_t);- S& d" F9 {! q
printf("optr出栈:[%c]\n",opr_t.ch);
2 t: x! m. {& J2 m8 p J s+ p if(Pop(opnd,b)<0): ]; N Q& I1 @" P5 s/ o* B
{$ D4 M# B" t+ F; a; l. j% v
printf("Bad Input!\n");
4 \: L3 q* Z% H, _* U v) c& n fflush(stdin);6 v/ p+ a% G" J# \/ \) U
return -1;
/ f) {9 ]9 |8 p# F+ O/ m9 Z }
/ X" c# V6 [/ D% z printf("opnd出栈:[%f]\n",b.data);
! p& m7 ]" @+ O# d1 x if(Pop(opnd,a)<0)" J# o& i0 q) U) {+ Q' Y) A! j
{
1 x' Y% m+ Q: h printf("Bad Input!\n");
7 p( U# y8 _& d6 M( p6 t fflush(stdin);. C) e: s! U+ G
return -1;3 |- j* v6 X+ m/ X/ g# J! _
}/ T$ e0 o4 R' o6 w2 o! o
printf("opnd出栈:[%f]\n",a.data);. R" \% U3 b- K# Y; h) w; P1 Q
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
2 F+ W7 n& x& V Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
' [& t9 H5 d4 h5 B printf("结果入栈:[%f]\n",opn_tmp.data);
, X7 _$ W, l: V5 _# t break;
3 `1 A \! l- ] }
# H$ W8 r6 C! `/ |" Y$ A }2 M. P9 R) B/ |# |/ k" q; h d
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
. E* o; d, {( r9 \0 ` }
) v, A3 i# R# _# ?) z5 ] GetTop(opnd,opn_tmp);) B9 [& J [" P L
DestroyStack(optr);# s# w+ U3 j+ E
DestroyStack(opnd);
$ }" |; K& h8 a return opn_tmp.data;& G( I; g# w# W
}
' Z o3 ?3 z& \% \
' s! I& I& [+ ?char *killzero(char *res,float result)
% P3 t: ]0 |' P0 @$ j: D4 c{) A1 q$ B0 X( L E5 b+ o
int i;
) ^ x' p+ r" ^8 d
6 v& T1 D6 X3 f u2 ]+ K sprintf(res,"%f",result);
% S% W1 X! u% b+ f3 S i=(int)strlen(res)-1; j4 m. e8 H, E2 X. R) O
while(i&&res=='0')% i2 I. X. H) H3 J# A* Y% j
{/ m- K6 n" W3 M4 A `- Q
res='\0';
3 Y* ^1 R r) ^) h: V i--;
5 g) ^ L) a- m% o }
$ B, t9 S* H! e& [- i/ C( }+ g if(res=='.')
. |- W2 H3 L ?6 H6 ^0 E res='\0';4 O+ f' a" o7 s4 W
return res;
# ~. d! w) @7 F6 L% y0 Y4 e}
" s( r0 v& n5 a2 |: {% M4 z1 b
' S7 O7 S" k! zint main()- j9 M9 n. }( t& @9 j1 k
{1 w: U8 |! }) H5 r5 K+ Z
char ch;
Y D" R! J: o; G/ U' n char res[64];
' l/ D" X1 H# _, q float result;0 O( A) _2 K- r. K4 T5 ]
while(1)# _5 ]+ L3 D2 N% W5 G& o* p, O, p q
{
! b& S9 v3 c% r2 P result=compute();
! m1 w% t) F% n# R. A printf("\nThe result is:%s\n",killzero(res,result)); J- J% ]# T" H3 }! R7 z% M
printf("Do you want to continue(y/n)?:") ;5 r5 q3 G& J& V) W5 A2 r% g
ch=getch();
! `1 O5 f C9 v, w, h% B6 e putchar(ch);9 j4 I' d5 ^5 @6 S
if(ch=='n'||ch=='N')$ s' J. q2 x6 B( a# K8 G
break;6 A+ c! w8 i$ ~
else
0 X' {; h& H. b q. F system("cls");
/ e9 B" s" |; U; A- V( ^, B& H- @ }) [, k3 q1 W5 f8 a
return 0; r, f! s S7 N7 d$ C" T
}
$ ]+ M7 g: B2 C; f$ n, Q! R* g5 C2 D5 |& D; y
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|