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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
G: E+ e' d- z程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=. |' \" G# R+ @! T/ U
/**************表达式计算器************/
3 o/ w C/ @* p( v#include <stdio.h>
% h7 h) ^# e4 x+ t6 S. D9 J#include <stdlib.h>$ v0 e2 e' X! M, r
#include <string.h>
A4 l# s" R, y, F#include <conio.h># k8 ^! W8 l9 U! T
#include <malloc.h>2 A6 B% _# W% D; B5 M P4 p
* b$ x9 G9 J0 B2 V- h) y+ q$ g
#define STACK_SIZE 100
% k8 M6 g4 S' a4 x( w, F#define APPEND_SIZE 10
! z2 e; m- P: Y! J+ i! C: L( r# Z& Q2 P) w; O2 e
struct SNode{
+ w6 R4 p* ^8 S R" I; z* { float data; /*存放操作数或者计算结果*// j, h6 n: e. G6 ?
char ch; /*存放运算符*/6 c/ l ]7 R% R$ ]- T
};' I, O' N. K9 O0 O
* F5 g6 a) @. R0 T' q$ j! D
struct Stack{( G! v% J1 ^& M& F9 h
SNode *top;
$ P( u* \. L3 m" _+ e9 b$ U- i SNode *base;! `( c% u+ z8 y5 b
int size;
! r7 i% m: T- Z: n* u};( Y4 C5 r( ~& O- P' h0 c
, _& V$ ]2 M) [, K! w( m, a
/*栈操作函数*/! M" G0 g) \! G9 C$ E# j0 J( p
int InitStack(Stack &S); /*创建栈*/
) ^7 v- b* I7 f- E+ c6 fint DestroyStack(Stack &S); /*销毁栈*/
, M7 D8 l- I' T. i8 {& V3 dint ClearStack(Stack &S); /*清空栈*/
3 z4 r2 [: P/ I' g) W; ^int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/' P& M* b. m" b0 _1 T0 n0 m
int Push(Stack &S,SNode e); /*将结点e压入栈*/
% H4 `% \- d3 g4 ~9 m2 gint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ W) H* Y3 X5 K, y! ?5 z9 Z
9 m! K0 o$ Y4 Y! R5 O( \2 O# u" H/*表达式计算器相关函数*/; b4 o/ {$ g. J: c$ H# G
char get_precede(char s,char c); /*判断运算符s和c的优先级*/$ X. N( K* U& L# z$ W0 q9 u0 A
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
! k ]! b. |( e3 K; M: nfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
8 p. s4 g# E+ Cfloat compute(); /*表达式结算器主函数*/
! j+ P5 V) g7 [" w' G: X/ X* Ychar *killzero(float result); /*去掉结果后面的0*/ 9 H/ S7 O7 I d7 y/ P( P/ u8 r
3 ^; [( R' J# E& ~( b" A
int InitStack(Stack &S)
- X; {& q4 ~( k9 e6 E K{: K0 E% j& D( ~, Z
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
+ i9 z1 Q9 j+ d if(S.base==NULL)3 F' D6 T. l: B* E2 b+ \
{
8 v; N( _3 R: ]+ O* H% L printf("动态分配内存失败!");
6 T1 F, v7 X; e3 _0 \ X return -1;
# i; N* `- X( L }
# w2 H( T3 Y: [5 U: `/ G0 \ S.top=S.base;
5 A5 j a5 n) y+ o3 [5 w$ s( W) | S.size=STACK_SIZE;+ A- V w% [. y4 T/ c) c) q. t# ?& k' @- |
return 0;3 ?5 X. z% N. h5 l+ P; Q' K7 R
}
: O& t9 a) h2 D/ N9 m2 r2 a% ^0 I' f# ?5 `
int DestroyStack(Stack &S)
; c0 u9 \- ^0 Z0 H# N, L2 x( F{
7 ~/ d# P* _3 R( k# h G free(S.base);4 G: \8 K1 V1 H9 x4 K2 v
return 0;
5 u0 t I- |% i}
G. S$ w( }7 n% u4 V3 S) j) H+ S% r( h v C
int ClearStack(Stack &S)3 A+ j* v6 B& C1 ~. ], p6 E- v4 V
{
3 Q3 V: |- Y& | S.top=S.base;0 \/ Q+ O8 N6 T# S; L* \5 F# A* ~
return 0;/ o: ~5 x$ a! D8 {& j
}( P$ u4 E$ {9 G8 @& I( u4 e
# a% R( O* G" D. Aint GetTop(Stack S,SNode &e)
0 k- C9 S* u8 B: ]% V) L8 E{
8 @2 ?$ j/ Q7 }$ x if(S.top==S.base); J* l; x. j; _, S K
{
: @ L4 M' f; }) i9 X printf("栈以为空!");
" j& S; O( W' ^. ?1 L V& M return -1;
8 r. S# f- v; J3 X2 F9 Z }, \' h: \- @* c2 |5 S# j; l B
e=*(S.top-1);
4 G/ p' Z0 w1 [ return 0;
0 J1 W! D' Z8 n [. y}% o% n2 l" M- C
3 \) r8 v% n2 } a7 w% h
int Push(Stack &S,SNode e)( Q- n( z# }/ b, `
{
: O! ^3 g+ I4 g8 ^' z7 X if(S.top-S.base>=S.size)4 K. ~* O1 k5 |% \% u+ ?
{, G# {5 c4 j1 S8 x/ [1 y4 O' n5 ~
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
7 }! [: x' a- }% h if(S.base==NULL)/ s$ K# \7 A$ e- m* C" B' P9 H `
{" f- _$ t% c; q% z3 a2 |4 \/ x
printf("动态分配内存失败!");3 }9 q: S$ z3 `# j
return -1;9 q% ]' Q! ~! t
}: |8 |4 a; R$ T" D, X
S.top=S.base+S.size;& }8 x, O) O' G! H' u# \; M
S.size+=APPEND_SIZE;
2 `' s1 i5 _7 ?3 M; a }& X9 t# |# G% u) z9 F
*S.top=e;
. H" d% N! I' Q/ o9 o* {2 v S.top++;
2 X7 J- h8 u4 \# ^3 e* b3 D return 0;
" O6 {$ s% @% X/ J; o4 k. `$ C2 n}
& n4 t, h6 b2 q$ P7 f
5 Y! Q+ E0 \: Vint Pop(Stack &S,SNode &e)# r$ V& K8 H0 w, d% n# k- o( W
{
5 W% F. g& e2 W1 S0 A& |! A8 g/ ^+ ~ if(S.top==S.base)
5 J5 _" j6 C2 ~( L3 g% V( s! { {# }7 O2 R- H$ f+ X+ K7 t( S6 O
printf("栈为空!");
/ P! x( v/ v" a1 o; F) Q% q return -1;9 \ T/ v3 K- T, \% Y$ x
}9 B( F) _! h- ^, n/ i
e=*(S.top-1);/ _( q1 o' c2 \: L' Q" m
S.top--;
9 e- f! x* n, V, |/ c4 U( q8 I return 0;
2 x# ^9 {: R% f}( x' B: M* c- f, O2 E
+ }) B/ q- A$ @4 n) ~( Q
char get_precede(char s,char c); U, e6 i( Q& w6 z, w7 ^
{
' X w' G: \5 ` switch(s)
0 S. \2 H( {! X {
4 x0 Z; H2 _ {* [$ l( u case '+':
- z) B; y& G! M/ g case '-':
9 ?: F( I* O9 U( @% h5 Y& Z; I9 q if(c=='+'||c=='-')3 x: p' p+ R: _9 O
return '>';3 j) [5 C5 E, b! X3 J% w
else if(c=='*'||c=='/'); F) v# O& F: E$ g6 `
return '<';
- E( j! w( w+ z6 s# i8 `/ ^0 |2 N else if(c=='(')
, \2 F/ ~5 H! |( s; P3 o return '<';
+ C% l/ J6 ? A( p, L# ]6 s else if(c==')')' y; l+ X+ U: S/ g
return '>';
# {8 U, U( E4 j else
" T7 a# q+ L5 W$ b1 D$ u return '>';
8 m, O; E8 E3 a/ m case '*':
6 m$ C9 Q1 l4 }2 m7 b3 q' ]. S% a case '/':- F" S5 I( Z- Z& L
if(c=='+'||c=='-'); z8 V2 h* L6 N% _
return '>';
5 j8 k+ z8 U' V4 h8 @4 h" A. k else if(c=='*'||c=='/'); E5 n7 ~ \" u- {9 |
return '>';
3 [8 |+ b8 B% h+ ^, f else if(c=='(')0 J- B) n3 k7 f6 f' z7 P
return '<';
0 u" l: L m# G1 X5 f# ` else if(c==')')" J$ E. P( E) f0 U: H# F/ V( V
return '>';2 f* Z' h2 \8 n9 y% Z* t P( S
else! D0 |: G- u) W# m$ Y( y
return '>';
; K* k8 _9 o3 ~3 v7 ] case '(':- q- c9 C q& A( c: U
if(c=='+'||c=='-')
! B7 x3 K `/ `# D! O return '<';/ L5 q$ x# Y2 K& h( c& v
else if(c=='*'||c=='/')
d, h( _3 m$ c+ j$ h* |8 A( N! P return '<';+ v) X7 E, H7 _) H o' F v
else if(c=='(')4 y l6 a& ~+ ^8 A* G
return '<';
+ Y4 m; i# k9 h8 c1 Z else if(c==')')
) c) I8 ^$ Q! G+ k+ I: s return '=';
/ k" D" L9 n) I( P else
. y1 n5 [6 a: {9 T return 'E';- y1 |1 C% j+ V4 B( y" }
case ')':
3 ~5 E" K1 E3 n: G if(c=='+'||c=='-')
1 G5 t6 N. e7 O" x return '>';0 k4 r, i6 N; ~" M/ _
else if(c=='*'||c=='/')
) ]$ @% N1 j& W: ^: T return '>';+ x8 r0 q/ Q6 k4 J
else if(c=='(')& Y$ z+ M# a( c) v* J9 a e% S
return 'E';
" ^) C+ C) Q' U7 \9 k2 P else if(c==')') Z! V; P8 I" U3 P( q: Q' U
return '>';
0 d* m3 o- d5 x' _2 x3 Y else K0 r' i* h# z Z o' f
return '>';
0 M( V5 F: @" `- u+ I case '#':
# B" ]8 R0 r1 X2 W- |& Z if(c=='+'||c=='-')
3 h$ p: d4 ^1 p* Z1 R. l3 A return '<';) m- J, L* l' q
else if(c=='*'||c=='/')
7 j+ E. L. N' R- B+ z1 P return '<';
9 A( R2 N0 R3 w: d else if(c=='(')& H, o( z. D' T# E) ^7 ^
return '<';3 t/ F) \( N3 g! M
else if(c==')')( c/ ~1 s5 X, p- j8 F; O
return 'E';) Q4 F7 B, {7 ]" A
else
5 J6 }& E1 i8 c# ], f& ~0 Q7 } return '=';
2 ]" ?/ y) ]0 B default:
$ D5 c3 A$ P2 r- H break;: l c( p3 ?7 P5 j2 K' l
}
0 |* T; c, H8 J* E+ A' j return 0;
* K, n" l' `. ~0 J! k}
! s* a: K E6 |" Q. I* D8 o7 h( p) Q, {
int isOpr(char c) |7 F1 m- S: k6 G: C1 x1 }
{1 ]7 N" \% K; o1 c x: j4 `
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
% s" k/ N) H6 `- W: e/ | return 0;
" I3 P: l! A4 F9 |, x) Q" f else
4 q: l$ p( P0 ~" G& t9 D return 1;3 U. |! j/ `! [4 o% N# Z, U
}
2 I3 }3 F. Q7 ~) z) _$ D" o0 W" k7 r
float operate(float x, char opr, float y)
: o$ _9 e5 A: q" P! t3 }) Q{; Y2 e3 e2 }/ p# e
float result;" F8 q2 n! `! `; P, K* r4 Z) D
switch (opr)9 l( }, t7 |2 Z* z4 A/ S+ }
{
/ S! L; s: O& Q1 S0 }$ m case '+':
+ e% G! b+ U( i1 R1 o+ E. v result = x + y;5 D; y% E$ \: a' _, j2 @
break;! Z$ Z- w% }8 b: f( n
case '-':
: Q" V" T8 i2 Q4 u) ^+ r9 ? result = x - y;
' c, j) {% v+ I# Q- b/ Z% X/ t. P, t break;
4 p7 d! N- N/ @1 G; e2 W$ H case '*':
( J9 P; ?' e( |! b$ `( D* d9 @! @ result = x * y;, G2 n# |8 d* e9 Y! @8 P9 C, R
break;
0 V1 C5 R. y" C- r' q" Y, ~ case '/':
. y5 R; D, u& V0 R if (y == 0)
# D8 h/ p5 R% k' ^) P {+ Y9 L4 H) g; o \
printf("Divided by zero!\n");
6 x) S' m6 ^/ a9 q return 0;/ |" d) I+ I7 d& X, B
}2 q% V: s+ i# x5 a0 J! Z" S
else0 k/ l- X4 ~2 J! ^9 k
{* [3 R4 B! `6 E$ w# B5 P7 s1 s
result = x / y;( i( u1 T5 d0 M5 `) w( q5 d
break;& D3 ~ l) ?- j* K( R; ~ S
}; L2 m: p+ q& J1 a
default: 4 J. T+ W9 Z. v6 s0 J8 \
printf("Bad Input.\n"); : n% x$ y+ l7 _; L9 e6 i, I
return 0;$ l D% h) }# P0 B" P0 }+ J: V
}
, d1 a- J6 a, C: k return result;
% s! c1 ~6 E) Y$ r( t8 o# T. U) N' e} & K- a) h0 |5 [5 V8 o. o' g
( M* }& p+ G. [: m% m" H
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/ M- g: y+ W, o9 V3 U- K/ O
{
& \+ [* t. N$ y6 H9 ]! Y Stack optr,opnd;$ o# K8 Z4 M9 z6 `( A8 |
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
* w! X6 _* L# R char c;. d, t/ |1 |) z% E8 M/ y0 P8 X
char buf[16];( z% W' i# N! }, E/ m5 }% k7 k
int i=0;) I* g3 |- D3 ^" l1 X
/ a* i* Y' V! Z InitStack(optr); /*用于寄存运算符*/
, M2 {! c, g7 G) N, K8 |* ~ InitStack(opnd); /*用于寄存操作数和计算结果*/% o6 Q1 l. c$ q0 v4 t
memset(buf,0,sizeof(buf));, Q/ `6 ]0 {8 e) E
- v F# y+ ]$ K' @7 I
printf("Enter your expression:");
* l# i* y. Q) z7 p. ~7 i
4 h; ]) T0 r6 }6 b! T% w opr_in.ch='#';
5 P, s& z" t! d. F% Y4 y* _ Push(optr,opr_in); /*'#'入栈*/
W, J4 I) a* q+ U3 i. |( R GetTop(optr,opr_top);
* @1 a z% _# Z" _& y c=getchar();. U- _% r, L: [, l5 M" h2 d$ [
while(c!='='||opr_top.ch!='#')- q3 n$ k B* ^+ Z) b
{
$ `0 F$ Q2 |9 `. j" v9 P if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/5 }6 C) Z& q( }9 H6 F- W+ }
{3 w6 }0 k9 o& q) @
buf=c;' e+ t, S( [, U8 d4 M: V2 o
i++;# ]+ _/ w- _( `9 x" q8 N
c=getchar();' H9 }$ H, T/ Q/ C0 o# L, s
}
5 @* C* {7 c- ~/ l6 f* r else /*是运算符*/
. u* R1 D$ W& p. y5 C7 `& f {. b, [) D, \5 L2 l1 O; ?5 Y
buf='\0';( H( C& Q0 z2 {) E3 O
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/0 j7 g" D- ]! R5 z2 l
{
8 k$ p& Q1 o+ m# z% L opn_in.data=(float)atof(buf);
7 J' `. |, B! H* A5 S* {3 R( L Push(opnd,opn_in);
& S0 l% e J+ _! H4 {( ^5 U+ u printf("opnd入栈:[%f]\n",opn_in.data);- n: Q7 h" V5 i* y" e
i=0;
3 F4 R- t+ @) n: C8 f' S' J memset(buf,0,sizeof(buf));
+ o$ C8 Y5 r- s! R/ @ }
8 H# r& A. d' U) Y! Y opr_in.ch=c;
% k# `$ W" L# y switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
% G5 N% t* ^4 b! _ {, L6 d5 @* p$ ?3 \
case '<': /*优先级小于栈顶结点,则运算符入栈*/
/ W' N1 Q8 _. C3 O+ I Push(optr,opr_in);
3 q$ I1 v; n$ a6 @5 X) n! }9 @, s printf("optr入栈:[%c]\n",opr_in.ch);, P K: B7 S6 U& r
c=getchar();8 \% ]- H& O9 [, Z) ~7 ?! e* t) W
break;
. b0 o$ {: j; Z case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/3 D( x$ ^3 X( V5 s: s) j# U* d; u
Pop(optr,e);+ t3 V' r! l, T. Q
printf("optr出栈:去掉括号\n");- U+ k+ D1 u% X n, n# N4 @
c=getchar();1 j$ b# v3 S2 L X! |
break;9 q/ A8 Z6 o/ I$ W9 }$ ^; }" y6 V
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
- \8 t' z1 ^; G" A+ _! P5 G Pop(optr,opr_t);
( t: o) U; H1 n+ ?' g printf("optr出栈:[%c]\n",opr_t.ch);
, r; w8 ~3 [1 }$ h, @& W if(Pop(opnd,b)<0)4 |5 @5 Q7 P4 b/ j
{$ V( I' F1 c& r! d+ c, T
printf("Bad Input!\n");
! U8 S4 i# m( Y% _ fflush(stdin);
$ Q, e/ `% O$ J: w9 q# S return -1;
8 p% a% q* s6 Q' f+ o( V' J: F$ g }
! {6 W/ g3 M. Z# z% @* u& w printf("opnd出栈:[%f]\n",b.data);
5 ?' X* J2 X" e if(Pop(opnd,a)<0)
. M; b1 c( |) G0 Q1 Q" f/ ^ {" I! A5 @% x. v: B) A
printf("Bad Input!\n");$ A; Y2 T# D9 r d' J2 P
fflush(stdin);
# E3 v! o5 l" ~. P8 V5 \5 e9 l return -1;8 I1 \) T& v! {8 X
}. j! G" ]; s( T+ j8 A
printf("opnd出栈:[%f]\n",a.data);
5 g2 \, Z( G' [8 ~2 | opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
7 A6 m3 I0 b. K9 X* I Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
( T5 P5 x( c) j' Y+ [ printf("结果入栈:[%f]\n",opn_tmp.data);
; _ ]( J1 B9 k0 `% C" ^+ q; e break;: [5 ^& ?( A! N2 Q9 b2 g/ f
}/ C/ T+ S) R* Y( U. _4 ~
}4 O/ m8 X% ^0 B7 m
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ ! ~: n0 P Y% _, {
}
/ i3 D a9 a: r7 V" E' f5 D9 h7 F GetTop(opnd,opn_tmp);* p" z* m0 Q% I$ x) R [" C1 F
DestroyStack(optr);# s% q% x' E- e0 `! E% i8 @3 U! i
DestroyStack(opnd);
# p& d! H& n# R- H- m/ S return opn_tmp.data;" r# A1 D6 m) L. k' E* X8 ~
}$ X }# _) Q- E* [# |7 U- E) i
/ c" ^5 q0 C$ h" Ochar *killzero(char *res,float result)
, u2 i- T T& f( o{
/ Q' H3 ^6 J2 G; P" z0 F& i. t( z int i;+ r+ H6 h0 H$ K5 \( H
m9 Z. T# Q# e& A% N# a sprintf(res,"%f",result);4 } E6 M8 D# F8 n
i=(int)strlen(res)-1;; q( L$ s* \$ I
while(i&&res=='0')# Z" g7 i/ X- c% C3 I Z- C6 h) p
{
: s8 Q4 z1 \3 h; Q: d' t res='\0';
* K5 A( A- [( M& s: d% f i--;
, z& x5 m" Q5 } }
# S. s7 @ @: u4 l' r if(res=='.')
; c6 z- l" ~( r0 A res='\0';3 u7 ?7 i8 u- P$ t1 Y! G/ N
return res;" D e O( C" c6 ^3 }
}% a ^0 t, |% Z" J- P, C3 B- N
( g0 s; ]. E! q% y4 [! }
int main()
! z& c& n! n/ X; N6 J( V% Z- o{
0 @& S6 f& T& q+ s char ch;
: q; Q; @$ _" M% r1 F char res[64];
0 `4 ?& Z! v. P/ W* Z float result;4 h1 [3 Z9 U3 C
while(1)2 t( N7 Q6 }# ?6 t0 R2 L
{
' @9 p, }$ e3 Q; |+ w* q result=compute();
8 M) m k$ w. a+ m) G' {5 b$ r printf("\nThe result is:%s\n",killzero(res,result));& ] b9 M4 I/ b8 K
printf("Do you want to continue(y/n)?:") ;; [. J0 @3 @: f9 d0 d8 }; y
ch=getch();3 I( o8 ?( b1 T0 [
putchar(ch);' Y6 F4 B5 l; U& e% x; O
if(ch=='n'||ch=='N')8 q4 L* ^9 B3 U7 u1 i2 X. d. {0 a
break;
9 T9 k y1 F) t! z) t# \ else
! {6 h8 N/ R! d/ Q% x' E system("cls");
! H1 ~% E2 B# K5 p, u1 x$ y8 v }
3 r' Q2 i2 G4 _5 _5 J4 q& J- L return 0;# l8 |- d Z1 f! s$ M5 a" C
}
4 }" t# F$ i1 U$ n4 |+ y
X5 a* t; _3 A* h1 I. d[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|