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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.- X5 r: J0 x6 h' m+ q: U
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
/ z/ @/ U4 Y" j% N& s/**************表达式计算器************/8 T# M2 i4 o! q+ J" [
#include <stdio.h>* e3 }+ f7 ^% N0 l+ Q3 `
#include <stdlib.h>. R' s% k- N% W0 v3 W; C$ f& `+ w: r, m, J
#include <string.h>" B. e& a& P' c* O/ s
#include <conio.h>6 m7 B% @: s7 J( {- g% X
#include <malloc.h>* c* R2 D+ g, u' t' R H
' U1 V7 F( l: P! \3 @
#define STACK_SIZE 100
* T ^' R% } b/ M4 O9 e: ]( ~#define APPEND_SIZE 10, J, T# p/ K; a P6 f) @. ~
4 L% D' \$ ]! d# pstruct SNode{* ^2 R! a, C& ^# b- `/ Q
float data; /*存放操作数或者计算结果*/; |7 {$ h1 R$ q Y& f6 L/ e- g
char ch; /*存放运算符*/
3 `; O, ?; q- Y0 r};9 X5 |! H. j( B3 R) U o: r
- f7 ^6 f' D. e; Q- ]struct Stack{( A# e7 ^# [# i3 O5 h
SNode *top;# O6 }" B8 S5 ~" j: M
SNode *base;
2 F3 h% O3 L( I- s0 z int size;
% e& s* j$ p* O};
e. ]5 x, \: m) N! e# P
' q7 u' `+ H. V6 y; s$ C' L/*栈操作函数*/
" _: s) d- ~: ]; n! I! v8 x; \5 l0 _+ kint InitStack(Stack &S); /*创建栈*/
8 \: x$ O1 k3 j2 b" Oint DestroyStack(Stack &S); /*销毁栈*/
1 u" K+ R- x* J; pint ClearStack(Stack &S); /*清空栈*/% V: m( j/ t3 a: F9 g3 c
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
2 S6 }" F/ u& z- n- m$ dint Push(Stack &S,SNode e); /*将结点e压入栈*/
$ n9 i! Z/ i$ ~( _2 @; m9 o% E* ]7 `int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
) u! d1 j2 Z" M4 h& ^8 F
; \- U7 i# H' W5 g" a/*表达式计算器相关函数*/
! S' j5 Y% o; B" N8 k: S' uchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
, a, s0 x# u& e$ mint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
( \- b3 c" E; |! U* |5 K; @0 Afloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/* ~! H; Z( o) ~+ d$ m6 ~3 d
float compute(); /*表达式结算器主函数*/
. |( p3 }4 {' N2 J1 Rchar *killzero(float result); /*去掉结果后面的0*/
* N0 v5 g$ K7 s: M7 ?/ c
1 I6 R* b2 y! m- Y: [! X. Sint InitStack(Stack &S)0 n8 {, @5 M W% N2 v h
{/ a' o7 Y+ w |" n
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
5 A6 z7 m: Z2 [3 W if(S.base==NULL)% K+ G4 q- T* ~+ W
{
/ Q% o& E( ?% K! j1 v printf("动态分配内存失败!");
6 g* L8 J# I) W/ u: J return -1;& d; ^9 j4 }7 A' }' m, B
}
T/ u; Q! p: X3 F. ?% j* j7 @% P5 ~ S.top=S.base;4 W' P( y0 H( r% b# e6 |
S.size=STACK_SIZE;: X. w7 a, o- y) P, o6 Y
return 0;- L; Z/ w' W. G% z$ _- \- j" n4 x
}
) e m) O" U4 c3 W A3 `. |; p v& P# {) s% `; l+ y
int DestroyStack(Stack &S)
5 p" s" A( w7 c7 T1 h0 R/ u w* G{
( t* ^; G0 F' ]7 L' F' h5 D free(S.base);" t' E( j$ b9 k' P4 e* \2 Z3 ?& `. H
return 0;1 B9 Z0 W0 {' z1 D1 w4 H( N
}& q7 B$ G) k$ w; K
2 }+ C! V7 A; zint ClearStack(Stack &S)
* _- p& \6 E; n$ r$ [{
; d% ?9 d2 Y, c B, K+ Q, m( E S.top=S.base;+ d3 Q! O+ v( j2 n" u6 L
return 0;8 z! p+ j; @/ d0 X2 E( Y
}
7 z g$ ]/ ?) M/ O6 @
- R( ~% q$ O0 J' _: k) V) D6 ^int GetTop(Stack S,SNode &e)
" o- ~" \0 t: Q% ~1 Q6 c! Z{- b, J+ T6 J/ _) V |* n
if(S.top==S.base)1 M1 T1 x! B; _5 X
{
- q: ^, _/ f2 ~9 c1 m printf("栈以为空!");
' q6 Y% z2 V7 G3 k% z; o) \ return -1;2 F) ]2 z% v* ?5 |1 V
}
3 H. \4 [& n- _4 X. x9 |6 n! j e=*(S.top-1);
) @9 B* e2 r! G7 r. K return 0;
s {/ G* m8 @}
, E8 ~) W1 t' `+ `+ m: E0 O* N
, f8 Y1 B! o* a! `7 s) x I. x: ?3 oint Push(Stack &S,SNode e)% X2 D! }6 o+ [% R R5 k4 ]4 g
{
0 ^9 R8 l% h" u" i& S u if(S.top-S.base>=S.size)$ P; g1 G/ ]' k. [, d. C5 \& r U
{
+ o( v1 u. m4 T& q: B- D9 Z: S S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
, o9 H% {6 o Y if(S.base==NULL), b0 x& }8 |, w9 `( S% R
{
: k( W/ a+ @' `5 i/ |/ N5 v/ r( d printf("动态分配内存失败!");
2 I" a( n4 P$ h5 d. u return -1;. E$ V: w6 p/ C( J7 x* s }3 x
}1 K5 b b3 Q* z5 J- \# k0 ^
S.top=S.base+S.size;
4 `/ v4 s. @+ ]7 j6 V5 }2 D S.size+=APPEND_SIZE;
$ Q8 J8 p/ M4 a+ f& H2 A0 M }9 x: I4 C: W9 P+ w
*S.top=e;
! e) L5 d: y( \) t0 `: q5 h S.top++;
* Z$ x2 R m4 k/ a return 0;
# D! d* C) S# C; }}6 F1 i4 ], I( C: ?( J$ b; @. _
' Z! ~8 k. m) O: \; \6 qint Pop(Stack &S,SNode &e)# p0 C6 t9 _( G/ S w6 H
{
. `3 ?+ ^& f: r" Z. R2 r" B if(S.top==S.base)3 S" @. b* F) P
{
5 V/ D! ]0 I3 ]5 ] P p9 H% W printf("栈为空!");
. g6 Y& I+ P5 O$ J4 f8 D4 \ return -1;
- u3 ^3 U/ `& [% L" v }7 N+ W6 o" k6 s5 H
e=*(S.top-1);
5 N* X5 i/ G$ V+ h# u5 | S.top--;/ d1 ~& q' N! ?6 j. ?1 r
return 0;' n4 [7 b- J% R; T( W" o. U! @" x
}
3 Y" m- x1 g. v# x
3 _* P0 `+ i! }* y4 o5 Lchar get_precede(char s,char c)8 _- e8 V, J0 B b
{2 Y) o! v; ~8 S$ }3 i! ]9 A5 ]1 N. a
switch(s)
# U0 K5 C& f. m+ w! ^$ }$ o {. m6 ^$ Y) ?# ]0 ]0 e g
case '+':
9 {' L4 r+ A' W case '-': w4 E, ~9 W$ p) S
if(c=='+'||c=='-')
( {0 _; a7 o+ w9 t; ]! j) L/ w return '>';$ r- P! C+ _3 p$ |$ l; x; @8 v
else if(c=='*'||c=='/')% Z7 q0 Y7 U: A: p
return '<';4 A* H) k3 i7 R6 e, B
else if(c=='(')4 b( U% `' `5 H3 W; }$ p
return '<';0 u. y4 M, u( e3 a" n6 Y
else if(c==')')! N3 i- I7 {0 A9 {9 [* K$ N
return '>';
1 _5 K( @1 Y! b7 e else , S8 o7 z D, I6 |" R
return '>';, d! m1 y: `- U7 R
case '*':
- _ }' R" F: } case '/':$ P4 p+ d( ^% ~; |4 o f8 s
if(c=='+'||c=='-')
5 L3 A6 i: |# b1 L t return '>';% `. b) t R q' _( }. i: e
else if(c=='*'||c=='/')( J: ~% e9 j' W& n/ n/ L
return '>';3 Q7 R4 \. \: h' r2 V
else if(c=='('). V- L# f1 l0 e' K' y
return '<';
0 L& A$ A7 L4 o( c/ A else if(c==')')
+ Z6 m2 }! L9 q M8 _1 u; e3 t, A return '>';! P3 |. y, z+ l% l
else" H+ u1 K8 K" `, w# k2 R+ ]: J
return '>';
# ~0 y9 T" i t/ e% g" I& _( y case '(':
' W# P- l) t2 H6 v( l if(c=='+'||c=='-')& M& h5 `- f5 F7 e+ b
return '<';* N, ^! d3 Z( a, B7 P5 D, S1 s
else if(c=='*'||c=='/')
3 E0 k. v: {( C return '<';5 [% y) i R' d" d( t( A
else if(c=='(')% D6 j8 [$ z. w! M7 ~9 V
return '<';9 j( t$ w: J E, h8 P
else if(c==')') Z4 h! y- T) n
return '=';
/ f6 M X. n" K# j else. K7 N3 A/ F& {2 h( V1 d
return 'E';
" l2 F+ V o W. U J1 Q3 W case ')':7 c. s: f% {" D) R$ r+ L
if(c=='+'||c=='-')9 q4 J9 h$ E. X; z" v0 Q1 e4 d
return '>';0 W a' l) B4 W/ ~; `
else if(c=='*'||c=='/')
6 K6 U! ^8 ^/ Y* X0 ?: d+ D3 F return '>';6 n+ R m' {# h k- ^0 |
else if(c=='(')+ i/ i+ v! M; L& U' c
return 'E';* K& |( M4 K' o- m' n. `
else if(c==')')5 g8 d* g Z& J3 M" W, W. j
return '>';
5 I3 r- j4 O6 A( W9 O else
. M0 b: V0 O! I0 Z return '>';
; ]9 t$ U; n' Y/ l2 g9 F case '#':
2 W2 N, h7 T) z5 } if(c=='+'||c=='-')2 |" v( q# k! t* r* ]
return '<';
! R/ _( X% g: a) `- N8 M5 H4 A else if(c=='*'||c=='/')" r" a0 _. z6 K6 M# x T' {
return '<';
3 \ l9 V. u: o9 z; @- ~ else if(c=='(')% e/ g ~5 W7 n2 d# \3 e( H
return '<';
H" W4 m: B' S. ~ else if(c==')')
$ I5 k# a8 ^! j& s return 'E';+ D, k7 h1 n3 P& M
else- c; S( I. ^# V" D) p7 c
return '=';8 d! s/ N: g) S6 T Y, {+ J t& E; m8 J
default:
, {. m. E0 O2 x- R: Y# v/ f6 B5 l break;
5 h }3 U; H. V! e# |2 v/ x) a }* \5 F' y- Q2 ?/ ?" U* d
return 0; 8 r3 Y: L3 I* L. ]' I
}$ u1 ]' V7 x. p% d* s- [
. B* V% H3 K; r1 p3 b# \9 mint isOpr(char c)
) ^& I9 ?6 Q; N{
X( w1 ?; Q. p& V; h# h: U if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')" c% A4 ?# f C1 |/ n! t' u
return 0;
9 A6 X, G: w' N3 B else 2 j3 f0 Q( d+ }9 }, O; z
return 1;: J' y- l8 p; {" K5 i! `& e6 s5 C
}
# Q/ } ~. v0 [7 X( V8 T) ]% _& {8 D8 ]& q- Z$ x ~* s4 q1 E
float operate(float x, char opr, float y)9 l7 w6 `4 ]" Q: l$ N* g. w: M4 i
{
6 j5 ]' [% h8 e* } float result;
# B( Z' M0 ]! |2 q" k. `" \, U& _ switch (opr)
9 y# ]9 f+ ]& O" o1 _' N ? {+ E1 D4 l! a0 H- i, s8 I" X9 L
case '+':
1 V: ^4 T$ U1 ? result = x + y;
4 D; V4 X& C8 H# | break;9 {, V, z. F. _# \
case '-': 7 H: |7 D& w0 V
result = x - y;4 w# S! w1 z, v1 g/ q" ~, `* a- n
break;
0 v+ @0 v/ \* v4 r case '*':
, j1 C( h1 N# J result = x * y;3 f9 U: u8 _5 K$ P5 w( ^1 a
break;, p% z8 k6 t; o/ s/ M& `
case '/':
& R3 F- q5 k) v2 s, D" t if (y == 0)
: a( O3 H' S4 M2 @4 b4 a {+ L" J& l' O& R" X. y
printf("Divided by zero!\n");8 l7 ]( |; i. Z n X3 @
return 0;. |% h9 ]" n% Y+ W/ e2 x# v
}+ }4 [! ]) l$ y& H0 y) V
else
y- \$ ?1 Z; n& I L7 m {
% b# ^' E* Z- Q0 m/ r result = x / y;7 c( D( X! C) ^
break;
) ~8 ?8 U4 }/ M- y }
- G, z$ t- Y: G; D2 C0 \ default: # m g/ A D% C2 V' G# F
printf("Bad Input.\n");
# I5 M6 K; M4 u return 0;: l: m8 D% z1 o; p
}
- o$ @0 c& M3 N return result;
! u! O3 P2 E' d, @} 6 K' G. F3 j L; f/ J& {6 U
8 \8 k- V6 l- j. e5 O% {! ]float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
. K2 I3 \; o% b{
! c# j* u% Q7 {, q6 f6 Z Stack optr,opnd;
" G: [- _6 l3 x! v- ]( S; ] struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
% n1 r9 L5 e# n, u3 j3 Z4 [ char c;5 Z$ Z, J; _' k7 L1 s
char buf[16];
( y. T+ l& q7 v int i=0;* ^) U1 l% ]8 W+ g! K
8 V* n1 q' D1 o0 D1 ~. j8 ? InitStack(optr); /*用于寄存运算符*/) w2 @# z4 [% D
InitStack(opnd); /*用于寄存操作数和计算结果*/1 W) z" Q- [' J$ f& }+ z8 W) E
memset(buf,0,sizeof(buf));# w( p7 _% g# |7 T
' Z0 i0 a% u' d# E
printf("Enter your expression:");) [) V2 [- d8 h
. @; y O2 f1 J8 B% V: n& A opr_in.ch='#';# a7 }* n. l5 q* T$ j+ L
Push(optr,opr_in); /*'#'入栈*/# I- h/ x4 {- \; y7 t5 P& q
GetTop(optr,opr_top);' k& o+ _ f/ x
c=getchar();
. _2 q0 X& [+ U- e# P while(c!='='||opr_top.ch!='#')
$ ?/ c; H0 \" P, C7 `% P$ F8 B- l {) [% F8 {' @9 ^- w$ h6 U
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/' P# P& l& K5 ~( l+ y
{
1 ^1 d, S4 G# w buf=c;
9 M' K# |/ D8 K2 [9 X i++;; A+ [ Q: y* e2 }+ y5 s/ C4 O
c=getchar();0 r+ z& F7 J, e: a
}
9 \, T( s1 o+ ^& \ else /*是运算符*/
( m" x' }) W' K {+ P; ?( a ~% Q
buf='\0';
6 [9 o( {3 q9 A; H$ L/ x' } if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
6 I1 ?% T) `# S {
4 T7 v, K1 x( J" N opn_in.data=(float)atof(buf);8 h( g5 j( Y' h7 t$ _
Push(opnd,opn_in);" q8 d) M" X4 b4 ?) }: Y
printf("opnd入栈:[%f]\n",opn_in.data);
5 V' y# e- w& H' x i=0;
! s+ ]- s/ K; M; E5 G memset(buf,0,sizeof(buf));
' q& U, s3 u1 n! _9 ~/ c. j, H }' B( l$ E3 O% g3 D: _* |6 @1 B
opr_in.ch=c;# {0 t, j! R( q
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/; P' Y, x! w# Y
{; `3 c, O' b) Q9 h5 ?- [
case '<': /*优先级小于栈顶结点,则运算符入栈*/
$ W9 a: b3 f+ l1 q0 | Push(optr,opr_in);
" M1 w$ A M! N R _# k* e7 V printf("optr入栈:[%c]\n",opr_in.ch); p4 i' |, h9 c& g
c=getchar();
& z) O0 S- d7 @ break;
" P4 U" G) j+ F2 | case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
; O0 K' J- [3 R7 y" k Pop(optr,e);1 Q4 u! ?& J, |( ^: u
printf("optr出栈:去掉括号\n");6 ^- N$ M# f* x5 a& b) w
c=getchar();2 E8 ^& A# C/ Z6 { B6 |- g
break;
0 C/ L* _5 x2 S+ t% a; g case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
5 O+ m3 {8 ?: f* t Pop(optr,opr_t);5 B, I) n8 O) e2 X( r W
printf("optr出栈:[%c]\n",opr_t.ch);
4 W' [3 o6 u# r% j: u: o if(Pop(opnd,b)<0)
% f# M5 e$ E2 X' k4 G% K3 R+ _ {( T; ^, P* f: g5 Q# J
printf("Bad Input!\n");( ]( }7 J3 S1 \# u
fflush(stdin);
3 X4 E* a# \( p4 U! P6 y return -1;
! V+ V, J$ F# I/ i }, Z4 {! {! A5 t7 |# k
printf("opnd出栈:[%f]\n",b.data);
4 p' @; e. U9 w; @; l% J0 C, s- A if(Pop(opnd,a)<0)
; g6 j5 a+ b/ E {
) @6 l* z: j9 l$ s printf("Bad Input!\n"); h/ g) k& M# m O4 d( f* m, W0 ?
fflush(stdin);+ h: z" U$ e t. E3 h
return -1;
7 d6 D3 @) E5 c4 t }
, B3 p- B' Q( k7 D, i. k printf("opnd出栈:[%f]\n",a.data);
: j* C2 S. d8 q* n opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
. o0 V+ I. t& K, h8 A Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/- _3 S K3 E' t+ k
printf("结果入栈:[%f]\n",opn_tmp.data);
1 v9 u, s2 D z break;! Q/ L) c) a; y+ `3 t' f& {$ ?$ r$ S
}
8 r. ?1 v9 @7 G6 F }; N- u( e5 b6 a$ x
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ . h! z2 k( Q2 l$ P2 p1 t: \1 X' Y
}+ r) ?3 ? Z, R# {3 Q! B! F
GetTop(opnd,opn_tmp);
6 ?' j) B+ V/ L3 c. \9 C DestroyStack(optr);
8 u ^4 l) p/ o DestroyStack(opnd);
9 y- w) G3 j5 a. X' S+ ?( F! K return opn_tmp.data;/ y, H9 Y& Z/ c6 M, p9 ~
}/ T; T7 [! d; o0 o: u1 Q9 u, a' S
7 s- v6 N9 c4 `$ Q& y- F) F, ?
char *killzero(char *res,float result). @/ P" U: d# c0 J* I
{0 b. l0 l" e9 R" b/ J) n- r
int i;0 q+ A7 L8 N, @6 {( P9 P- r2 _
2 x1 X: p$ L* p- G, n
sprintf(res,"%f",result);
' F# s% T) U+ J( r" C i=(int)strlen(res)-1;
1 w) a+ M0 f, ?0 O1 {- m) o while(i&&res=='0')+ P2 t# S$ f- C$ ^0 R
{5 ?0 J0 y9 }. `" X' X
res='\0';
: L3 d0 `! z0 t5 m! k i--;
/ g+ \3 o8 F E2 x9 u a }
+ [1 r3 E$ n% S7 H0 D$ ?0 W if(res=='.'): x* K3 B9 c3 ]7 P. }. m) u* f
res='\0';
' d% \7 E6 K9 v" k8 A return res;, u' ^% @# K1 i" u
}$ P2 X% b6 n1 x% \' u* A
9 x2 u# [6 v: o' \
int main()7 s6 K6 _9 @! N) I. l
{) \( c; O2 q+ Y$ \
char ch;- v4 R; ^: C* l$ @9 a* I
char res[64];. g( P7 O/ w# x! @. w
float result;3 p3 d1 j' ]7 N1 N9 F
while(1)% O0 s( O3 B# y/ I" B7 D+ Z+ a
{
* c" O" q; ?( l2 ?! S9 u result=compute();# \; y' W) S) w B9 [8 l
printf("\nThe result is:%s\n",killzero(res,result));! U+ P6 Q) R# T2 g
printf("Do you want to continue(y/n)?:") ;
. O0 I$ w: a5 s" _0 M ch=getch();
5 X" O" n {2 g6 K putchar(ch);
( t b1 H. E/ e- V1 w if(ch=='n'||ch=='N')
( ]4 k% A. F- b6 D) i7 r g break;3 Q- D4 j' r3 h* }# i/ m
else
6 @( h7 |, w8 U9 f# y8 O, @ system("cls");( A* U, g6 ?# r0 H# R# o, u$ j
}
! w, @& Q: m4 d$ \# l return 0;3 {- l. S% r/ @2 q- C* l
}: E1 }; Z" b4 v J5 D
4 p" }# b7 ~ i! N3 R% q7 Z[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|