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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.+ b, ?9 C3 o) M4 J
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=( ]4 ?% R; [& C* D% v
/**************表达式计算器************/
. b& D# G# n/ F* @& Z. j2 S#include <stdio.h>
9 ` F2 H, X' @1 l G# ~) v$ D% p/ {#include <stdlib.h>* Y: R- o' X# }
#include <string.h>) `! W$ h6 \4 {3 J4 n$ ~$ M
#include <conio.h>; W R0 I8 }: N. O4 r, T# n! z
#include <malloc.h>
& V: W" o. l# ?) g% K% O. X2 e: R' M' \8 ^2 n
#define STACK_SIZE 1002 J/ |9 b1 L& i# |) \( b' R0 I
#define APPEND_SIZE 10
( a: t5 y1 W0 U5 f7 ]9 z6 K3 M$ s
struct SNode{& g# E( u/ }/ x7 b8 K
float data; /*存放操作数或者计算结果*/
# _: M$ i+ n/ f+ Q6 m) _/ O$ U char ch; /*存放运算符*/
/ ^8 A% I ?2 x7 P};; |/ p4 D2 p' b" ^; X& Q4 p
+ }; b. ?9 }2 D* j4 r; a: L
struct Stack{1 G& F; j9 F3 y
SNode *top;& [; w# B- b* a, |3 z6 ~
SNode *base;. j# i) z3 K6 `+ ^
int size;
5 f4 j' q* @8 w* w3 J};$ ^ t J R2 {3 ?
9 s- S" B2 B1 n% F4 I+ J0 ^' r& y
/*栈操作函数*/
1 \* v! a* M" X% P# @- |; t8 L% bint InitStack(Stack &S); /*创建栈*/6 S! m% k; p+ @4 e8 g h) i3 F
int DestroyStack(Stack &S); /*销毁栈*/& c3 H) _7 |7 p; h9 P) q
int ClearStack(Stack &S); /*清空栈*/. F6 [) \+ u" d/ s
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/4 D' x, c, z' Y
int Push(Stack &S,SNode e); /*将结点e压入栈*/
9 i- d) O- Z) @- D, M% E8 y( aint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
6 B% S6 M1 K9 x* }. Y
# T% f( H7 g P+ `/*表达式计算器相关函数*/
u& E, g* ]" b$ _8 Dchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
$ x. P' z$ p7 k4 f. e9 \3 vint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
! O( l" b2 _0 Y9 \- Dfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/. n6 x7 \, j4 k. z' C
float compute(); /*表达式结算器主函数*/# _8 u3 D- x9 R6 `
char *killzero(float result); /*去掉结果后面的0*/
8 Q" U) ?, |+ r" h/ x2 v( N/ ]9 G* B4 M& ? R% C. q* r
int InitStack(Stack &S)7 K9 T: G. b" J" @( f
{: M! V* U. d$ n# k
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));9 }, [+ \( C3 G
if(S.base==NULL), Y; u( c; f9 u% @
{) X2 h% V; p/ f3 s$ q% N
printf("动态分配内存失败!");
- n6 G( `6 D K; A return -1;* ~# ^5 P, l$ m8 O& e V
}
4 a4 u4 ?1 @, j! l3 U0 {7 b5 v6 v3 e S.top=S.base;
) t/ p% u4 g& e. d" a. U S.size=STACK_SIZE;
: c2 G4 @5 I9 s# e0 v0 m5 F return 0;
3 F: D h5 x& e* |3 g% e; n}4 X' {3 |0 o: G$ P
) H% W6 m2 @& H" d) H0 U1 W2 y- Qint DestroyStack(Stack &S)$ ^) l, X! D' G2 B
{
) x" {, t$ Z5 Z/ I; N! w; p free(S.base);
% ~- _5 c( J5 ~. e* e return 0;
" l) H/ g9 M( r, [2 |1 D}) C5 J7 K$ F. z5 w
. v; ^* P& @" n
int ClearStack(Stack &S)
. V n8 B0 H2 X; t6 r- P{
& G( Z* ]! T$ I0 q/ X S.top=S.base;6 G* o" Y& x3 \% C+ r$ h
return 0;
" E0 N; W C, q5 [: k# L- t" t0 |}; o, y9 z3 l4 N0 B: Q' D
" M0 |) @ y" ~, g5 J' [+ bint GetTop(Stack S,SNode &e)
3 K3 k& w _& ^{0 K" B; }5 M/ m) w- n
if(S.top==S.base)
9 a" d; M1 t0 W! T+ |% o {$ R5 i' t( I' B8 [5 j
printf("栈以为空!");
, T0 J1 x5 ^( K6 E9 V _( {- w% r return -1;& @" I3 A% R9 z' M
}
9 K6 T5 F4 }0 i6 |# z e=*(S.top-1);
8 P/ M; ^: V& ~( x return 0;
. K. E! F, y9 M: q}, e1 W; b0 l+ z
' G" z! k6 P0 yint Push(Stack &S,SNode e)# X b, a7 z! E; a
{
4 Z1 F9 P: b" X1 ]8 W( A if(S.top-S.base>=S.size)
+ s" K1 m6 G$ R. m, z( T9 T {0 F+ O m) l6 x7 N* M& b
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
3 r! z) i( j8 ]% S if(S.base==NULL)" e9 ]5 K; `2 P) d U/ f0 z
{
" [# }- h; @9 J% F2 y" h printf("动态分配内存失败!");( W. ~5 y- T7 m! @; g
return -1;
! U* p, V$ Z( O. v2 h- s }
4 r( I& A( `) @ S.top=S.base+S.size;
! n! |9 H5 ~) r, }- k9 ]& c S.size+=APPEND_SIZE;
- Z7 R, i* b$ N9 w3 h6 n }% w7 [$ B6 [4 T( q1 |
*S.top=e;3 w) N' C' v4 m) m1 n+ \) f
S.top++;( p" j/ j8 {. ?) `* G. [
return 0;
1 u) Y) Y8 A0 j3 T8 E}
+ u, p. }2 b2 h. Z8 F" ~# w/ x( M& W/ C/ A6 A; b& S
int Pop(Stack &S,SNode &e)
1 ~2 v/ L. [: D* C- _{, a3 R0 u* j- j2 H7 `. P
if(S.top==S.base)! I% v8 K1 P0 P& A3 K& G+ Y8 d
{; w+ \1 @; k7 G% w! C, F |# J
printf("栈为空!");$ g5 v1 v2 m, L
return -1;* _; B0 L% h6 u8 a# k, s6 I$ q5 {
}
, {! c. J2 t4 | e=*(S.top-1);" K, k; S+ H; Q. x, G
S.top--; D* I0 `3 y8 f3 e
return 0;
9 v4 z3 }$ W) {: R}
! }1 B; D2 Q6 Y. t7 V& m o* s0 q% O, y A# i) ?
char get_precede(char s,char c)4 X$ J# K- ]! g. |
{
% ^& ]$ N# b! W, F' I s% X$ d switch(s)
; d/ J: v& r/ \5 C {
4 A2 @8 f0 q7 O0 H5 ]) H" m5 ^ case '+':
" \4 D9 Z# ~3 i1 \" ^ case '-':5 k, L5 B4 b1 d& q1 Q L- T) @5 t9 g
if(c=='+'||c=='-')
1 ?$ ?) e- v0 k) [ return '>';
" c5 ^4 Z, K2 r& J' C7 { else if(c=='*'||c=='/')
3 ?! I3 ^, e' L" m# m+ S5 \( ? return '<';
4 u, V. {! S0 \2 t n. Q0 ^ else if(c=='(')
$ V9 X; @4 K; c8 e# W' M return '<';" F4 Y# k0 y+ ~9 p
else if(c==')')
' d$ O4 [$ y6 k1 T; x3 \6 E return '>';
+ v' v) R: U2 R4 u# y8 | else
w6 d& o; S" \& \8 M3 l: b* J1 H5 \ return '>';) V# k8 e4 H7 k, j" w# b( n- S2 g
case '*':
- J3 |8 L/ w: Q! x3 X, y* z8 q case '/':
8 W. G G5 b- N: d* p+ Y if(c=='+'||c=='-')8 j7 \! \& K+ w, n7 e& F% O
return '>';
( A/ k3 M3 [: v7 s else if(c=='*'||c=='/') [- D5 L: t9 p5 X' m; G
return '>';2 J( z& y+ }8 k
else if(c=='(')
- m/ o: U P2 u% {3 t9 `# r return '<';
# `& F# `' w; a; [1 q else if(c==')')% i: @% y t4 @( s
return '>';% j/ S; h7 Y+ h& G! o7 ^4 m4 m8 E. a
else4 Z' ^0 R: m" Y# [ k0 f+ z- s* m
return '>';5 Y. p0 ?; O7 c: C$ c% H
case '(':
0 h) o$ m8 m, H) ] if(c=='+'||c=='-') w" X9 z) k% B9 ?" ]1 ~2 I
return '<';
9 O7 O1 ^/ u) [3 @' v; M9 [4 K else if(c=='*'||c=='/')
) N6 x' B7 m" c$ j return '<';; k9 u; g; V: Y& e" E
else if(c=='('). c! P8 T+ r5 `* o3 W4 B
return '<';
& }+ s1 D$ g. z else if(c==')')# |1 X0 T3 z2 a
return '=';
+ R9 z e# p& m( D1 J( Y7 X else3 k, [5 K' v( l* V. c4 O8 ~
return 'E';8 X1 M( X3 x' ~9 [# N; M0 j# |" M
case ')':
( b f/ B0 e4 z- D4 k6 D3 b if(c=='+'||c=='-')2 U# I( f; y8 a0 n) k( h$ Q
return '>';! P+ N( N |0 k g$ a z1 U
else if(c=='*'||c=='/')
' t5 l8 E8 o% s, G0 P! Z. c return '>';; I) Z6 n3 ?% a
else if(c=='(')4 M/ X2 O" W( y) e
return 'E';; F$ o @# C6 e6 l3 [1 O$ q
else if(c==')')7 L. ^, y- L9 i5 n/ S
return '>';
# K, S( B; O: B: F; W0 ~9 [ else
: i# i, T6 p" V6 r1 Z% t e return '>';
7 b+ P6 r2 X, \. z' F case '#':
) F& S/ v2 v; m5 q if(c=='+'||c=='-')2 V9 r$ U2 i& O5 l7 D1 f# ^
return '<';
+ K; z2 D. E0 {8 |( ? else if(c=='*'||c=='/')
5 j1 l% i" P( p4 O. s4 R- _ return '<';- ?2 ~: C& i. |0 g) g
else if(c=='(')4 z j9 @4 u3 C- [
return '<';1 @" \/ u6 X/ ~; Q/ D
else if(c==')')
& z9 w7 T {& g" q( V return 'E';
1 H6 r; D5 A+ v" H/ P else
3 s8 j2 ]4 M. s5 a+ ] l8 N+ S+ ? return '=';, l& h8 l: e9 x+ d* [0 B, P' I& \
default:5 P( w" e h1 e5 Y6 h
break;
; ]' _$ l+ ^& X2 n1 V& V }( r1 b7 |/ W6 ^+ m/ q8 B* X: q. @- P
return 0;
/ N9 v& Z0 H; W) J- H}
! @: R1 ?4 N: @3 O
" F6 b* L" b% a) F2 uint isOpr(char c)" p( T; S6 j0 O1 {1 x+ B3 \+ ~
{
3 [* ]) j0 R: U( M if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')' l( _9 D+ o1 g- _* D* M
return 0;
5 F6 r0 x5 E+ ^* T else ' M: L* }* B3 v" ^3 M5 b
return 1;+ h. H8 Y2 L5 J5 H8 K
}
. t1 N2 i3 b& Q+ Z6 j7 B: F+ P
/ Z8 X S: H( L" Q6 J+ _; C# G+ m2 q; m# |float operate(float x, char opr, float y)! P4 P% E. o! `$ q- |3 q6 }; T. d
{2 Y$ q4 Z3 k! m
float result;
+ j1 n/ [ C% \" m& J( U switch (opr)
9 T4 x. {, N( j; x% [: L8 T) M {
( y4 n) p- [. |1 k1 k case '+': t/ X0 F* T. h# T9 ^/ R
result = x + y;& F& Q: n+ y6 z
break;# d) K: d; R: i7 K# p
case '-': & o2 R+ H6 W8 t# G& K- v
result = x - y;
) \2 l1 Y" M/ t, E0 ] break;
# X, Y8 N* l% q3 l- d2 d+ g" x! S case '*':
- W D! G/ S3 Y: _( A- P$ J result = x * y;! \) F" X/ n( e( K& \! ?
break;. J* A0 ^8 W+ y
case '/':
. p; T. C9 u, y& i# \1 Q if (y == 0)
# [0 m$ z6 E( ]+ g1 _ {5 d0 @" i& w0 K3 m: e
printf("Divided by zero!\n");
% p0 M( b1 E- ^& q& f* R9 X) P( M return 0;
7 J* u" A6 Y! z( I/ O5 i }( i! y+ o2 b4 \' x) J9 [5 P, q4 S7 x
else
% w4 u; D) F4 _" ~$ M/ T {3 E3 D# c" T% u% _& C
result = x / y;
8 M7 D9 p: K0 @7 _, ^" G break;
% w: n& c# c: D+ u* n }# c9 ]: q6 Z. }! ^
default: F! Q9 S1 C1 i! t# u
printf("Bad Input.\n");
, y4 N. Y+ N2 h% `5 u return 0;
; m+ {7 W% c( v7 s" @) z$ A }
- @+ C2 u" A0 i1 C i1 B return result;# ^7 W, f" s6 D+ _$ N9 U
} 8 u( Z4 a* U( S$ o
8 a0 }/ V2 R. V3 Y
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/4 | q6 }1 y( C
{, k/ u$ `9 p$ K
Stack optr,opnd;* m0 d& N, S4 S& x
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
4 ?' [& V, U! N h6 N" d( T char c;2 Y+ M: m" D2 ~" i
char buf[16];
9 a8 Z% X' j" C# _6 O int i=0;
* U- `. M3 W* W$ W+ e8 S9 j: T $ A& j( F$ i' d7 D2 v6 Z1 o
InitStack(optr); /*用于寄存运算符*/
7 e# Q$ R+ D/ g+ ^- Q% g$ ? InitStack(opnd); /*用于寄存操作数和计算结果*/
: Y4 Y! X' ~2 P( J+ V memset(buf,0,sizeof(buf));: u$ F$ T3 r8 {! l4 i2 L1 _
: L7 m* R* y% U. _* ~0 T0 w printf("Enter your expression:");
1 X, L7 f' O" T! v
. k; n! R' m, p4 ~% b opr_in.ch='#';: y) z! |( d. M, @" m# Y. W
Push(optr,opr_in); /*'#'入栈*/! \* c2 w' i2 l t
GetTop(optr,opr_top);5 E; c6 K s* j
c=getchar();
! O) p* [1 }/ S; A9 J while(c!='='||opr_top.ch!='#')9 W$ P! c, M( Q: v# F# X3 h
{
8 D- y; o/ x; T: v if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
' {( U- u; c7 W4 |/ k {
& a$ }! q- G# [+ U4 Q buf=c;
B0 A# u5 X4 d5 M @* M i++;
" @+ P5 X0 S' {% S+ ?$ M& x c=getchar();# b; |( c# {$ h* W F! s* _
}* N( K K4 v, P3 U
else /*是运算符*/, Z, Y+ [! y$ a* j6 k# l. g, n
{
' {$ C, m' R) r/ ^ E" W: I/ \ buf='\0';
- F* ?+ H( q" o. T- ~ if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
2 ?* f. b7 x. [ @8 |) \1 g {
4 t+ T; G0 \( v t6 \ opn_in.data=(float)atof(buf);0 X0 m/ a* A7 ?# I* |. L2 N6 b
Push(opnd,opn_in);1 K7 w) f' W c- R! S
printf("opnd入栈:[%f]\n",opn_in.data);. V9 c S+ l B# D+ {% }3 n/ v8 T
i=0;/ W9 V, i- N7 O6 t7 W4 b1 N/ W% M
memset(buf,0,sizeof(buf));# O ?$ H' T% W9 i. K1 G4 W
}
3 Q* N; T, F R! } opr_in.ch=c;$ H, E- s- K! j1 i8 t
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/. Z7 |6 Q$ d& V* W9 A
{
0 Q0 }2 O* U3 U case '<': /*优先级小于栈顶结点,则运算符入栈*/
6 ^) h, t2 a6 G" \ Push(optr,opr_in);, K. _+ h @1 T* R
printf("optr入栈:[%c]\n",opr_in.ch);5 \6 y9 k* S' n; `: q# L" ]
c=getchar();. S7 D1 |: y' ?1 I7 T" j5 O1 A$ N$ |2 y
break;4 f4 U/ |1 i; r4 e
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
1 F: {/ G% Y/ Q+ G Pop(optr,e);
$ _! M+ Q7 [/ I* g e printf("optr出栈:去掉括号\n");
! w. m; x* U2 ^ c=getchar();1 V2 X& J; I9 r( w
break;7 D; c: R5 b% H- @2 m
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
+ T" r( Z( \, z4 [" n Pop(optr,opr_t);7 v) N7 k+ @+ c8 m
printf("optr出栈:[%c]\n",opr_t.ch);$ s; B1 U% I, r, p# |7 U0 B
if(Pop(opnd,b)<0)
$ H- S( `, m0 Y' J) ~; } u {3 `# v9 ^( f1 t6 r5 V/ v1 F
printf("Bad Input!\n");
5 ]6 t- V) j0 O5 {9 @* f4 c! ^: I fflush(stdin);$ x$ C! M+ t- ]
return -1;: o5 I- j) j% C& z6 H( l
}
1 @0 ~$ h! N5 m4 L" P printf("opnd出栈:[%f]\n",b.data);
3 l# u8 |# C9 r; J! Q if(Pop(opnd,a)<0)
; P, U4 F9 M, |+ P" `* d# S {
+ L" {' w! \6 y7 P printf("Bad Input!\n");
. m! F( A2 y N: ~1 k# y! j fflush(stdin);
" ?7 H' N$ m# _9 z return -1;: k0 z+ y0 q& ?
}
; b! |* t, Z& }; P printf("opnd出栈:[%f]\n",a.data);
. b. R/ T. f W( N& y/ l1 B# Q opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
! E3 W$ H) F/ y4 ? Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
, {6 V$ r: F; `4 b- N) ? printf("结果入栈:[%f]\n",opn_tmp.data);) l8 M+ z/ v* ]" s! S3 ^" d! D
break;
- J7 u9 b4 I: T* N3 F }
2 S3 x: i! U3 x3 Z8 ?( Z2 T; S5 y }
% ^9 H3 H" x2 H2 I$ H GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
. n0 `3 e. S, d; A+ T }
0 `# L+ c5 B/ X! C9 i8 ~ g GetTop(opnd,opn_tmp);+ p) M1 f9 }6 l2 ?1 `4 o
DestroyStack(optr);
4 I0 |/ n5 F P0 I, z DestroyStack(opnd);! e2 Y s5 \! w/ E
return opn_tmp.data;0 o; {2 u4 \7 L6 e I
}
" v4 ?5 i! C9 N
5 p9 r* D3 C3 H+ d; Ychar *killzero(char *res,float result)
$ P! w6 @, h& Y5 W8 Z{" `+ V% B# g0 A( o% r
int i;2 e% [) Z; c6 T v& n" y
7 L3 i& A8 L6 b2 h
sprintf(res,"%f",result);# ~/ J+ j& ]% k6 |
i=(int)strlen(res)-1;
- l( _* m6 U$ b while(i&&res=='0')* y8 z: X$ M% y% K. e5 j
{
; {; |& {5 {8 Q Y# ^$ Q. B& ~; o res='\0';. c8 D; V0 R' o3 m: m- I% l
i--;% T* J! z: f a7 s8 w2 I4 C* B
}
1 \& J! G$ Q9 n5 _) ^ if(res=='.')
1 `, K5 A* ^5 ?# H" A. w! L! p res='\0';
# [. ?6 @) W: H, f return res;
' a7 _( ]4 P( Q5 y: \/ N& G$ p8 l}2 N1 Y' {) K+ z4 w( y- n4 ~
) h1 |) M3 h& t5 W O1 x2 x' K
int main()8 y6 V+ B& Q$ R! y0 r
{% B: c! d7 A4 A6 v+ z# B# J- c" c' s4 t
char ch;/ i, J3 _+ C5 e8 Y9 _
char res[64];0 L6 W& `5 y! Y
float result;$ J3 Q. ~, Q# J1 b
while(1)8 K% x2 b0 S% ~) O$ O) g6 V
{
. |4 u% C& G- M% | result=compute();
1 I2 [ a8 {9 t$ Y1 U/ X printf("\nThe result is:%s\n",killzero(res,result));
4 b: g# F. k, Q) \ printf("Do you want to continue(y/n)?:") ;
5 ^2 Y/ ?5 @' k/ q ch=getch();: T/ ^. N, n ^1 r0 ~7 F f; a( K
putchar(ch);! B* \" `2 l$ `$ I w# x
if(ch=='n'||ch=='N')
5 S) g, ~! n9 w' ?$ h& h) y break;
. \) p6 o- w' K4 R/ Q7 @' M else
' s* d0 z+ g3 c6 V) R+ \ system("cls");
9 h6 M7 i- ~# G9 M; u }7 l( @/ r" }$ W# F* L
return 0;9 g$ g6 \+ }7 V
}
- L9 U* c) ^8 ^, Z
0 C5 m! a& V* T, [5 e3 u[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|