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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
1 r7 @; e9 ^* U% P% m2 O+ {3 V程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=" i9 V* n0 |$ x0 |2 P P, V- ~* C
/**************表达式计算器************/6 {7 _# ^- [) _# v( ~
#include <stdio.h>
7 Y. J% Y. C' X/ H" F6 m#include <stdlib.h>! _: e2 J f; h: O T
#include <string.h>$ \1 Z7 I2 [% J5 ~$ K1 G
#include <conio.h>
- |6 V% }$ ]8 ?; S0 G$ e; @0 x- ]#include <malloc.h>; ~% g# O0 D+ O$ @% J% O
$ \- u" D- U8 ]#define STACK_SIZE 100
5 q# M2 Z5 [, R# P) `, C# U, Z8 k#define APPEND_SIZE 10
& ]5 `9 L, g' o9 X# [9 e2 b
# ~( I5 K, x% o( Astruct SNode{' i& L% w% _ U4 P) v
float data; /*存放操作数或者计算结果*/+ @; @2 S: x T x. C$ k
char ch; /*存放运算符*/
( {' G. \% c% z% S3 e8 ^1 t};( u+ B! J7 X9 s C, k% J5 p9 G* `8 A. Z
7 n% @2 O; h# A6 j" |2 r4 a3 L" qstruct Stack{
4 l4 ^, N4 q3 J5 i SNode *top;
1 n# I/ q1 o6 c, b$ n SNode *base;
9 |0 Y. l' K- S4 f5 A3 V: l int size;
; ]% |4 |5 U+ n% q};
3 f; n/ \! `+ W3 O# D/ F/ L/ I& P2 N
/*栈操作函数*/
' @7 N+ q% g6 F0 ^0 g2 F. h: Rint InitStack(Stack &S); /*创建栈*/
& I5 p4 B# o0 @" j! B! |int DestroyStack(Stack &S); /*销毁栈*/; g/ u( c& D( I' N4 O2 Y
int ClearStack(Stack &S); /*清空栈*/
" }/ ~( y) y- C( I. o6 q9 |/ B, wint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
8 }4 h0 F7 r5 j) P: ^( Eint Push(Stack &S,SNode e); /*将结点e压入栈*/( s6 e& @' Q( Y# H
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/3 `. S! @# G7 c
( F! Z$ {' S+ d1 a2 b" y! E0 p/*表达式计算器相关函数*/
9 c" a& o+ ]( }+ echar get_precede(char s,char c); /*判断运算符s和c的优先级*/
6 I4 _$ P" m5 \1 o- aint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/6 e3 ?' M9 @2 J. S* A+ W- V! L
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/- ?8 M5 z3 I, l/ f
float compute(); /*表达式结算器主函数*/5 Q! l4 {, {8 A, |" e: b
char *killzero(float result); /*去掉结果后面的0*/ Q$ C) n; d' B5 Z/ f9 {# E
& c2 G O4 J7 h" a) x1 F2 jint InitStack(Stack &S)
, \% R+ I8 E3 B* ^( j3 [{
3 ?# M7 ?! V; t6 `9 a- C- _, d7 r S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
' w4 k, a3 b% J# q3 Q/ Q5 X if(S.base==NULL)4 w2 M+ z! k4 W% n0 @- H
{6 N% \- Q# r# F; P
printf("动态分配内存失败!");
/ @/ f: {% @+ [' l" I$ B return -1;( V: h/ F. r$ u( m
}
) l1 S+ P9 F. B* h$ c S.top=S.base;
- r2 a8 B' D8 c1 [ S.size=STACK_SIZE;
9 E5 L4 X) M1 m- e return 0;
1 Z+ t% ?$ I1 I4 J5 }}
8 Q* x0 v. X& k) f- N% L- q1 T$ M
int DestroyStack(Stack &S)
5 i! `2 u( @+ S7 b{& P2 u' e0 Q( I8 |0 O% R$ \1 s9 { |
free(S.base);5 F8 g5 Q/ C! c& L
return 0;
0 f# O, m) [2 L}
3 d" ~; }5 _. t/ H3 T) e ^1 o
" u( {7 ]/ `5 z& }int ClearStack(Stack &S)+ \! s' Q# X" M7 o
{
& Z S4 e6 x2 h4 c2 x; p S.top=S.base;
# m! Z% A) a& ~ ]) ]9 \ return 0;
; b8 a9 }+ d+ o: o1 R}
9 z; ^4 d _ [$ \$ v v0 x
: e+ \, r, U7 \. K4 mint GetTop(Stack S,SNode &e)
1 W; a7 g) m- J7 z{
2 o% t+ w) O8 u; U) A8 f6 _ if(S.top==S.base)
r0 }' g5 W- d b) G. M {1 ~6 p1 }' x9 f% d
printf("栈以为空!");* k7 N& u4 k- p& }5 G
return -1;
( \. p- w& ?$ v2 n4 X4 F }! R H7 k8 s' P4 c! U
e=*(S.top-1);# t2 C7 M% S- w Y6 V! @' |) L
return 0;& H4 L: X1 V# T
}9 ~! S$ b. W8 @; ^ ~6 S. c
9 J- I7 i ~5 d5 ^: K: pint Push(Stack &S,SNode e)
- F: E+ n* b: c" [{
* l) H4 U; U8 M if(S.top-S.base>=S.size)
/ B% }- U( N9 t1 j% C+ Q) O {& U7 d$ @6 X! S: U \- T# X/ g
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
' ~" P. Z) [) V' o+ Y# l if(S.base==NULL)4 V! h" y/ I" \" c
{4 z2 V# s9 j4 Q, q4 L$ e( ]
printf("动态分配内存失败!");
3 N; @. [; c& [! W return -1;
5 v6 |6 E; R) d$ B; ~) o8 [) A5 t }$ x; B" [9 P) Q3 e+ @( \
S.top=S.base+S.size;; }3 V9 ?3 i6 I9 L3 o
S.size+=APPEND_SIZE; @- o. j+ T% h1 D
}
' U5 d+ |6 k0 g$ c4 N9 J; V *S.top=e;$ }9 O5 V# b' R g2 s$ y2 G( S/ a
S.top++;
. o4 a4 D, Q" d. z return 0;
8 k8 f# I: B) C} ~/ h3 F8 v3 }5 t7 |& ?
, }: G( E- C( Vint Pop(Stack &S,SNode &e)
0 G; P+ k2 Q+ `) X3 H, ?; \% p5 ^{
2 f s# Z4 c5 ?" q' N- g l/ w if(S.top==S.base)/ n6 g- k, x5 l2 G6 h- u
{
) t7 `+ u: O, o% [1 m printf("栈为空!");7 P u! V+ Z2 Z% Z4 i( C8 w( `
return -1;
7 `: j5 M# u' i) K" N% s, I. c }
$ R( t) P; _/ J: F7 A6 }0 p e=*(S.top-1);
# H, X- m* b, |9 t: S$ x S.top--;
0 s4 H/ P! S6 {. n V: t. \* p8 g1 D return 0;8 Q. o& k) A0 ?+ ^- l
}
3 O( B5 X6 A) M% A& G# q: H8 m
6 f3 ~9 N: d6 ]) W4 `: }char get_precede(char s,char c)
6 k, I( z' i+ O0 E0 W: M' u{6 b+ o- i/ |( }# K5 F/ e
switch(s)/ ?) \; l+ z5 _
{: y" b- W: c% y- a) K) L3 l
case '+':
0 X( a1 D; O/ `$ d1 N case '-':% X" G) }- v1 N2 J o# H& W" S, |
if(c=='+'||c=='-')$ l, I% a9 [4 u7 A8 }1 `4 ?
return '>';/ i9 u, s! J& V% x
else if(c=='*'||c=='/')" W8 H/ ~+ u4 e0 w, Q
return '<';
; c- P' U- f% R( G else if(c=='(')
3 i8 L$ U( Y! t* Q% l return '<';
" K; H3 e2 {9 `, k: L else if(c==')')4 E- u' ^( p' r6 D7 c
return '>';: n* x& t: X3 f; C2 ~& `2 ]' X0 {& R
else
9 x( [5 Z7 O: f# |1 D1 a I( R8 d7 N1 \ return '>';. Z/ |+ V G3 f$ P
case '*':9 O9 Z3 U$ B: ^% @/ Z1 m
case '/':
7 R6 Q/ z/ \) g& r8 D8 i if(c=='+'||c=='-')) ?0 W3 S: N: J+ b3 E; T, J' d' A* B# ]
return '>';! I( r) ~6 J7 O' A" A
else if(c=='*'||c=='/')5 l, ^% I2 W, [3 t
return '>';
" ?& F8 y+ d+ l- _$ P4 ~0 e else if(c=='(')
# O0 Q( o% N5 A) ?4 T return '<';
+ a$ p& n6 X. t$ ` else if(c==')')
! \, S: L2 Z5 Q, i/ G return '>';9 _7 F0 F( U1 d, I% H ?
else: ?) @, K8 Y! g' M- j: Q. C
return '>';
9 A# N+ L1 f/ f4 g case '(':
& }' \5 l6 [& v# n2 m: O1 V3 U if(c=='+'||c=='-')0 H! \& Q- r8 p& n3 S1 a/ @
return '<';# j& R1 ] z3 O( O
else if(c=='*'||c=='/'), A z4 h8 k) y+ c- X. t0 M* E
return '<';8 S u: b0 s2 Q3 d( Z0 _# d! v" z
else if(c=='(')
: A% V. @- r" y return '<';+ b" J, b, E% w$ S; I
else if(c==')')
6 P/ r @. y9 H3 P return '=';4 G9 m' \: L: \+ t" }7 |
else
, {7 d4 E1 @* }3 W% X. l9 i return 'E';8 [* H( U6 y/ X
case ')':1 z0 z2 H$ Z8 U; t7 y* i4 N. g! K
if(c=='+'||c=='-')
U3 \, R* k" M* i) T6 n return '>';
4 N: M- B/ U- [4 b else if(c=='*'||c=='/')' m+ w$ y. N# j7 E( J5 ]6 b. ~' K
return '>';6 d% U* o: f: ?, {
else if(c=='(')
0 E! K/ G' J- d! o, q2 g return 'E';
. m3 j5 V. n. T2 R# N* R& @8 A else if(c==')')
1 L8 [0 g w9 `5 `. f- l return '>';2 r1 p/ o0 X, n' u8 @
else- I5 s8 R3 K# d i; P: J3 X
return '>';
- S. a, }6 ?* Y; X0 h& `6 y- c case '#':# \- s; o# ^5 [' S. v& l6 p" _
if(c=='+'||c=='-')# L% \. ]: n; n0 _! Q$ O
return '<';
9 N) k/ K+ K7 q$ \ U b* t6 |5 R else if(c=='*'||c=='/')0 m6 @, c- P6 o( U5 B
return '<';7 r: _8 E* a+ W
else if(c=='('). \5 f" F7 U1 Y
return '<';
! l2 f2 `, i# |3 V else if(c==')')
6 |1 A! Z+ Q) k- o" f* Z return 'E';
* }) k5 Z$ U- l! \8 V else
9 |! b( g2 } k1 P return '=';
3 f/ ]- n- o1 o& ~3 B5 C2 c default:
* }+ l' b; a' D" V" n0 h6 {; n6 V break;: E% l" d, W3 n/ O! \
}
; O. i3 d; a ?" L; N return 0;
; V. U( F% {/ a$ s# {/ Z6 W}- c* ~0 [- |& l$ H- O E. q
6 o, O/ b. x! t0 d) j9 v4 Y# Vint isOpr(char c) \" k5 s9 @! P/ g
{
$ Z1 F1 M/ l4 V$ m1 c U8 w if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
; |" F: x( u4 o7 ^! C6 [) q+ e return 0;2 f& } E. B/ K2 O+ Z
else E9 }0 W7 ^- k; w% N/ F
return 1;
' `4 x+ J, r" [" m; {}& B2 c, o! z1 l" ^
# x" N* h0 |" u6 Y( j5 Hfloat operate(float x, char opr, float y)
1 {8 J |, z+ {6 D{0 H; X6 m9 m$ _0 d3 a
float result;$ g- |& k! r' x$ Q+ t7 @9 U
switch (opr)5 U1 e" ], h$ j
{
. O" w9 J5 V% t8 q% [ case '+': $ L: F* j4 T- N( p3 {
result = x + y;
6 F* A- B9 r e0 \6 u break;
8 L. l* T; V9 |# T3 v* a3 v case '-':
4 j9 X5 J1 y! V5 ]. h/ F; u result = x - y;
6 \0 H+ n3 H) x7 c break;
, E. M9 a+ F- {* _+ z8 o case '*':
! ~, M* }2 O* H* E! l' i result = x * y;
2 }5 `" V! Q( f3 g1 K5 y% a break;
3 I: J7 U$ q: o, A case '/': ' d5 J5 i. o& _! C8 g0 {/ j d, B
if (y == 0)
8 y0 m: e) F" Y: t' r/ X9 @' t {
1 G: {6 t. t7 J' }& i' I printf("Divided by zero!\n");& }+ E6 W- a4 P4 K' O
return 0;
8 g5 p5 i$ o }7 f4 } }
3 z/ E7 A0 \/ J* z! m8 m else
; ?" b6 U3 j' W0 D7 t( l F {; @# R0 a) P7 \" V a' _% Q
result = x / y;
# o8 g4 P, ]5 p+ O0 @$ E break;1 h& X6 U0 `7 v: ^5 b& u
}
; E5 v1 g' F; s3 V9 c default: h; e6 }- q' N9 C
printf("Bad Input.\n");
0 m8 g. i" a* U2 k$ a return 0;
3 X$ x3 ~5 t& `& N }
* i6 V. }0 s3 t8 o& W return result;& i8 o( Y4 U( F% X* ^3 }; P( U# d
} : c* U. m" x3 X- O
( n' D# U3 ?: ], Z: f1 Z2 vfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
3 E8 T% G4 ?- `% X{6 M1 S r% o) y0 ?- e" X$ K5 X2 x
Stack optr,opnd;& G) u/ m+ r( z; Z" j0 j1 R
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;8 u2 Y( B# O: [8 Z' `
char c;
h2 T" u/ z+ r4 ?+ e char buf[16];
# ?3 S _; u8 c3 G" d int i=0;/ S6 t2 a: T& I' T
- U, L% V$ E& F" d InitStack(optr); /*用于寄存运算符*/
( T5 h& W W/ ~, C9 t1 ] InitStack(opnd); /*用于寄存操作数和计算结果*/
) u& g1 k) ^. \* g% Y9 g; s memset(buf,0,sizeof(buf));
Q4 O" n* e* M6 q/ M7 c 0 |: d1 f) z, U
printf("Enter your expression:");
/ {; w$ H: ~/ Y$ E" N
- j6 s9 K3 p" ], _0 C opr_in.ch='#';% s9 [- Y1 T! d" @( `0 M% E* R* s
Push(optr,opr_in); /*'#'入栈*/
" L0 O9 B/ I) K GetTop(optr,opr_top);
& d" \7 R! S g5 B8 g c=getchar();# s! w" N3 c+ @# N+ a
while(c!='='||opr_top.ch!='#')
0 a7 r3 `1 c$ }) E {3 q# B6 L( W* H# n
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/# e7 c4 L7 u6 M3 q' s
{5 r. `& F6 T0 ^: i0 D7 h# [' U
buf=c;
6 j) i/ Q: b- T7 r i++;
' q9 F! b, {1 R5 e& M c=getchar();9 C' ^8 Y$ q. }8 t$ U2 j
}
4 K, y/ n' h/ U else /*是运算符*/* X# ?, z6 K. X2 |9 E4 n. R
{* r# ?$ o' f; g- U$ N* Y
buf='\0';5 D2 W8 k1 G- p0 [9 l( j1 x
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/) r0 J ` Y7 O! A% D& ]( t
{
0 i$ S0 r& V+ ~4 F! a opn_in.data=(float)atof(buf);
( c" ~4 S6 C' X; V" M Push(opnd,opn_in);7 V) J( o+ s. }, q0 O
printf("opnd入栈:[%f]\n",opn_in.data);2 ^: c: e4 w5 n( R. C+ `
i=0;
1 S! X( W2 x; k* j* c memset(buf,0,sizeof(buf));
" L9 W* w" K# E0 u; z& i6 u }
! P5 N, X; j0 Z: O+ u2 i2 f opr_in.ch=c;
( ~: ^9 `1 X1 E, C* w switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/: ~. x; h/ ]- ?
{
) A1 i* ^6 \4 } x2 ^2 L5 I a case '<': /*优先级小于栈顶结点,则运算符入栈*/
; ~; j$ N( i4 M7 e& s5 [ Push(optr,opr_in);
* n! D- m2 }8 R. \% ]7 e! h printf("optr入栈:[%c]\n",opr_in.ch);
/ [: a; a, f% v c=getchar();! x- r# m: w( l' P v; ^) n
break;
% I: `0 j" P z7 `+ M# B% x" ?; b case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
) O9 K+ o2 g; j( G& u5 l Pop(optr,e);* J1 F: ^' O& n! a& j$ B1 ]
printf("optr出栈:去掉括号\n");
" X) y9 t/ ^9 P c=getchar();
9 r6 z e0 m; U9 V5 k0 T break;
5 T8 B0 W2 Z* A$ ]) u case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
- U% y2 q5 _) v p Pop(optr,opr_t);% d' u- U' A d8 c* ?2 K
printf("optr出栈:[%c]\n",opr_t.ch);
7 ^9 \2 J( |2 P if(Pop(opnd,b)<0)$ `2 n& X! U( J) N1 L7 r9 a
{( e+ h9 A& b3 e) C0 b
printf("Bad Input!\n");
3 l/ V+ M8 v* C& {9 z% } fflush(stdin);) b' P7 s! @ T
return -1;
7 |6 a S5 ]: n0 f& p }2 q- b' F9 S4 O7 P
printf("opnd出栈:[%f]\n",b.data);
& ?, a: x. @7 ~7 D2 |# U. A8 s if(Pop(opnd,a)<0)9 F: ?' t( ]0 g$ g
{4 y* i. T \1 w7 S
printf("Bad Input!\n");
" Y9 o: b/ \, j# C3 D) K fflush(stdin);. ]( b6 q% l6 K& `
return -1;
6 P3 M- h0 S6 |9 J2 H1 A- i }9 i6 S4 D4 @. a1 U$ ]5 T- L% x
printf("opnd出栈:[%f]\n",a.data);7 F; l/ ?" V+ [3 h
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
) h+ }+ b4 E/ l Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
2 o6 m; T6 d' {' L0 ~/ k, t printf("结果入栈:[%f]\n",opn_tmp.data);0 x+ R2 Y% k; @% ~, q7 }0 u
break;
7 v& |& h+ N: I/ U- C& t }* P" _# L' \' u$ V
}# B6 K! V- g$ L ^- J" j3 N
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ / Y. d% h# j8 L+ }# q
}
( r8 a+ Q( y9 c9 T$ e GetTop(opnd,opn_tmp);" l. `$ F" C# ?, A
DestroyStack(optr);
) ^9 g& w& q4 w c" X$ L DestroyStack(opnd);
2 ^+ U7 U, ]% f return opn_tmp.data;& m4 L* t9 Q8 M G3 J1 o9 `
}
! I8 u! s: g+ J( h& Y1 S# R+ x: z# x% [% ~
char *killzero(char *res,float result)
8 c* M. F6 W5 G. L) m& g* A) @4 T{: J* M. T; [0 w: T" T* K. ]" O" P
int i;' |' e9 ^2 c+ ^" x- Q, `, ]: v9 z
) E+ m# \& y9 t& o$ S1 v" B sprintf(res,"%f",result);# [* u* b \/ p/ M0 |- e X2 P
i=(int)strlen(res)-1; J# G4 E) O0 V9 f1 Y5 S2 ~
while(i&&res=='0')2 W. r$ D. C) V' }8 t, \' d2 t
{
. q* j) R4 t/ k; f: N res='\0';
U K, Q) a3 H: Y3 n! v0 M i--;, ]9 M4 g' W5 H0 @4 M0 }
}
! {# T0 {4 H4 m( t1 ?; w6 c if(res=='.')( m6 g8 p7 U5 ^( R f8 s' B
res='\0';2 g' I @2 n, u3 G2 a3 S; h
return res;
2 _1 O3 w4 j2 s}* M& Q/ r% z# l8 _( b
5 C) s' r. x! V/ N% ?( `8 `$ K
int main()) F) r) o/ P0 x+ t% R+ W
{! l) u# E3 ^2 m
char ch;: R4 N1 ]6 j+ O. ?1 r$ [
char res[64];6 R$ r& W0 d# t5 t H+ K% b
float result;
; K! S- l9 P( Q while(1)
" k! K( o" T, x: _ {6 H2 P5 U% o8 Z8 K5 H3 j9 ?
result=compute();
( G: P9 D# l# F5 @: Z Y printf("\nThe result is:%s\n",killzero(res,result));1 i3 M" x& m) ?! D
printf("Do you want to continue(y/n)?:") ; g+ F3 g: ^* x, F; r
ch=getch();
) l0 @) n/ J: w: G. B" P- ` putchar(ch);
& l! Q0 b- P1 a9 c+ ?$ F if(ch=='n'||ch=='N')
! [; M+ _% H2 X0 G) O break;: d" ^# q) h% l) k Y
else
' U. Y/ {: i6 V6 ~/ U system("cls");
* l! G9 p" }3 A, O# A- L3 a }
% @$ q7 U. E! A3 P return 0;
1 E5 C3 k$ N4 L: I6 h}
) x$ M! n, [" a I( k# V% D7 k# s: w5 l R6 f: }+ ^
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|