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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.2 Y2 w! a$ T5 b7 g+ @2 H8 ~! n
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=) E5 @8 x6 Q) b4 U( J( m& }
/**************表达式计算器************/
# s. M9 |% ^. {) k" s#include <stdio.h>" W/ D2 R' r0 ?% `6 K8 n
#include <stdlib.h>
1 }, D0 c- s& k& I#include <string.h>3 @# L. B1 N5 H- s! C! n; r
#include <conio.h>
8 y. m% |/ e% K$ N3 \#include <malloc.h>
c7 |$ S1 w# {# B: l/ p
6 W0 i! W; }4 W#define STACK_SIZE 100* g$ Y: s8 k) C' `
#define APPEND_SIZE 10
% X& J- T; B, j; j1 w
3 w$ O( k* W4 L% gstruct SNode{% |8 n E8 i, Y# E b6 [% z
float data; /*存放操作数或者计算结果*/6 _: I5 n" V2 O% d8 u& x1 @
char ch; /*存放运算符*/! p; `9 U% a* E6 P
};
" e: t8 N7 b: t' X4 R
9 a7 N7 ^' I! L) i" jstruct Stack{
# w, f( }' E8 y8 h SNode *top;
! b+ |' p, `# N SNode *base;- w: P( B* C! d5 C
int size;4 O1 U0 m2 e _$ ~6 H
};/ S& m; q; W2 ~ K# l# B
6 \# U o4 B1 V* T' `
/*栈操作函数*/
& R8 g9 w6 j" ~int InitStack(Stack &S); /*创建栈*/- d; V8 _( a6 B) }1 [3 L( Q
int DestroyStack(Stack &S); /*销毁栈*/1 W' U. x6 B. ~. p4 I6 V* j" l, I
int ClearStack(Stack &S); /*清空栈*/
2 c5 G4 `; C- p: r6 \" ~int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/' T+ }5 b9 T& ~+ n$ f- d
int Push(Stack &S,SNode e); /*将结点e压入栈*/- h9 Q3 L; E; C, D9 f! K
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/8 A' V+ U6 ^8 N7 v1 h
# v" s6 G6 J+ o7 A/ S/*表达式计算器相关函数*/
& U& y: D$ \( W, k% Dchar get_precede(char s,char c); /*判断运算符s和c的优先级*/% ?; b: ?* y" P
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/- q" F* t! ]+ H- G p. v' x
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/7 X& }! ~0 h! A" z
float compute(); /*表达式结算器主函数*/
; k/ U! g, x6 v" P* ^) Wchar *killzero(float result); /*去掉结果后面的0*/
/ \: @7 ^( X2 ?
/ }4 D' E/ i8 Pint InitStack(Stack &S)3 U. `2 k* N8 v; @
{3 @! l9 t1 @0 i. O3 A! d. h, o
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
, |$ P5 a; T) A0 ~7 E9 [ if(S.base==NULL)& Y h" h% v' }. J, K# Q
{
2 p4 D3 A: r5 x printf("动态分配内存失败!");* r( Z0 G0 t' F ~* m2 {5 u0 m
return -1;
* x! G. H' o( i }
5 ~/ b" ]1 K5 T: u) O( t8 J$ C; d S.top=S.base;
3 ?# S* t0 S, r: I8 v S.size=STACK_SIZE;+ ?) l6 |! S% X$ m# C
return 0;: E. R2 `9 ] t3 G, _9 q' R$ J7 c! i
}
0 c' f4 T9 R% s6 j6 z% a
2 c2 m' N+ f7 d, tint DestroyStack(Stack &S)5 D/ [) y9 h, ^5 c( p: `$ U# {
{
+ k& y/ _% _% \ free(S.base);
! N" ]& N F/ i return 0;
2 a. _, Y0 |( d# P+ D6 I}
8 g& u4 U5 X, U6 M1 W% ]
- x( `2 p7 ~6 S( _& I# u: Gint ClearStack(Stack &S)
% c. l' ^4 h: M{
: t( j! ^3 A" f S.top=S.base;, c7 @! y/ e) d* Y0 l$ u8 U% W/ g
return 0;, A" y: w/ u' e/ o0 R
}
2 @; h0 ~3 `# O; l3 k1 j4 A; \! _+ O8 |! R4 t
int GetTop(Stack S,SNode &e)
* e" F+ ~: x2 f% K{
3 U9 v! ]/ n8 s' z" Q9 K( E if(S.top==S.base)) C. x' n3 a$ S" n- |
{
8 R* ^: a- j- v% ` printf("栈以为空!");1 J) B- d& P8 f/ H# [
return -1;
( s) _7 G( g9 v& }( } }& R% y: ]- H* ^
e=*(S.top-1);
0 L% b0 _' A5 w( G return 0;7 t u0 ~6 h. L$ X3 _$ {
}
' y1 ]7 G, ^. O6 j2 k3 T" V" w' d! O( `& Z) L" c
int Push(Stack &S,SNode e)
" X9 q/ b: }- n4 u; J{$ ]% Q" t7 [' h1 W# J" o! _, U
if(S.top-S.base>=S.size)$ ]9 {" k1 V8 i7 p7 A; _$ t
{+ A9 L2 Y4 O. O
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
7 W. f, a( z1 j& v if(S.base==NULL)
& y5 a8 ]5 Z" g, F! ] \& N {
; }/ L6 t- t2 c3 o6 q) V( y0 e- B. J printf("动态分配内存失败!");3 V% w' U4 f8 ~+ q
return -1;# N( J0 s8 Z/ T- h
}
4 X' u. h0 f, Z* o6 X S.top=S.base+S.size;/ }' h N. v" N F4 j
S.size+=APPEND_SIZE;
/ b3 z' b/ z- S& z1 K, @! s5 }( D& o }
. r; ^1 `2 q0 k+ ]4 z" U2 u *S.top=e;. o0 R. T/ J' p+ B& p; h
S.top++;
5 A1 J( t7 o9 G" M2 \8 P( A/ ?0 W5 { return 0;8 T/ h5 v3 D4 {
}+ A& T1 I5 ~6 E) V- |
, i5 ?6 g0 g; p3 U! O* `& t
int Pop(Stack &S,SNode &e)
/ [! J1 ^' H+ C6 N& Z8 a{; l, r; g$ e, Y# ^* g
if(S.top==S.base) L2 n1 @/ ?. {7 ?; V
{+ D9 w& z* `0 K* x1 ^7 R& ^* s
printf("栈为空!");) s6 t7 w/ ?( H& y0 j; V6 b* u4 F
return -1; e% q3 B0 A& U8 o- d
}
' v4 x6 d1 @% `3 @2 I e=*(S.top-1);
% S2 G- B/ h8 a. U; J S.top--;
( i7 @; }3 d$ q5 } return 0;
p) W! Q. _ C& h}
& [$ S0 F# d# ^' w. f8 p" ^! X/ s1 k9 [4 S: ?% r, w$ @5 |, u9 A" x
char get_precede(char s,char c)
# k( _6 z; i! X. n$ l# ~3 r{1 o' `% J8 U4 M& i# M
switch(s)6 d# ^" w! `: D# A8 H" q" }
{6 P( V9 T+ i# F( H9 [
case '+':
! q5 ^! j' ?7 i) N E& B case '-':9 [( i/ X7 `# A+ ]0 c% Y
if(c=='+'||c=='-')
2 z: V, I% G8 C- F' h; W/ | return '>';
* F/ t5 F6 M. Y+ \: G- _. F O/ d else if(c=='*'||c=='/')
1 f( g% G2 J$ P) u- R return '<';
4 C, z! }; `% A else if(c=='(')3 k4 a! c* w& ]
return '<';
& J" z+ G( A* p) `" c2 a9 } else if(c==')')' W: V5 A$ L! a, q: }/ _0 k) F
return '>';. t6 p% B1 \( H
else
7 z4 S1 r* Q& ?: O1 A+ T+ Q return '>';
1 m! \5 t& P8 @/ A. p& a( {/ f case '*':
* r2 B% h& e- a# Z& e% @ case '/':$ z7 f% W: c+ }; A
if(c=='+'||c=='-')+ w* Z" r( D# Y7 e" S
return '>';
2 Z" j9 E9 s% Z, ]9 ]& r, v/ o else if(c=='*'||c=='/'); n1 ~, B! r0 M! G
return '>';
0 D) s) g E% c* U1 ]- Q else if(c=='(')
4 q v9 f5 l, J; Y3 |+ w return '<';
* i6 s6 j3 b3 f* U3 k+ Y+ V4 B else if(c==')')
9 A2 s2 w' g' u8 { return '>';
* W7 x s5 M9 ~* p& A else
# _2 B! S/ T! |4 e6 J& j( ~4 s return '>';
7 w. I B# ~$ ]9 U: a0 | case '(':
* I# a9 e, U9 c( f" M3 D+ K if(c=='+'||c=='-')
- e+ p4 `: ?# V) i return '<';
# _1 N: K- |9 p1 K" z' d else if(c=='*'||c=='/')
. q/ k* P1 l' E6 a: ^6 X return '<';
, X9 }3 e* I. c# ^' R6 ? else if(c=='(')
4 Y+ |0 R3 M, s q$ P return '<';
u- y: f5 `! M i6 G& S else if(c==')')4 g" W4 T; P4 W# L8 ~4 w b r
return '=';
. g; B' `6 k1 d) K. S else
* R r0 O9 M& F3 x) C: O: t3 L8 ~ return 'E';
, _6 z$ i/ g, C- D8 o }: t case ')':
) i% U: `" E0 h2 k( H if(c=='+'||c=='-'): l0 e4 F" h! V, W; x/ P) `* f
return '>';+ \, @& C3 |5 R9 j5 c) Z4 h; ]0 q7 P4 b& H
else if(c=='*'||c=='/')
7 J9 x- p2 x0 |% E2 u return '>';
; }8 j' ~9 m( a, Z7 K9 k& @' Q/ ? else if(c=='('): V4 P: U+ [/ w5 O0 ?/ K) y3 l
return 'E';
' Y* K5 m2 C4 d$ u" Q else if(c==')'): T6 [7 M+ Q# g) Z- u' @# D
return '>';' J5 l$ s. |, u" Z% Q
else* b' e8 j) Y$ H1 V- M z
return '>';1 h1 w) }5 g8 N: I0 w
case '#': k% H) Y1 ~9 r6 g& j
if(c=='+'||c=='-')
3 i. _7 ~% B0 T& w8 F2 m return '<';9 ~ p* ~2 J: I$ C; |- A" J
else if(c=='*'||c=='/')
" l) s3 ~2 i" f- i2 p- r return '<';
O8 F& a% ^) M else if(c=='(')* r. j5 n& s3 B* P+ h
return '<';
0 D) x- v+ ?3 w: Y) }# [ else if(c==')')
. c: D) p: Q0 } return 'E';1 ~. Z4 a( k6 r- M- E
else6 O2 R) G/ B; ?1 F+ n0 Q
return '=';
6 ~5 C+ P- k* f! y- H5 T% o default:
5 L9 t; F( j9 C5 f7 g! [ break;
. Q ]0 b2 l3 [" Z" z0 v/ t( t }
+ r- J* O+ `$ R0 X5 E U' N( A return 0; 0 x9 x3 v3 z$ V! X
}* z+ T. _" {5 W& \/ z C
, |5 K* |( O' t& Z5 Y: S( zint isOpr(char c)1 ?; J+ M! L8 j& m
{
2 t+ V) X7 @" U y9 p0 H0 U if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
3 H( x' j% H7 |, B$ k return 0;) H+ @* B: T% |1 C
else 9 A' r) \+ S4 n1 B, Y/ [- C9 e3 p+ E
return 1;; v. K4 W. R- z2 r
}/ Q8 M; G) u- b6 l
7 E, V+ W6 c9 E" o
float operate(float x, char opr, float y)9 m/ E, z/ Y! I' l& Q2 o% J/ r8 i
{3 I% F+ x. Q: ~# h0 {
float result;$ |0 M) z7 ?) t3 ~
switch (opr)
. H* k& V1 t6 y/ M; Y, I2 i {8 N" d9 ?1 f' c6 P- n* J
case '+': ; `$ A) r) o/ z6 ?) W
result = x + y;) D3 f& w( y) ~1 s }
break;
% z" M. c7 S/ I2 `- c1 f case '-': 7 t, c( u: w" o+ K! P4 X+ p
result = x - y;0 g' p- Q- r& C7 B! x. P) d. g
break;
( H2 e% s3 K) J, D( _; ~/ ? case '*':
& G+ U; a6 u3 W; O result = x * y;
2 K( L' k* |) J break;
4 r% ?( Q1 \1 w* q" a3 a' p* ^ case '/': # G6 C$ C3 d' }0 |8 A# ^
if (y == 0)$ E% w- E5 v; V& Q
{9 S" `0 k3 U% J- z. b
printf("Divided by zero!\n");) w, a0 S q: T ]# D7 t7 [
return 0;
" v% P! n! H. P2 t! p; E4 Q3 ?' _ }7 r6 i. P( O, d2 N) R5 L/ h/ ~7 a
else+ a6 G0 y2 D S
{
, y0 u8 `5 G) u4 N& q1 y( x3 w result = x / y;
) _; }/ S, \% \0 z/ i( R6 s break;' E, w0 Y0 w- O5 k; k& C/ P& p
}
. t0 z5 I' a! I6 g default:
7 \) M( N* v% g7 | printf("Bad Input.\n");
; l7 F* D C( p: M8 L% x1 U return 0;
% E4 V. U. c; q! G }
( U; \3 ?, J( w6 W* N& Y+ G* ` return result;' \$ i. @+ @8 X
}
9 L- a2 b0 c# P" o f8 }% B9 |$ J4 L$ S1 @
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
& \$ }" u- C& r( [3 u, g{+ ]7 ]! K' Z4 O" \+ R! l1 M
Stack optr,opnd;* B* f1 d# W) I
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
0 q0 G9 U U# P char c;& ~9 F2 c+ F8 r, F% T$ ]* t% N
char buf[16];
5 V* a* `2 G X6 T4 _* t" s- c int i=0;
3 T+ T0 F0 A5 V8 Z
3 V t4 n- \, i2 W: { InitStack(optr); /*用于寄存运算符*/
, @1 _. a0 x( p6 F InitStack(opnd); /*用于寄存操作数和计算结果*/; M' _. {) W; p- `/ i
memset(buf,0,sizeof(buf));% L% j5 i! h/ t. B
+ p- S" d; y8 Z$ T* `7 Z3 L2 o
printf("Enter your expression:");
' Q! r) o' k7 X/ w
- }% d" e0 c8 D6 v) M opr_in.ch='#';
" X- N4 p* L. |- s& N# ^/ [8 \ Push(optr,opr_in); /*'#'入栈*/
$ {; ~% s( e% ]4 T GetTop(optr,opr_top);
/ [1 K, b9 O4 U5 b c=getchar();
- v2 r% o' S1 F8 Z* d, t& q5 [0 N while(c!='='||opr_top.ch!='#')# A `0 ]# m2 R# A. z
{2 D; i6 q) q% H( {9 Y
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
# b" u% d: B- r; k! ?, w$ C/ n {9 ^$ \& _8 L) ~& ]- ^; L8 U! j$ e
buf=c;9 l/ O5 d4 C) H- E- d8 C4 z3 Z3 r7 o' ^/ \
i++;
% S# u' }6 q7 N5 [" ` c=getchar();
v, i& q- c( m9 \: a" W% h2 ^1 H }
. ^- F8 X' X# Q* J9 B; Q else /*是运算符*/
: C( ?0 R! @2 T) g$ P5 P {
% K) C, [( _0 {4 ^ u6 x buf='\0';$ Y" h8 z9 O0 @) ]2 J0 N4 F# T
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
_9 K! p- s, l- A {! G. ~# h4 `. S, `
opn_in.data=(float)atof(buf);
$ _; J+ Q: J, T! t3 l+ R8 v* o+ k Push(opnd,opn_in);& r! @. F7 M" C* J
printf("opnd入栈:[%f]\n",opn_in.data); a3 p, I* |( R
i=0;1 b/ h1 C/ g2 [2 E, x" L
memset(buf,0,sizeof(buf));7 j% h4 g) E6 P$ O4 ?% |" v
}3 R+ Z5 m; U6 O9 Z! I6 i/ C0 k0 c
opr_in.ch=c;) h+ T$ \+ e) u# T2 S
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/4 w4 U9 v _* ]- T$ @( d+ n; B
{; ? @! `+ l' P z2 Z# Z) M
case '<': /*优先级小于栈顶结点,则运算符入栈*/3 j! E, v6 v0 z, d2 F
Push(optr,opr_in);
( a2 M( O$ R2 o$ H2 J/ `5 } printf("optr入栈:[%c]\n",opr_in.ch);# j3 i% J f: t8 i2 F
c=getchar();$ C$ L3 c, r3 ?. b- I0 a. a
break;
) r3 x/ m2 A7 o3 Q; N- W case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
0 `. m7 e0 n) b$ t+ h2 g Pop(optr,e);0 D# ? B) P3 z0 j9 V" e1 W3 H
printf("optr出栈:去掉括号\n");
6 o W4 [% \, H# x! _ c=getchar();, ^8 b$ |: F' q
break;0 N m. c4 ^9 `1 R" S- o
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/5 H* h- l8 W4 `$ I6 |1 y
Pop(optr,opr_t);7 P( J0 ]% b5 a3 R4 Q, A; [) B
printf("optr出栈:[%c]\n",opr_t.ch);
, v6 T6 j! S' [ z5 M! H0 F( H& m& `/ K if(Pop(opnd,b)<0)0 |- z8 M+ }, Z! n& p. Q7 i
{
C3 f' G v# M7 v printf("Bad Input!\n");- t/ g+ E, x/ J$ H( ~
fflush(stdin);
+ _/ r+ U$ t5 Y: I1 ]9 a: ^ return -1;$ n% ~0 r3 _) L8 E) y: o! r
}0 r2 a! ~7 I4 z; M% W
printf("opnd出栈:[%f]\n",b.data);
: P4 W6 ? H3 x, B& U" S if(Pop(opnd,a)<0). t& O0 {" U' e9 p
{2 a* l' M0 @3 y, G
printf("Bad Input!\n");
" c6 K I& `* Z* T, y0 @ fflush(stdin);2 Y/ G/ J! w$ Q, D+ e( W
return -1;
1 d. }1 I1 h: }1 p2 ~4 t+ R. h) c) W }
+ b& v9 ?* l0 d* P7 ~6 [$ V printf("opnd出栈:[%f]\n",a.data);
4 b( Q5 l0 q9 `9 T% v1 h opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/, B3 Y! W% a( Y0 a1 l5 F4 N
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
|% [6 H3 R- K+ a( s/ B" | printf("结果入栈:[%f]\n",opn_tmp.data);& e# g7 @8 G& F; x% n
break;
: Z0 B0 s! q! W8 \ ~- W" V/ Z } ]% S. T. T# Q: L- w8 L
}
% \. f$ S; x4 Y/ j GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 4 M% l5 c8 W) r- C' K+ k6 o
}! [' U+ k- ?6 ?" ^% b
GetTop(opnd,opn_tmp);. F, e8 J/ l9 U% S6 O6 |1 z M
DestroyStack(optr);% @3 r8 y5 J/ O: K9 g
DestroyStack(opnd);" t( U- W x+ z2 I" ~
return opn_tmp.data;
; q7 a% ^+ C6 \$ s0 r}
. k/ Z& s% v6 D8 R3 Y& _; }5 [5 r8 z
char *killzero(char *res,float result)
& \& k9 K5 s3 @7 |0 X+ p{
. E& p$ Z3 o$ I/ p* k int i;
/ g7 D" q" I6 H& @1 F3 s A
; ?9 ?; E$ Y* U- z sprintf(res,"%f",result);7 K9 ]' F; h' n6 _
i=(int)strlen(res)-1;
' v) Q/ ~' U) W& f- {* j5 L while(i&&res=='0')
k }1 [$ y. G3 M1 T3 x {9 f5 Y! e. ]) I
res='\0';
' _5 P0 w6 [; \7 j: m# K* P i--;9 {" p( |" ^3 J& S8 A6 X# N- U
}
9 h! }5 c N: o; V) @0 z if(res=='.')
0 v+ }7 `! l$ F2 A8 K res='\0';% A/ {- o, I' j( [$ d
return res;
]" H: J+ Y% y# l1 D" z+ H5 R}
" R6 W& @- Y6 v# j* z* S" B
' t& I: {( i& Rint main()
6 N. o) h& \1 u& P& e{
+ z; H1 H& ~ f char ch;
7 X) K0 U5 c. i u& Q char res[64];
; F, K0 R; P0 e* ?, t float result;
& ~3 n3 A) `7 O) r/ J while(1)
& [- l2 m, E# P6 M @ {
3 \* B P+ k1 t# D9 Q" X4 |) R) \ result=compute();
6 [- {+ c/ x3 O- f- V. L2 T% y/ ?, p printf("\nThe result is:%s\n",killzero(res,result));
& C5 d% G# C7 M printf("Do you want to continue(y/n)?:") ;
: F& [4 g4 ^& V, J/ u ch=getch();+ ?* |) H) [9 _2 Y5 G% W) h0 W
putchar(ch);
; s8 N; J1 i9 [3 ^8 @& B if(ch=='n'||ch=='N')
$ u7 u$ R o& z) [6 m break;
2 {1 P7 y. I$ Q else; D% w; o" R# r# T1 _+ `
system("cls");
/ x l' k2 K0 w7 O, i }! O i) m2 K g9 R3 j
return 0;& {0 b$ K% d9 Y) ?. j4 p
}
, z9 B# s9 D/ M! J. |5 k7 h% ^4 Q* K0 I7 s7 z. O2 v# h* d
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|