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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.. C/ ^! V$ R3 a
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=, V) |9 e6 O2 h m' V& R" D1 j
/**************表达式计算器************/
9 ~3 H7 ]2 ~1 M" e+ m#include <stdio.h>
4 k0 l6 E+ w$ q" Q) B, `#include <stdlib.h>
3 g1 {7 c, [" b3 E0 p% @$ N#include <string.h>+ P9 v! G' a" A& k8 ^- o6 r
#include <conio.h>
& f( K* o R1 A#include <malloc.h>2 d4 Q, S8 E! M& |9 T* t/ ^
( S# l5 y# E+ c6 c2 K" G1 c, h8 w#define STACK_SIZE 1008 T! n7 U5 t- _! z) O
#define APPEND_SIZE 10
% T! c* z& \; s* Q3 M. h
$ x, L$ M" d0 S" C" ostruct SNode{
* J) e4 S& u' l$ ?* @2 t* P6 f* P! S* A float data; /*存放操作数或者计算结果*/
4 r1 P. N# o5 U" l char ch; /*存放运算符*/) z8 j t3 [3 A* W1 h( F
};8 U3 w6 }8 G7 Z! K3 { w, _$ n% U
; b& Z5 U+ P2 E0 r$ {! O" bstruct Stack{" b' G! ?5 F; l& i, S
SNode *top;) f a- T. i$ N) G5 _
SNode *base;
* g& s# L* g7 C! J& } int size;
/ N; C" A n7 L" n};: D. J" Y6 i5 ^( A- M
. Q; l4 k3 v( K0 t/*栈操作函数*/) v& y+ Y& q- } L$ i; F& j
int InitStack(Stack &S); /*创建栈*/5 Q# L4 _" O# `! ?) u6 ~3 Q7 }5 x' z! f2 m
int DestroyStack(Stack &S); /*销毁栈*/; V# j5 p; l2 `; G* z6 z% H3 Z
int ClearStack(Stack &S); /*清空栈*/
' q; {8 v x. |1 U; x' ]6 C. S* Fint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
- H& J# e# d5 Z4 O0 gint Push(Stack &S,SNode e); /*将结点e压入栈*/2 F2 y9 g* `3 L& J3 K3 Z
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
1 e& J" L8 V! A- T0 T% W0 P, Y* ]+ l- S; l. w! i2 }# b
/*表达式计算器相关函数*/
c# ~8 a4 ], l- s% \! Echar get_precede(char s,char c); /*判断运算符s和c的优先级*/0 e; e) S& m, I- _6 ?
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/) l1 m+ }) u: ~$ ^. C2 W5 M' K
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/2 m' M8 G( m1 s3 H
float compute(); /*表达式结算器主函数*/& ~. j( O5 e/ v, s* W0 U
char *killzero(float result); /*去掉结果后面的0*/ ! q$ q$ Q6 Y: x, |" X8 j/ d
8 D) I' M3 Z, Q7 k, L1 k
int InitStack(Stack &S)
& o# L4 x* l$ a! z{
6 B8 d2 D& [8 Y" Y8 D0 }, t4 l3 y- W/ ? S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));5 p |6 a* P0 k7 c$ o) s
if(S.base==NULL)5 F$ V1 Y! Y+ j6 N1 b% V" t5 l
{
/ y5 B! _* b/ E" R! M( ? printf("动态分配内存失败!");
; b/ g' r w4 s" m* ? return -1;5 m& ?7 ^& i* s8 \: g! E
}
/ }6 H/ }9 g/ I% p& s) w2 g S.top=S.base;
& V7 }' O+ d2 J. `- w& [ S.size=STACK_SIZE;, [1 f( h) S) x
return 0;# q! @' k9 K! n& \- w* O
}
S% y7 |2 ~6 w3 `" h
( w. f! ?' x6 q; `int DestroyStack(Stack &S)' N% u! x2 K# ?2 u8 {3 g3 C
{
1 z& [" {$ U9 A' A, i/ \ Q% V free(S.base);
7 K5 q3 u4 y4 r. i) m. [; m3 `, g+ p7 e return 0;
; ]( } z0 }) S# |* R}% k2 j1 m0 B! A8 H, y
$ i1 T) n0 g, T# t+ m' u
int ClearStack(Stack &S)
, e( \) L3 C$ N [{) e, |+ N% H5 ?% k
S.top=S.base;
8 k$ a1 k( D/ q9 B return 0;: d2 X' G4 X* C* w1 q5 `
}* g; d# U& z7 Z' \
" s* h; K4 u. L
int GetTop(Stack S,SNode &e)0 P7 p! ?: u) ^: u- u
{
3 N( G \, \( y: P* E if(S.top==S.base)
* G9 |/ { a: p8 t {
+ G: i8 X; c w4 |; u printf("栈以为空!");, L/ O0 m" M' e1 H4 E
return -1;; K: T3 o/ J3 z( a' Z( z" F
}
5 a) b9 a# U, c' K e=*(S.top-1);
' ]1 f( r& s3 L1 Z7 E8 | e return 0;
- T+ \' |( w4 p, V0 q}3 W% Y6 P# A, {+ U0 U
2 h+ k3 e' M/ c3 C6 kint Push(Stack &S,SNode e)( Q i1 [4 i" N- ?: V
{7 f P, e: n3 j( t/ i, }6 n
if(S.top-S.base>=S.size). h( [! |! z2 M
{
* y: E# l2 }# u4 G3 T+ r8 e: d) A: y' X S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
; i- j! D" A9 F+ v. u if(S.base==NULL)
5 I1 }2 l% V! D, q {
+ g/ s6 m! p9 ?* o( |* n8 E printf("动态分配内存失败!");" c- k6 v2 n3 H2 g2 I0 f
return -1;6 t9 B' u5 W2 K: ^
}
5 l) ]2 E6 a9 R5 D" ^ S.top=S.base+S.size;
( i% A+ U. r/ ? S.size+=APPEND_SIZE;
7 G8 t1 ?- E7 y }$ j; D H) o% [/ h) ?
*S.top=e;3 G: q2 B$ E3 d# z1 X6 k9 _3 o
S.top++;
1 Y9 C# @+ e6 ^7 ^ return 0;
6 z8 i5 k) [5 I! B5 A( b* {5 R}1 \" M; }( v4 A3 i
- Z/ F6 ?0 Z* W+ Z% J
int Pop(Stack &S,SNode &e)
; [; G: W4 A5 b& T{0 M" r$ X# A$ c3 W1 h
if(S.top==S.base)+ C: k/ l e& X3 n4 q% f
{
) h: p- K; n+ q) j! [6 F printf("栈为空!");: a* ~7 @9 K+ {! Z7 Z- b) I, ], x
return -1;# I* D1 r7 }/ |3 \9 ]) }
}) R9 `* c- V1 N
e=*(S.top-1);
# q/ x3 A. Z( f1 R o8 }$ y1 f S.top--;0 N2 F4 D k7 {# t
return 0;" C- d" \; |; g% J i
}
+ ?7 a1 o( t! U) y$ Q* `7 i9 _& u' i9 E. ]$ o9 M5 |
char get_precede(char s,char c)
; g+ G$ F7 j) p: c( B{
1 G+ t1 d1 `. L: u+ ]) W switch(s)% v- x, e j' H9 ~5 `
{/ C1 |4 c( i$ z l' `8 E9 g
case '+':
- ]* x- O) V* t case '-':
3 i% }$ d6 }' r& h, ?( { if(c=='+'||c=='-')0 u0 ] R3 J' g" I
return '>';
/ g, ^) w: i$ C else if(c=='*'||c=='/')
9 u) `: x$ |. I: h# |) y return '<';: a* i6 D% u! P* E
else if(c=='(')
* }7 v6 ~7 W; Y7 ]9 P0 |6 K return '<';9 z, R# E" `/ `6 C1 n
else if(c==')')" @4 `* j7 @ Z0 A. E/ z: V
return '>'; P! m# y! `. U5 j4 D, W
else l g- e' c V5 l2 K
return '>';
+ l. d v' {. y2 S0 r+ @ case '*':: V _* ^3 a% V1 I9 F0 n
case '/':6 b$ ~: A* K* H z
if(c=='+'||c=='-')
g$ s+ F3 p) J! ]' ] return '>';" p2 c- r& H8 L( w5 ]8 g6 G4 T
else if(c=='*'||c=='/')
% G- {0 X9 X" l' h return '>';
1 u" c7 j4 B8 E else if(c=='(') Q E" [# m% n# E4 J/ k: v' z9 V
return '<';
6 E0 z2 o8 W& I4 J3 s7 s else if(c==')'), |6 s8 ]5 n; s2 C. q
return '>';
0 g+ U! ?6 Q8 G/ H5 W3 O else
8 Y, @( C8 o9 b. _ return '>';
$ m$ t; } p2 X* U" }, G case '(':
- A; y" Q, L4 B if(c=='+'||c=='-') E# X: k3 I& A
return '<';& t# J% R) Y3 R7 s: w' _
else if(c=='*'||c=='/')
O3 b/ [2 L7 x6 k+ h return '<';1 H( D" G; [6 S$ F! w) n# C6 u
else if(c=='(')
! o( N* _/ u6 f return '<';( |0 `# Y4 b7 }9 N( [
else if(c==')')
! Z3 L' t0 c! q return '=';9 k6 K# K. _$ h$ Y
else/ o! @% [( ] ^/ z7 Q6 }
return 'E';& N/ S Y1 O! N% d9 e
case ')':3 M, d9 H% m! q/ w
if(c=='+'||c=='-'), T4 Z, [9 n5 P: f# Y( t
return '>';( i. x! [9 B. ]0 \: m. k
else if(c=='*'||c=='/')
7 }2 x3 ]- m; r0 n. | return '>';2 s4 g2 M' g3 {+ _4 v
else if(c=='(')
0 B, q6 h+ e! k return 'E';3 I# C( A) X& G3 U! j+ p: r
else if(c==')')
7 c* Q$ ~" r8 u5 l2 I$ G return '>';1 D+ V, [4 |, t W) c$ `
else
$ z/ Q* \6 I1 v8 H, z- R# t6 c return '>';
! e. p. A1 Y0 a+ `2 d1 g6 J" O case '#':
9 ~0 j" F) b& z if(c=='+'||c=='-')
+ e5 I4 b4 y: D7 F, b return '<';- }, s( u/ H# d0 {
else if(c=='*'||c=='/')
" R. X; d- p5 i! C return '<';, o; z8 W" [0 k1 ^
else if(c=='(')
# ?! o$ N# w& x3 d o G- B3 w" B return '<';4 g1 n/ e% i# S0 Z
else if(c==')')3 y3 L# B! a( M: T* v$ h1 E; T
return 'E';/ y' ~* Y0 r) [6 b) \
else
! h. m# ~* W9 f return '=';
, X5 B% A; T% E. \7 {5 {1 y3 b default:
X) f' A8 s1 L. l break;2 Y0 w" \9 t& E& Y
}
: g k1 W; k& b3 w return 0; 8 t$ n, o$ c, \5 k* x
}6 q. [8 ]' ^& Q" A# B9 V6 v: @
6 |9 {% y4 O. t' r7 `$ n
int isOpr(char c), M) j7 ^% a1 d" J1 @6 g: I
{3 c9 f; I7 i# I* t) Q
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')2 k$ ]/ E7 w" b v2 m5 D
return 0;2 @$ S- S8 C1 V3 T8 r; H
else " X/ P- u4 D8 t9 o8 S/ h7 L
return 1;
- E& U6 J7 N6 ]$ g# F' z}, z/ N1 W# Y& C9 w) [( I* y. Z
. q, s( u# W; u I+ d
float operate(float x, char opr, float y)
2 u- H# `. O+ Y; J6 b" a{, W( _+ w# M7 j6 W
float result;6 V7 O1 N6 i, @. K0 _( n" f; Y! [
switch (opr)/ _! r' @* I) Z+ f+ A
{
1 i$ s, @0 w" J2 y case '+':
! U1 x0 n" R; k6 ^& ? result = x + y;
! j+ q3 P0 s' V) d break;
. ^$ H' i% p/ H case '-':
. ]% a. r" Y; y" [2 j, _ result = x - y;
+ D Y3 Z1 m: a) e5 K break;& g. [( f) N, T2 J
case '*':
, J# h" E8 K5 c* P. h result = x * y;
( c6 W8 d1 }( f9 K break;
8 S' `- x f# r) A case '/': ; b* K2 u$ c0 R' e" G# \. r3 z
if (y == 0); H0 S) ^( D" \( F* M7 t, e" }5 d L
{ } v6 Z8 E2 B
printf("Divided by zero!\n");
D) U2 F, O# H/ w return 0;
I5 @4 Z% u' Q; C% R2 A. z }
$ ~8 n& L6 Y, B- W else
' r/ X% Q) {1 q6 x {- F3 p9 |1 M; g8 d3 [+ {7 |
result = x / y;* ?! \0 e; c8 T9 L
break;: }' j+ ?! t3 X6 ~
}
+ Q5 V0 O0 l0 R default:
* l+ l) D; s! l) Y* f* j printf("Bad Input.\n"); 5 J# A" n4 t! {" ], q5 Q* O1 w
return 0;; Q2 T f5 h3 Y2 p) H
}
3 l/ t7 B7 G5 W; u* c return result;
, x! A1 f, v$ E% t) a* v/ S4 X}
* I! R* T4 _0 k7 p" C5 w
& O- H8 Q" g( \" ], Gfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
7 t Y$ G5 B) _5 }& ?- K& u1 b{
& W& A G8 k1 Q, g5 u6 n Stack optr,opnd;: |6 J5 R$ W* K; j% U6 e9 [7 H
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
i) G. x( ~) x& [5 h char c;
* e3 B! D; I' H* ?, C) F char buf[16];: y8 a. z. b& X: z# Y J
int i=0;. O# p% v* n( ]% b; ]+ x
/ n' D) N/ J* d5 L, G
InitStack(optr); /*用于寄存运算符*/: h/ b' A) ~9 n8 D6 b1 e
InitStack(opnd); /*用于寄存操作数和计算结果*/
3 B3 c: h2 D9 @# b memset(buf,0,sizeof(buf));
+ |" D; X& ^) O* h0 P+ A/ h" _, N 5 k* n$ S7 }: ], U5 }" P- c" ~
printf("Enter your expression:");6 C$ v1 y# H# ]; _; u
; H( ^2 J- _% n# z' @: q( y
opr_in.ch='#';. P" g) { E% e2 H9 U
Push(optr,opr_in); /*'#'入栈*/" _; I+ x/ F' D9 C
GetTop(optr,opr_top);( k! k* Y0 C$ b* b5 D
c=getchar();2 X. |/ |0 O" ~
while(c!='='||opr_top.ch!='#')
H0 q/ b( I* I& w {! a7 {. k* l. |) `% h
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
! q2 p% S2 W+ M. v6 G! K {. b9 n' s6 V7 X j% B) }
buf=c;! @& u! b. y# @( g% _
i++;
% x4 k3 u+ C. ?% L' k' M5 v, \ c=getchar();( d' C/ z5 ^' T, W
}
3 j; N* R8 b8 i3 A. K2 B( E else /*是运算符*/5 L; o0 s- P4 A$ Z3 z8 }
{
- C9 x8 z+ r8 K: m buf='\0';/ y6 s/ G$ C: J: x6 a/ c: [+ R4 l
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
5 S8 C0 S! _5 S7 A1 [6 ` {2 c( T% S; c; y+ E- ]7 D V
opn_in.data=(float)atof(buf);
- p2 ] w& }4 Q9 s0 ^- ` Push(opnd,opn_in); P" S+ c8 n9 r1 @ t% I5 l2 f( g
printf("opnd入栈:[%f]\n",opn_in.data);
8 |4 }# W! P6 g i=0;$ p L' p; o# `. E
memset(buf,0,sizeof(buf));& |0 m! P4 j% |7 s1 H- i5 B# X
}
" ~. M% j4 e9 s7 L+ }" j0 B3 [ opr_in.ch=c;
! ?: x; C' A/ k9 x1 u2 [ switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/* R) X% D) c* w8 s$ U" X
{+ ?, g& l, I) r
case '<': /*优先级小于栈顶结点,则运算符入栈*/
9 p7 E- |! B( @1 Q* L0 [ Push(optr,opr_in);: `1 }3 m3 f9 L. B& P% A" v- q
printf("optr入栈:[%c]\n",opr_in.ch);
9 A1 F' }' ]% t& S2 F( D6 ~* H c=getchar();2 f% e' Q" n" @
break;3 g6 c- P: r5 c/ |2 `
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
: R. z% n* @' G- H$ M8 h Pop(optr,e);. L; b6 v9 [ q; R/ |1 E, |9 Y' t
printf("optr出栈:去掉括号\n");
- T% \7 c8 Y6 v. z( z R( z$ s0 D c=getchar();
) ]: b7 J$ s# z. J) R) V break;0 ?8 u% @) m9 H( c; W
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/8 M& n( ^5 [6 o0 c
Pop(optr,opr_t);
# H) i5 w. o+ ^6 J" u3 [$ h2 s printf("optr出栈:[%c]\n",opr_t.ch);/ E" S0 Y/ f% E7 C
if(Pop(opnd,b)<0)+ k# ~) E# g4 w. N: q
{3 a/ w B8 e' v- n# e, G
printf("Bad Input!\n");
4 M m" }7 J; _0 ?8 S fflush(stdin);# [! E& {% e" F- a/ \
return -1;
9 o( m4 F: V% k) I }8 u* D. D5 @: O" I" h1 z
printf("opnd出栈:[%f]\n",b.data);( i$ D f z" r: i; E8 X
if(Pop(opnd,a)<0); C) k8 P/ q4 `8 t, d
{$ r! [- ^4 V- H9 }
printf("Bad Input!\n");+ @8 ^# \( b n" N( j7 A I
fflush(stdin);
0 U& I% @4 V1 [6 f, G" b4 J return -1;
s% u+ D+ B9 _: l( a }" ]0 s3 v6 P$ c$ }+ d0 i8 _- v/ {
printf("opnd出栈:[%f]\n",a.data);# [3 p' ]! o% m& V) K, q( S# S l
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
6 O( Q3 S& W7 ?6 h8 C8 e: [/ a3 Q Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
$ f# c! C/ S0 e1 X! ?: Z printf("结果入栈:[%f]\n",opn_tmp.data);
* N0 ~2 y' i8 X4 n. ?4 ? break;
3 W2 g% Y9 E- d0 U9 m6 i0 s }* e, E6 X# C" ^% F; g( o% p/ T8 E
}" y/ ]( b- Y, h& h5 g, ~
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
0 `8 o5 {1 N. Z9 Y }% \9 ~5 y2 t& ^' S
GetTop(opnd,opn_tmp);7 s2 `0 w, p) N2 R7 y" U- O
DestroyStack(optr);
; ~4 E/ p/ R7 x DestroyStack(opnd);7 g$ N8 p8 e7 ^) H2 R, g1 `' C
return opn_tmp.data;
) ^1 [* D" B6 m0 o2 F5 h7 t+ R}
' m7 S8 A6 d! o2 G. S% `
& N! A; E. X, _" \char *killzero(char *res,float result). O8 ?8 v3 T( a5 a( o# i# X
{
2 I3 I1 Y# B+ d8 v: i0 } int i;2 \% B% |8 Y4 R
( I8 A, A4 \* z% C) s5 l! H! e
sprintf(res,"%f",result);, _2 z4 t" {" D }# x
i=(int)strlen(res)-1;$ P/ l+ \* H$ T# T0 D' \) k7 `/ ?
while(i&&res=='0')
6 Z) x0 c/ g+ b* e" o+ [3 F {6 t8 ~ o. ^9 M% D! r, Z
res='\0';
# I W v6 [' B0 ^6 ` i--;8 Y8 o+ t) b6 [$ f9 V3 e: d! W
}
( F, h- Q: t; u5 [9 i! o if(res=='.')
; e3 H/ t- `- m+ E# @4 C res='\0';
$ [; n/ W+ S, Q; p/ V' ~ return res;
- g* L' @ T& E8 v1 G' v} h4 y5 o* Q0 M4 K9 }* g, \
5 O7 d# t: N6 y+ s: }* L$ T
int main()
3 B* {: [% V- ]" ~" B{
5 P5 k7 j! B/ @ v- Q9 F char ch; p& V4 o l b; l% v% K2 a
char res[64];
, X$ ?5 c8 y: \0 _ float result;
: }( p) D# a. R0 A" C while(1)+ Z1 w+ q6 o1 z, o/ Q; a( k
{& [6 U, n- ]+ p' R; k+ J1 a
result=compute();% r1 C# o, j# E( V4 l4 M, [
printf("\nThe result is:%s\n",killzero(res,result));% J* H& i7 R6 V2 R
printf("Do you want to continue(y/n)?:") ;) \& O$ e1 d" V+ y/ F& h z
ch=getch();5 V$ {9 ?$ C# X5 U) Y C3 F
putchar(ch);. T2 V# M6 {# S m& Z
if(ch=='n'||ch=='N')
& W0 k/ k) w2 A2 {2 Q' @8 V break;
% k% K6 _6 H+ k" k- E; z else, c" E5 d$ f8 N E+ q0 p4 F6 N
system("cls");3 r/ o5 \- Q# @9 G" P9 z6 g) Z! p
}' @- S4 O' G- E
return 0;
- [* k1 G7 w1 k/ l2 z}( O5 m6 i& ~ c" R# d: D8 K
. j. j, Q6 p. S- m6 k% A+ g) Y
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|