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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.8 o4 ? ?/ @$ F6 |# i& d, D
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=* k; T" \& y( d. p! c1 ~/ R9 B
/**************表达式计算器************/
) M' O( G5 |- ^) Y( o. M#include <stdio.h>+ s. f( j B! U$ T, D
#include <stdlib.h>
: |% R6 F! x0 B% e8 F5 V/ R#include <string.h>
& R4 o7 g3 A+ W% a; N1 i#include <conio.h>
$ Y% `4 @( A7 e! y" U: I#include <malloc.h>
; d3 {% r3 C# c, c0 F7 B/ ]/ o3 U h& B" U
#define STACK_SIZE 100
: Y( _: m7 T$ i% E8 b+ \: t+ q3 E; v8 j#define APPEND_SIZE 10; f* m6 a7 f. }, v( m! O
& ? U) `9 N7 J5 C" B1 f
struct SNode{
9 }+ H- |# R# o+ O3 V float data; /*存放操作数或者计算结果*/, I- c) H" ]% j, {" {
char ch; /*存放运算符*/
: X5 ?, F ?$ w8 D};. D/ S6 M/ N' J
* D/ Q* H- K, N4 {. W% tstruct Stack{0 S2 \) ^( S+ I. j
SNode *top;, [/ o! F* v6 a( \# B8 l' }. a: |2 o
SNode *base;
* i( w3 G: h4 o! x2 x# b3 b/ X( e int size;
( r* ~0 A( `/ r% M D! l g* l};
. q. _2 _* `0 i, W. M/ a1 m
z( i. C2 X0 B2 F5 I. Q/*栈操作函数*/0 x/ r, ]1 S$ f" v- O# W/ i7 \8 Y
int InitStack(Stack &S); /*创建栈*/
: Z8 {; y! _# y; ~5 K' a h/ Wint DestroyStack(Stack &S); /*销毁栈*/
& y7 y: ~" ?2 O7 Dint ClearStack(Stack &S); /*清空栈*/
9 x( l. b |; P! Kint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
3 M( G# Q, u0 M- K4 C1 S5 B& M2 oint Push(Stack &S,SNode e); /*将结点e压入栈*/1 Z, y: f0 U! {7 i3 t5 X
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/0 |7 i4 I+ j4 k, D% C
@, G9 y6 ^7 L+ J# M# b9 W* l
/*表达式计算器相关函数*/3 ^6 L* O" F6 S$ q7 W) t3 i
char get_precede(char s,char c); /*判断运算符s和c的优先级*/8 l3 g+ c$ {1 c
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/* l& A/ t8 G' w c" f6 L3 J- q
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
; b2 e% T/ G3 u7 W6 r, Bfloat compute(); /*表达式结算器主函数*/1 |+ }9 \7 ~5 z+ C6 e
char *killzero(float result); /*去掉结果后面的0*/
9 _3 B5 i4 V* L" z, w+ w, {* o; ^& a* G( M
int InitStack(Stack &S)( r1 r9 j; b/ }) V7 ^: N! \% k5 {" ~
{
2 t* C, B" O) c6 B9 _. ~+ w, B S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
J" u [$ d# Z8 c7 @ if(S.base==NULL)3 H6 j/ ^* E+ q; I. e8 P6 c) S
{
& m0 e a6 W( S& R) a9 H/ { printf("动态分配内存失败!");
* G* {$ e( u1 @0 J, } return -1;) f$ I" U6 N$ v2 z1 C; F
}* q( w3 T! P/ w1 }5 y
S.top=S.base;
; o( o3 y7 J9 b0 R9 [* s S.size=STACK_SIZE;
+ y$ g1 v; ?/ H+ V3 v: v& H return 0;
* N& ?6 L @0 W4 e}% {; B' y9 p3 s% f# q* i. t
. c, P( h* m7 V+ t- tint DestroyStack(Stack &S)
) K7 _/ H7 W( E/ L: }; v6 h{
: [! L4 I6 @) i" O free(S.base);* [# }8 Q* }5 H8 U
return 0;
5 W( }" g/ q% J# a$ m, a}9 Q6 V& e0 ], x3 w1 |9 M% u& g
; W7 @9 x* c# e9 @8 C1 p$ u
int ClearStack(Stack &S)( ], ^6 F( ?0 C' w7 I
{
3 u1 P$ w+ ?: L! \6 I" B( ? S.top=S.base;# j2 H5 x. p' b9 Z, k$ Y9 w
return 0;
" E% S% }# {* s2 ~$ Y; H}/ p; `( C( y1 v; ?* A( A
' l# y+ p, `, a) j& yint GetTop(Stack S,SNode &e)5 }4 _! k6 g# t0 E, L
{
1 t1 y) b) z2 a$ }* w if(S.top==S.base)" [7 b2 w9 e+ W$ H1 A
{- m! D6 I4 b8 o: w* o, g: V
printf("栈以为空!");. Y6 z% S4 j1 o5 J/ Z
return -1;% i$ q7 |( v8 ^- R& c
}5 N9 e! y1 f; s
e=*(S.top-1);
* ~5 S# t1 a1 C. [( o return 0;+ e) N8 v( y! p) M9 S- y3 z
}4 T. p3 z9 d! h! z2 c' Y
$ J+ ^" r7 L+ D. Z/ ]# G! }7 Tint Push(Stack &S,SNode e)
; u/ ~2 f4 _3 @{
) D" f+ T. Q, Q) e6 z, I( h# R if(S.top-S.base>=S.size)+ ]% u3 I3 u/ {, r8 ?5 c
{( ~7 ]+ V" \& j( q2 U( b2 a& y8 B8 U
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));( o4 a' o! t2 U) ]7 {
if(S.base==NULL)/ V' o5 v5 k3 l- \9 W) b! c
{
& o% z, n- X5 y! r printf("动态分配内存失败!");$ \% u$ n) i- d7 B* l4 a
return -1;
4 D7 Q* F/ z& t; i4 Y }, U% E% S' X4 G, c" {% c1 \0 J
S.top=S.base+S.size;" b- E5 i8 |7 x) M4 h3 q
S.size+=APPEND_SIZE;
/ A8 }, E" H: h* Q" z }4 @6 D3 I+ M0 ~
*S.top=e;5 i6 U% E, o0 m8 n0 d( U
S.top++;3 D- \% {% P( c
return 0;
" E1 Q7 z6 L6 j' _}
4 M s! Q% t+ _. e6 S& O) ]( j) \$ d N5 p
int Pop(Stack &S,SNode &e)
7 h' u1 E; N( ~3 M; q! n{7 F( w0 J7 @) r6 d, E+ G2 o
if(S.top==S.base)
7 V9 m: z/ W; m( f& ~ { i# H' o0 _+ E5 X7 R2 L4 o" e1 I K
printf("栈为空!");2 j6 y0 k: B& p9 r9 ?2 q
return -1;
) q& D3 n& [/ B3 X9 I; e, q/ o }# a. d0 b4 F; i" k6 U
e=*(S.top-1);8 O( a! c, T) a# R' i2 j$ g8 R
S.top--;) l1 ]6 `/ `. a! t/ h
return 0;
: S* P- s! S3 \% d5 E}
/ B6 O O7 w1 m& \! r. n9 A- u/ w/ L( }. h
char get_precede(char s,char c)' V2 p$ S% x, H ^0 b A" s+ @- }
{) k/ v. o$ K+ f0 F/ C
switch(s)
t: q8 B. M% y( _5 g2 v {: N6 X/ ~4 `6 J* ?$ G! J0 V8 e
case '+':
, P6 @9 |7 t: A case '-':
$ V; Z7 N5 n- A# S6 O if(c=='+'||c=='-')- s0 n! W ?' L' j
return '>';
8 h q& e- [9 {* {$ k else if(c=='*'||c=='/')
3 P& c: u7 `. s; T4 B return '<';' q+ C5 @$ b, ~7 c" Q
else if(c=='(')
* s. B( I/ n, Y( N return '<';
0 U# h* k2 p& p& a else if(c==')')
( {: J+ W8 W! K5 B/ u6 e9 u7 H; B: Y- W return '>';
; k- k+ {/ H Q e- X else , R5 T: Z3 `0 O5 N
return '>';
- v" x; c( K: K+ N/ ~ case '*':7 O" a3 j" V2 v
case '/':2 o6 R q) J; L
if(c=='+'||c=='-')
5 D- n7 ~& |, F$ U return '>';
! x7 h6 E( c$ Y2 C3 T% } else if(c=='*'||c=='/')5 s: r! e* `' t
return '>';- ?' e$ d7 P) b2 a4 O
else if(c=='(')
. L) G: C: |. B" S# D' L3 R- h return '<';2 Z2 w9 P: k' E! o( u
else if(c==')')
9 M7 m3 d/ V' Z7 v/ b1 z* c return '>';
% B7 e/ {8 M$ @; d! y) m* S+ g& [& O else
0 A. e/ C/ p% O+ ? return '>';1 Z4 ~0 e9 x4 F$ f7 L* S/ N1 t
case '(':1 N! W H. F7 A& _8 N3 M2 O
if(c=='+'||c=='-')% s4 e+ o+ c/ }
return '<';* L* { o! t$ d1 }9 F) }) M# J
else if(c=='*'||c=='/')
, b: }* k4 h; I2 j return '<';
6 A( K9 u% P+ J; }" J! j ~+ n% T, u else if(c=='(')
0 E& }+ L- _+ Y$ I5 W9 v% J/ b) m/ H return '<';
& ^( a+ B5 n! w0 }" R- }5 v( x else if(c==')')- ~1 s# H6 a- D0 R7 O% y7 B
return '=';
' [( d2 d4 V8 j3 x else
8 N2 }- |7 O( [' ^ M! l return 'E';5 v2 \$ F( S# z. r
case ')':
" n. m$ U0 n8 W8 k1 Z# s8 s; r Z if(c=='+'||c=='-')
2 Y% W# z1 v* W' {9 M$ X) j return '>';. f9 a) y. q. \6 S9 b0 Y1 d
else if(c=='*'||c=='/')
2 e; r( {3 w* X, G) s2 ] return '>';+ P* b9 T, B) \" m$ m
else if(c=='(')* B1 k* N! o4 o! `5 C$ J4 P
return 'E';& X1 R1 x4 S6 J! h1 u* |* G
else if(c==')')
" y6 e% q1 Z, Q) N/ C$ D return '>';- i/ S. J5 p- t9 \% B7 C& K
else" d5 R; I; F- j/ m' `5 |; ?
return '>';
* O" Q$ F k2 I4 W! ] case '#':, t; t6 t2 }% ~2 T0 t* f" v
if(c=='+'||c=='-')' \" z( N( @- z( u' n
return '<';& T U# d# L$ c7 r. c' c" \2 Z
else if(c=='*'||c=='/')6 @/ N( S/ n; t4 U* R) |, J1 f) \
return '<';
9 \2 q8 j7 m* o1 ` else if(c=='(')9 h+ s8 `1 ?# I4 Q/ S( M) ]
return '<';9 i1 \9 `- A2 K9 Y
else if(c==')')
/ Y. V1 W* u4 m1 E$ s return 'E';
% s0 X# ~) ~) ^) h! s. ]' X else- v7 t( Q; l6 l6 K* j. h. |
return '=';
- q! v" | u" e0 a* c* a. m default:
( R; l3 ]- P" U; t1 V8 E break;# D$ E |2 V$ U" G
}- J1 M' W% }2 J: f: l2 ~$ N# X
return 0; 7 u1 [7 v( ]; c) X5 @
}
1 i3 g+ C- R4 }% T3 L9 R) z7 W) h- c' F9 W: {9 O2 d( d
int isOpr(char c)
* o3 ?- ` C- E; j{) _7 f6 C; M5 J4 k2 _# l" |
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
( l+ d) y# f @' C) A7 B return 0;9 X3 [, ]; Y4 U# G" i: ^
else
+ V5 t! A4 {% J% | return 1;
( T; f2 s4 Q- c- _4 Z}, |# Y$ U1 D* ]2 p6 i `
; [3 w/ {1 b) R/ Vfloat operate(float x, char opr, float y); E% S. @# v) _% F# M
{7 g. f0 R6 W9 J; ~
float result;
8 o; b% z v8 M0 F1 R' B n' ] switch (opr)
* z; v: ]" k5 w& a" S {6 r, B3 ^2 r; }5 K9 ?, |, B
case '+': & |* N4 T' v6 m- ]- ~
result = x + y;7 `2 q6 F$ k; ?, V6 y
break;
1 j1 m4 P9 \- p# Z5 { case '-':
4 j; g$ o8 ^0 M# Y result = x - y;: c( [, _7 b+ _& R6 c2 S9 m
break;
( K0 z3 F3 Q. X) a, i$ T* I; o& t case '*':
; F- U t$ r1 j; @ }$ } result = x * y;( O) N2 ]8 J9 ]/ F3 ]
break;7 {8 B2 y7 X' ]4 G. S
case '/':
) Z( u* x0 Z, ?* B H if (y == 0)4 P+ s. V* r, n) D" g9 m7 ^, y
{4 z0 y" s& B& x# M# B+ {$ w& U
printf("Divided by zero!\n");; \7 S( q/ V5 U# U4 |& d+ z$ B. g9 ]
return 0;# S( x3 v4 d6 ^* }5 z: r7 u
}
+ y) ~7 Z+ b" `; q; r) y/ {8 f, D else* ~; o/ g. {4 V# ^- }/ Q% P
{
# X8 g3 ~9 h; z& o! B" n; |6 t result = x / y;# K& S. g0 x; d
break;
2 X/ b) b& y) \* J. ~' @ ~ }5 w5 I7 {8 X$ E( ]* C x" a
default:
7 F) G( _) d) O( o7 `- A$ F6 m* g printf("Bad Input.\n");
# k3 u. y* b& Q9 e$ Y' S+ f return 0;
5 e8 @! W' _# A }- \ ~6 `3 T4 a- Y& J
return result;
# f) y1 M; r* _; V- V4 m} " r: D. U' a# |4 u- `
% }; i: w H3 a+ g: C$ pfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
% p: q* t, [! l$ t# r* D, ~, @{
- J* g# i8 b; T* W& D Stack optr,opnd;
4 _0 o( ^! G& c struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
, u6 I6 V' D1 A3 [7 {! s char c;
, Q+ R# @& s" a. v c7 g char buf[16];
0 D) ?! f9 Z: k. q& Q4 Z int i=0;
; P# i, q/ W7 c- [) N2 b, ]1 d: D U
1 l9 v# X4 R* ]5 u- Z- C InitStack(optr); /*用于寄存运算符*/
0 R& c$ n. _# I3 X InitStack(opnd); /*用于寄存操作数和计算结果*/
Q: p9 M$ z" t! Z! ]2 v' A memset(buf,0,sizeof(buf));
- b+ z8 s: G; e! E0 V4 C3 s
# d9 r7 Z( S* Y# R& S1 E printf("Enter your expression:");: O( d# p& c# j0 U
- j) ~! K7 l8 p7 F: M opr_in.ch='#';
. M1 I1 @9 q9 R: q Push(optr,opr_in); /*'#'入栈*/. w/ w i* O$ K2 N$ p
GetTop(optr,opr_top);, |4 Z3 I1 R- o* q, h& i7 _4 a7 Z
c=getchar();6 r; x& ?+ L5 `" _
while(c!='='||opr_top.ch!='#')3 a, P8 D* z" w' f
{: ~5 t; I/ h1 {3 Q; t0 n% X% F
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/5 ~7 b$ n9 X/ c0 m& Q! d
{4 ?8 u- M9 v5 ]2 M2 V$ s/ T% U2 X
buf=c;5 r: K7 G0 y% R
i++;
& q7 M9 G. N4 ?# @5 \% d c=getchar();
2 p/ l- f2 k; g/ V0 H, G( D }
% }" \7 {# U. m* P else /*是运算符*/1 F7 S# O4 Z; k' q7 @* J% d
{3 H6 }' s! ?" ?, A3 E- g* t; `
buf='\0';' V1 i. |' y7 n' F0 k4 T
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/0 F; y0 ^' ~5 d
{
9 S5 O4 X2 q% h' V' k T opn_in.data=(float)atof(buf);" p3 [2 |2 I" N
Push(opnd,opn_in);
+ I0 w% I1 q/ Z& l" B% F3 `9 | printf("opnd入栈:[%f]\n",opn_in.data);1 X# d+ G' D4 x2 V
i=0;# c# W! j E! |# C T+ n. V
memset(buf,0,sizeof(buf));% F# T+ G0 Y* z9 R1 M* ~! W* P
}
4 m$ |! \2 U: t, V7 O! t opr_in.ch=c;
1 C* g9 n6 E5 m7 U/ m& X switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
4 V5 ^& w" Q' J2 K {, E: X$ c$ q4 U; ?# p$ e' G1 |
case '<': /*优先级小于栈顶结点,则运算符入栈*/
) {' j: }1 o. N0 u. ~2 u Push(optr,opr_in);- ?" G* u+ {" r3 M
printf("optr入栈:[%c]\n",opr_in.ch);, f. ]4 m8 O: n% B: _6 i
c=getchar();
& v% P# K% ^. W4 o break;/ F+ J4 b2 O$ y" l C
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
, P- t4 t6 q/ J7 g0 m Pop(optr,e);
# B& p! Y. g( f$ U% w printf("optr出栈:去掉括号\n");, o- {* b! t8 `4 O) Q, r# }
c=getchar();
) o9 }! G7 t# n* G+ a" ?. D+ C, D break;. g; }. _/ ]/ Y. I5 Z# h( w' z
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/' D7 z$ V; F( w# C' P0 e
Pop(optr,opr_t);
9 H+ f' h( O. P$ y printf("optr出栈:[%c]\n",opr_t.ch);
/ S$ t8 f) d: i- f% ~) O3 x+ }6 e. ~ if(Pop(opnd,b)<0)
1 y# ~- l. j, C! d+ S {& r% m9 o o X3 e* h
printf("Bad Input!\n");
2 B, V$ J( x. Y fflush(stdin);9 f$ y: B# ~& _
return -1;
/ K! @8 n2 j$ K6 z7 D8 }4 `" y }
+ L& L1 I3 ^9 ]) i6 J printf("opnd出栈:[%f]\n",b.data);
: _% G9 X- f/ E5 ^1 E if(Pop(opnd,a)<0)
% ]6 t9 R. q) S$ Q4 k0 J {
- W7 p. ~, _, m2 v9 r8 l7 l; H printf("Bad Input!\n");
" p* E( G" C9 D) S7 d* E' | fflush(stdin);
0 W Q; m, i# T3 W) _ return -1;
5 C; C3 L" s. _. m$ Z$ y- c# T }
" P$ U" x& r5 ~# h& ^( [ printf("opnd出栈:[%f]\n",a.data);
) g, V* C" J" E4 Q opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
0 h. D8 w9 E I! d2 {; d Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
) k A- t ]# i" `5 z/ @( O6 `$ G printf("结果入栈:[%f]\n",opn_tmp.data);$ @7 N {- m- a& `. w& M) D, x. E3 s
break;' P& d2 o# G+ ^% q. c& y
}6 J9 \( f6 y2 Y. e, Y w
}
3 n- U* o; ^6 ]6 F: F+ ?! s, C GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ ; Y C9 Q; R, n5 E# Y9 I+ ]- y& \
}7 p7 _- b9 t& j, x: P4 @
GetTop(opnd,opn_tmp);
$ S: r# v8 [* D$ [ DestroyStack(optr);
* _# r* ], R3 |0 v3 Q DestroyStack(opnd);
4 ]: k$ y1 A. g" p; a; s return opn_tmp.data;, U7 L9 Z8 P1 o$ G) I! V
}$ G: I! p6 G! O; B/ ^7 |# I9 ]6 M
$ p# e' T3 e1 W% e! lchar *killzero(char *res,float result)
4 G. s3 [; g' v+ c0 g5 l9 e{0 l. T; C4 Z+ V7 j7 H
int i;
6 c* M8 ?, R1 _' g% u6 j5 `$ s) l, V5 Q8 r
sprintf(res,"%f",result);
# j0 h: M% T. Z @ i=(int)strlen(res)-1;) a( l8 k+ D9 _8 K& j
while(i&&res=='0') X& u% q$ F; K
{
3 \- Z4 W2 q: J res='\0';
! P x( F v5 S# A) c, ~5 n$ b* K i--;6 |! W: m8 i1 Q0 u7 P- w/ T
}( F: Z$ ~. M6 x4 z1 F! P$ T3 G
if(res=='.')
' |# O! }& _# P# y res='\0';
) w u, l6 S" Y6 O% f0 O; R return res;
9 M6 ?5 C# W1 G4 D! E0 X# j}
/ j3 s/ k; Q# X# g
. h+ x+ o8 J/ S5 I# Uint main()) N0 }2 v. F, h1 P, b% J9 X
{' y/ \: T+ V% H9 U! w1 N" a
char ch;' {* k, r0 x' Q. l/ A: I
char res[64];* F( j+ v3 ?* p& G1 i
float result; I1 e- \+ r" \9 A/ X1 y: N( n1 E
while(1)0 C- z, i0 l( d. }& G& n
{
- f+ p+ J# ?$ X8 n0 s; u result=compute();
& Y B' e0 C' j: e printf("\nThe result is:%s\n",killzero(res,result));
3 Y' `! Y w1 X3 K$ k0 d printf("Do you want to continue(y/n)?:") ;
4 K0 w4 p e3 }2 i+ I; t5 q ch=getch();6 F7 e- @$ ^# n/ h* K
putchar(ch);+ C3 B5 ^6 C4 K" L0 \: W' ]
if(ch=='n'||ch=='N')6 e. j2 y$ ?+ p y& }8 a, c. u
break;3 [0 Z: B- x" `( C5 ^3 {0 C
else
* Y+ E* u/ \. Y& s system("cls");' E! f3 v1 o J/ d6 G
}
% a% w; E k/ M0 L5 e) S7 Y return 0;! g! ?9 q$ L" p7 s2 R* W h
}4 ]* J# D$ ~ v9 o- ]( D
: g/ B% n) ~* \. ~' d[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|