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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
8 ]" s( ~; J6 a程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
* {, u- a" V& Q( O( S* K* G5 R" S/**************表达式计算器************/
; m1 N# w2 h5 i' J#include <stdio.h>+ i, G1 X: q4 {& Y' [+ {- C
#include <stdlib.h>
# y2 a8 B2 O! `7 `#include <string.h>/ g5 O1 {! P, E( v* v
#include <conio.h>! H5 l) `* z: h; q4 `
#include <malloc.h>
7 F& l# J" O ], M! N8 A/ s( m" R8 F1 z3 R% {4 U: D
#define STACK_SIZE 1005 Z6 u7 b+ d8 x! Y
#define APPEND_SIZE 10
& Z( f: e# x# r$ j; \+ n, Q( R8 m
' m. M2 r9 [1 R! z4 Estruct SNode{, k0 ^2 }9 p8 f. x5 n: `
float data; /*存放操作数或者计算结果*/
, C% f0 X3 e. m3 g. g' ? char ch; /*存放运算符*/ b7 g# K0 `/ @
};
& F2 A$ ^) g6 f# i& X
' F, ?$ }( s$ ~4 cstruct Stack{
& Q/ O; ]$ X/ J% B+ N3 | SNode *top;
: m0 K/ o; s, ~& z& F) G2 { SNode *base;' D5 C, K1 ~ w# z
int size;
9 J% S3 m' f" T5 U& Y! N};+ B9 C6 |/ S5 f, D( H
! A" X7 K+ v3 Y- s! x& t9 s z; G/*栈操作函数*/6 [, j( _# ?* O: _4 {- m: \2 |
int InitStack(Stack &S); /*创建栈*/3 V' c/ I+ F0 G* ^0 ^
int DestroyStack(Stack &S); /*销毁栈*/1 J2 D2 S/ t' q6 |! X; [
int ClearStack(Stack &S); /*清空栈*// ], [( C1 r' e/ g: s
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/( C( O4 p# ?5 S2 i4 h* A4 f
int Push(Stack &S,SNode e); /*将结点e压入栈*/$ ?8 Y5 ^2 x5 M X9 c
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
! ~9 R- ^0 M* s: F4 ~1 T5 `1 J% Z1 |1 x) d+ w, f' F# x: x& n, U
/*表达式计算器相关函数*/
3 y4 B5 H7 _; \5 S( w) Uchar get_precede(char s,char c); /*判断运算符s和c的优先级*/9 b$ H! Y$ `' a, t9 v5 S
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
4 i$ D; Y8 z* \float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/* M6 p3 m7 b6 f% |
float compute(); /*表达式结算器主函数*/* x9 y! p6 ]9 w1 [1 j: t
char *killzero(float result); /*去掉结果后面的0*/
. x8 T$ L0 O; k% `" c! G/ W4 n" P" f% `' c1 U3 N
int InitStack(Stack &S)" Y e/ i9 K# n
{
" H; b0 x2 Q y& ~* n/ B S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));, Y6 c0 c( g7 {7 J S6 _7 h. Y
if(S.base==NULL). N3 S; k; a9 \1 ?. f0 d
{! o7 G9 t8 e8 @/ e$ [
printf("动态分配内存失败!");
7 e; `- @# j5 s h1 K return -1;. @. p; {3 }. y
}
6 e; t) [0 W4 f6 i4 l S.top=S.base;9 E0 I, l, v3 p0 B2 }1 \
S.size=STACK_SIZE;7 I- n* ^9 P+ |
return 0;, {; O9 o" c$ Y$ o
}: G5 I6 V" m& z- U
3 q Q0 d J' M* g4 M" ?( {int DestroyStack(Stack &S)0 ]1 I1 u% f. J3 I$ A5 b5 D
{- ^) f. Q: r7 E5 L) ?) e
free(S.base);
0 Y& G5 x% S; R& g3 _8 h/ Z* Q return 0;
7 c2 H% y, b4 }9 b: t}) w7 S. E4 z" M0 {
/ e* T9 m; C; I3 wint ClearStack(Stack &S)" ]* l% y# }5 m: O7 ] \
{
# \# ?5 A& }$ v1 ]7 w3 v% x S.top=S.base;
9 u: z3 R5 X1 s j5 k3 { return 0;6 R; S% e6 }: U$ R6 w" F( C
}- B4 N: z' F' |3 U/ [: p& e& G
$ {. S8 [. I+ [3 Mint GetTop(Stack S,SNode &e)4 N8 N7 l: a T; W9 S9 l( g
{* g. d O: O4 r% v' N
if(S.top==S.base)2 g- d( K8 u7 ~6 g* [ Z {' Q5 W# B7 c
{9 U6 q% `1 M' Q2 k$ ]/ O
printf("栈以为空!");% {) s: I9 z6 k' @/ K' X3 |
return -1;
6 e/ I3 ?1 g6 d& k }
& e7 K! a( R+ C, X4 X Y e=*(S.top-1);
- I1 U" u, p. z* M- r; v return 0;
0 H' q3 b9 H( w1 |1 a7 P: M}- N( S% O0 i# K% u1 m* ] a7 a: C, ]# R
8 a& f/ Q. W0 H# Q; F: w: P& Rint Push(Stack &S,SNode e)
0 ~1 K' {* k6 H! v3 z{1 V) y( b6 G& `$ V' s' H9 M
if(S.top-S.base>=S.size)
/ T! [# X7 d O) H8 I+ h c- Q {
( R; I4 W" f) ]5 E% J0 \# m1 h/ r( }; Z S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));# L$ C! D5 z7 X4 ^7 j3 m( f
if(S.base==NULL)9 P% f5 ~6 p3 i* X' J) Z9 c1 ]/ b
{
# n9 _' N' V; U6 o printf("动态分配内存失败!");
3 e& N1 o: b+ P3 j return -1;
n/ `5 F2 m0 m+ z1 D }% i* v* s4 f2 S9 v- W
S.top=S.base+S.size;) G- R& d! g- g$ b- t9 L
S.size+=APPEND_SIZE;
" d; O( A2 G$ m, E3 o! h }# V A0 d' ^9 U9 @
*S.top=e;
3 w {7 D1 A" ?0 a S.top++;
P4 G. \( Z6 N- k1 j7 s return 0;7 z6 i7 X" c. I5 I5 [1 P
}
- k1 L7 d6 q# j/ G. \( Z" U* F, h6 s( c, G$ W* v4 f5 R
int Pop(Stack &S,SNode &e)
5 a* z: X. K: l{
( i) i0 O0 H6 T" R6 i, { if(S.top==S.base)
$ C' f# K% }( p' \8 s% x v7 F/ x {2 k9 R( T6 Q) [+ Q1 `- E
printf("栈为空!");
: y- M9 e5 Y7 N( d# D) I& q8 e return -1;
8 S8 r9 n) Z! D; D, a+ y t }
2 X4 B* y- F3 U! M+ m e=*(S.top-1);
" ?( A! B5 I9 O O& f/ T1 S S.top--;7 s; t( M0 [8 d$ z
return 0;
% l+ T4 c4 m, Z) r' O}, B6 T7 E6 c9 Z, f
$ h' C. L, k& y/ ?/ B7 g
char get_precede(char s,char c)
) t- Q2 j" U$ x; v. Y6 _{7 t7 f- P5 y; T$ m
switch(s)
: _( j$ E; e2 K. V. t P. p$ H {* W2 Z$ c4 e& p" v g
case '+': % C+ s% c t. X4 x
case '-':
6 W$ ~/ A) k9 L6 @& w1 { if(c=='+'||c=='-')
- I! {3 O( v* Q; C7 u3 @6 C return '>';
3 O- l1 T' k1 v a I/ x else if(c=='*'||c=='/')
1 I; C p( e5 l' g/ a6 h+ A return '<';. o* p6 X( O- _% D' Z$ @
else if(c=='(')
5 @1 M8 e' x0 X) p return '<';
( I8 Z2 ^; c" @2 f9 J else if(c==')')# l) I# m5 q# P
return '>';
4 T- [2 A- O; f else * O" @% B2 M4 ~" V: Z: y `
return '>';
3 ^, p& W' M( q) p7 U2 ?# N& l case '*':
: X2 n. M8 T" h9 I' x% E case '/': s2 _* T* Z0 O, |% z$ P+ R
if(c=='+'||c=='-')
6 z$ U/ h8 r: u& @0 T2 Y return '>';3 ~: m. S* I' p: e, H
else if(c=='*'||c=='/')' z4 f% s* O4 d3 @/ |' Y
return '>';
+ X I# a; R$ } g else if(c=='(')) f% w3 y6 h9 M+ y* J. D
return '<';6 n; p% v" Q) ?1 m- \2 S* J% M1 \0 Z
else if(c==')')
2 o" n9 M) _0 v- D return '>';! l+ C; B& v8 @9 W( H
else4 U* b& A9 S: H) d
return '>';& g+ i ?! I5 N7 i, [) @& |
case '(':
8 b! |% u9 |* L2 ?$ \2 N6 W if(c=='+'||c=='-')& [5 O8 S* s. ], @# F
return '<';
. {9 T0 k* ?( g. K else if(c=='*'||c=='/')
$ W, G8 p8 R; s7 Z1 k( m return '<';
/ k( j6 l v+ } else if(c=='(')
* o5 J. _. _* q0 w return '<';5 Q/ Z% I \" H2 o8 k( x( r0 I
else if(c==')')
a% r& Y7 x6 g) ~3 g7 [ return '=';+ `# m' j7 A( s; g% D
else
* H* N6 R+ {5 {( D6 p return 'E';
* l4 f v6 M! @' O& g6 R# I" n- A case ')':3 ^! C- i, a3 p! W- C7 S' z
if(c=='+'||c=='-')
; d/ \) [1 _' j! b: J' ` return '>';- s) \/ L, V, H' {8 ]! D ^ N0 d
else if(c=='*'||c=='/')
% K3 L) s0 F5 \" _ return '>';
: L. P$ C v* _. r: N% q; v3 N$ @ else if(c=='(')
" d- Q5 C$ f* I% O7 Q1 v7 g return 'E';1 u* ?; y; H3 _ [
else if(c==')')
, `! s% j2 M8 X return '>';
8 C+ ?1 l1 ]) k% F* P else
$ J G R- {9 `- y return '>';
|( j7 }& u# V case '#':
& r1 j6 V" u* f! r, v, B* o if(c=='+'||c=='-')$ P: \2 k& N; B/ _
return '<';& a: u" f2 h0 }
else if(c=='*'||c=='/')
- a% q, J' o% f0 C1 F return '<';
/ k2 z) A* B7 H' v; U; U else if(c=='(')
0 P! C1 g' O7 J& A4 H6 U return '<';7 |& N. E8 p& U, O
else if(c==')')
3 w; U$ `/ v6 x8 E$ i L! i7 D return 'E';* d# i! K" i; v4 t# A: ~
else$ T+ A( w6 A. Z$ S4 _" q3 `
return '=';: I! k# e( V" L, O
default:# K. s ?3 U4 L/ I! n. h# S! C' y
break;( o6 y7 ?, Y9 k" d8 x
}
+ v/ H& Q( g( F% N+ x5 b/ R! M2 e return 0; 7 b% f1 a3 s; ?# J0 e1 R
}
8 O' W7 Z" ~9 Q1 [: G5 m/ E) Y
$ m. `0 t- r# fint isOpr(char c)$ K" i" {2 S( Z6 D
{9 x( y7 D, w, U; X& r! z7 R
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
& v% ?% {2 P( ~* L3 M8 v+ X) x6 Q return 0;# x9 L& ~4 l% _0 K4 o# N: _
else 7 T. K: a* x. J; y/ @& e9 \
return 1;: F3 X- v! t5 z' L n y! P# |7 z' [+ X
}
( W/ M& m$ Z4 G$ O4 J2 ]5 J( W' e
/ R* h* C9 R( L" p) A% T6 T, s5 b- ofloat operate(float x, char opr, float y)
. | g$ ~0 S& H/ y{" i# u" a5 x$ ^% u- b5 H
float result;5 x+ M9 e/ _2 b8 h. l5 `3 s0 g
switch (opr)
' x, R/ M$ }# B4 G% |8 s; c1 p {& O) i8 a V( ]5 A
case '+':
3 F% I" _- q" @9 M- J, F C result = x + y;& J2 a, g; x2 b$ n' p
break;
5 }' E8 S+ v. A3 r1 l. |2 r7 i case '-':
$ e0 |6 V. L% U e: o% y# u& Z result = x - y;
) o6 v4 [7 Y/ f; n9 }7 n( t" l break;3 w& y; n( o* y+ [+ e6 h
case '*': , W) ~- h: N% m9 p9 u# ]
result = x * y;, |7 O2 }) j' L% ~) D
break;4 ^5 s! Y2 O( m$ b- _# y' w$ |6 h3 U
case '/': % U6 c% n$ A1 `) ^: W' s5 l
if (y == 0)
6 b& |8 W3 f% T k+ X# P# U# n {
- m/ A7 c. J. S printf("Divided by zero!\n");! O. D9 A+ d- E6 a2 c
return 0;( T5 \/ ]2 o4 D' e3 V
}- X V# l9 v+ A% y
else! ~9 ]2 U# u9 `" a2 u ]6 x$ L
{6 a6 t1 u3 l! I! |5 H# W( e8 J; S
result = x / y;" s/ m+ r4 q. V+ H! L3 p. z
break;- T) O% T" k! `2 w& M5 O* W
}3 i3 x7 G8 s7 C( Z0 y" C% W* U( z
default: " Z% d( y( Q# o, e
printf("Bad Input.\n");
- Q4 b1 X# C# T% x/ O2 ]3 f return 0;
# A1 l; X4 n; [* g# H. H }( H& M( i9 q* \6 K! H
return result;% t. C/ C. c* p/ M _
}
( e; i# Y% @+ W# o3 J3 J1 H" D/ W# v% ] G
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
. M4 {2 S+ `9 K3 Q5 }/ ?& L{5 ]( ]4 j& q" x
Stack optr,opnd;, g0 x, V! A f: B: t
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;+ W1 f9 r- l6 P/ q
char c;
" U7 K( S. U6 P3 M char buf[16];
B( A+ o# N: b: L. e: k int i=0;3 T6 P) N9 {, j5 ?4 I2 q
9 C3 O1 c% c/ Z: c2 Q0 f8 v InitStack(optr); /*用于寄存运算符*/
1 k# @) M" k: [8 m( I$ n: w InitStack(opnd); /*用于寄存操作数和计算结果*/
* B# ?" g2 Q% t, F* [! [7 O4 \/ S7 t$ W memset(buf,0,sizeof(buf));
' P4 k/ V/ m2 \ E5 s9 i3 ]
6 S! x r: Q7 n5 x printf("Enter your expression:");
4 M! v6 X+ S4 q, ~7 ] & A; _1 p, Z. D+ f7 b
opr_in.ch='#';
% W6 W% x* A; B5 Z9 }2 A0 |$ j/ P Push(optr,opr_in); /*'#'入栈*/
& x0 [# A4 k7 k GetTop(optr,opr_top);. C% p+ i; p8 ]4 ^3 N9 e, W
c=getchar();
$ _3 z, [* _& w* X6 { while(c!='='||opr_top.ch!='#')
- n7 S2 M) D' G. } {, k: b" Q8 i# e
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
, w+ h3 J+ j1 a {; n n5 ^$ L! P
buf=c; P. y. f. ^+ O. q: a, t
i++;
' j0 L( j7 `- H c=getchar();+ I4 X6 C7 t% p5 |2 I
}9 {$ r* t; G0 y: Z- u# N
else /*是运算符*/
$ c- E' Q3 g- y; Y1 P {
& @) G; x7 J8 q buf='\0';0 x4 G0 }- R) P4 ^- t3 Q
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
1 C) z4 v: N6 Q {0 E2 U( P6 j/ R
opn_in.data=(float)atof(buf);
- R0 f" {. u6 I0 e* o# `3 N. D% s Push(opnd,opn_in);
$ z0 t1 _+ S0 i! ^: ?3 Q! C printf("opnd入栈:[%f]\n",opn_in.data);
0 h2 T5 U0 F- f1 M i=0;
2 B/ g2 W3 V1 M+ i9 H: X memset(buf,0,sizeof(buf));5 i$ P" Y; E* m& ?2 Z+ \3 @- R4 P
}# R5 f k* C$ P" j
opr_in.ch=c;( |8 ^9 k, g! h- H0 s$ p9 M; q
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/6 A7 @. t: g4 p: u& Q3 o r
{
7 B% s7 R. Q$ _# e1 b, ]2 C/ q case '<': /*优先级小于栈顶结点,则运算符入栈*/
4 f0 `& k+ p6 E+ V: U1 r' R Push(optr,opr_in);. f7 s$ P# I4 x; S: e
printf("optr入栈:[%c]\n",opr_in.ch);
" t& A9 t1 b0 d0 H g2 v c=getchar();$ ?) O: H$ V: Q( {. q0 |
break;- N+ v6 E. @' v# l% v
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
2 ^- j0 j7 F t- Z- |: v! s Pop(optr,e);
1 s- N1 b+ D- B9 z0 a printf("optr出栈:去掉括号\n");' X( n, K/ [) T4 g5 x A) [6 v
c=getchar();
2 ?; b3 u @9 k& o+ z7 Y break;
" \6 v) N u0 S3 B K case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/5 _3 ?1 {2 z+ ]" @4 \. ?
Pop(optr,opr_t);
: d g/ E: Y" ?0 {0 H printf("optr出栈:[%c]\n",opr_t.ch);
C6 g$ p4 V# M- a1 V( S' U2 M if(Pop(opnd,b)<0)
0 E- `/ h+ t3 \8 K4 F: [- v {
4 H- [! j# A. N/ l8 f printf("Bad Input!\n");# @) K5 t j$ O' S
fflush(stdin);
$ b2 n+ ^9 R, A" i7 e& z& B0 s return -1;
5 J" U1 }2 g0 f! H2 U }
0 ]! Z7 c3 P" V: B6 |' b5 o- u( F printf("opnd出栈:[%f]\n",b.data);! {) L0 f- Y0 l! b3 m
if(Pop(opnd,a)<0)
. a! C. O$ v- ?! X% T, |: k {
! }3 C! @% ?. l; G1 k! E5 s2 ? printf("Bad Input!\n");
* }4 |4 R4 w* K. q6 g3 g- K1 _% v fflush(stdin);/ c8 D. p! Q% L, ?- n) N/ Q+ T
return -1;
* i, o* u" q1 N( ~ }
+ N$ l+ J s8 N printf("opnd出栈:[%f]\n",a.data);5 o6 A& Q- y! C0 p- \
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
6 D: q( h( i/ K1 A Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/% f4 H. R" g4 ?, m5 ^9 p- e
printf("结果入栈:[%f]\n",opn_tmp.data);
6 l2 M& s& n' ~4 x c o7 @8 y break;
# ^1 \7 H- o a e; n% v/ z }! E, K; x9 ]* O3 c
}
- `9 y/ O' Y1 c& E8 p' O: u4 [ GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ ! ^2 H! C) C( {
}
8 E1 j4 c) z P7 X# a GetTop(opnd,opn_tmp);
; a1 k- _0 c, }: R' u' D1 |1 D DestroyStack(optr);
- A' K/ w, f8 e6 |* W DestroyStack(opnd);
1 t: ~* a7 S6 l return opn_tmp.data;
) t, x6 B H+ [}
$ Q& |, F4 b* V+ \) Z( K3 b3 Y$ `0 B3 \4 Y
9 i- k% Y s- L/ pchar *killzero(char *res,float result) J$ z+ X) }8 E+ ~
{
' k! ]6 h$ c. Z8 ?5 W* }/ ?9 W int i;1 m. ~# L, q2 T3 x; s# ?, h
7 O, u! H! o5 ?6 K+ E
sprintf(res,"%f",result);
`/ H" d4 e3 E& ] i=(int)strlen(res)-1;
: [+ I s3 z% B+ g while(i&&res=='0')6 S3 \5 p$ D( s: ?, V$ f: z
{
* q5 q- D! M5 @; x$ E% b res='\0';4 ~3 q& p9 o! e: D1 g% L
i--;
+ F) b5 X& Y' B. i0 i) s/ P }
, U5 G m R) l& ] if(res=='.')& ?+ E9 |. \- E4 k, L) t! U A
res='\0';% r: ~2 C1 n+ J/ ?
return res;
- J1 f% Q+ F. M3 @2 u}% z* f4 c0 q: Q ^ `1 M" D& ^
8 ^1 c+ }' h9 C" ~( d0 C6 i, Uint main()6 [- G1 z! _# T5 e! j6 u2 f ]
{
, g; K% B% O9 } char ch;
. H+ Y! c/ j! O9 u1 B( n char res[64];
* X7 e' P: `. j$ f" w float result;
2 |$ |; F9 \+ L8 E5 c while(1): t" l' p& m$ @ r
{, l, T* b7 J$ Q$ W- T
result=compute();# \; n- \% t& Y) I+ ]
printf("\nThe result is:%s\n",killzero(res,result));
2 D$ W1 A8 \( D/ { printf("Do you want to continue(y/n)?:") ;/ V8 y$ R3 Q3 q! G) v: \0 `. z
ch=getch();
7 _+ q+ Q; Z. ?/ J1 [ `$ U7 R/ r putchar(ch);
' Z* j1 }8 a7 U) `, s9 S if(ch=='n'||ch=='N')
* O' R: B/ y6 L2 l break;# h! f$ E1 Z) F. N5 \- i E+ J
else
# y5 `$ E7 ~1 @ system("cls");8 x. z9 z* ?+ J# u
}
( O: u" D0 Z$ S; p- ~* b T. N return 0;9 Q5 k+ |$ J8 v5 q; H- {5 N% S! C
}
8 J+ Z% u! u c$ }5 b$ c' N, z$ ]$ U* u% @* H; E9 Y
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|