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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
2 I+ ?& h5 ?; i/ W5 N1 [3 p程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=, J+ E& U: S9 z+ r! f/ j2 Y3 z+ b W
/**************表达式计算器************/
8 x% L# ~! n( k! H0 ~. B#include <stdio.h>) _9 _. r' j/ B1 m# H* w' \0 G
#include <stdlib.h>; N. k6 D: O: b+ b0 o8 G
#include <string.h>+ y: c9 ~+ y" I
#include <conio.h>7 B; A* G3 r H r5 I# w i, x/ S
#include <malloc.h># R2 L+ N& a6 ^* ?+ o+ g! ^: h/ I
) a$ F1 a. P% I- L( O#define STACK_SIZE 100
( G2 L" _0 i5 S5 N; a+ w& |) ?#define APPEND_SIZE 10
% }) F" U0 a% B8 f: f8 v4 v+ |' Z8 H
( U! {3 H7 C ^% i# O( |struct SNode{
+ C! ?$ t: v3 O( Z1 P% [9 V. G float data; /*存放操作数或者计算结果*/
# O4 x" ]/ ^+ r char ch; /*存放运算符*/( }" p' }# Y& z" O; N2 F7 I
};; A9 |1 l& u; r( B- a, M- U
; y1 A% c; y4 R8 E4 i7 S% T. [# S Ystruct Stack{
6 y* d$ ?! l' i/ e, f. }( ` SNode *top;! S$ V/ O) j+ I: p3 k
SNode *base;# j; O! X3 y7 M
int size;% p. t( p# b' [$ O0 }; T5 I
};1 g# [; ^7 @# X- b& v) f
0 }3 w Q4 K0 Q( C0 q# K
/*栈操作函数*/
& K$ i4 Q7 b5 J5 p8 d8 O5 dint InitStack(Stack &S); /*创建栈*/
9 x/ i' a" O# j* I9 A$ U4 H+ {int DestroyStack(Stack &S); /*销毁栈*/
% w2 u$ F, w5 e6 E1 a: \) bint ClearStack(Stack &S); /*清空栈*/8 Y' s- l3 Y+ w( @/ D
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
8 w/ ?5 V0 k5 d; lint Push(Stack &S,SNode e); /*将结点e压入栈*/1 J% N9 ~8 E% X* Q8 z8 f
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
( l0 |8 u# o" k% a' E Y" O( D P! p9 L3 t, p3 U
/*表达式计算器相关函数*/
$ t. O# t7 v3 w* L! C2 `+ jchar get_precede(char s,char c); /*判断运算符s和c的优先级*/. D2 I! B" J4 O9 j$ V6 W5 r( j
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
8 w( |9 K0 t' F0 [, g' q8 Tfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
! r' g. B" D7 A& ]float compute(); /*表达式结算器主函数*/
0 D9 F1 J* _3 b- @" X/ ^* Fchar *killzero(float result); /*去掉结果后面的0*/
9 U, }# L( B4 m8 w7 [+ g8 X2 B2 T7 e$ F$ @% E0 g3 }* D
int InitStack(Stack &S)# I& q p3 Q' i4 B3 U& Y' n
{$ I; d# `) M3 j# a: I5 }
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
) z' e" h+ g' a; T" h if(S.base==NULL)0 f: ~: d+ c: r, m$ J- T
{6 j& v5 \: P. }' T9 Z
printf("动态分配内存失败!");+ N2 H# R* [9 U4 H$ a9 g/ ?4 b& H
return -1;1 ~% ]" A, `- L; E9 M8 D
}
) Z6 i, C9 v5 R1 K# s0 E S.top=S.base;
( G& }3 m0 k9 \+ { S.size=STACK_SIZE;
, z1 q: j$ C0 X return 0;, ~7 C$ [ W0 H. g; X9 [
}; _# J5 m9 n6 F
& l+ t, _& U- G; m. E7 w
int DestroyStack(Stack &S)6 w8 m9 e/ y% l! p V8 z. e
{. J0 j9 b6 i" K! x
free(S.base);, d6 b4 d; B/ |' y0 O
return 0;
- T8 Y, G D% y% }- L; J, n4 A9 d1 i( n" F}
2 d3 v! N# q- N
* z- Z$ ]" D; B9 pint ClearStack(Stack &S)
+ E8 d4 w) h- z- s4 N6 ^' c: u{
" U6 p4 @. j, f* u% _/ h5 z6 Y' y S.top=S.base;, S) w6 w* }* ]
return 0;
4 c3 q8 S" ?- ^. b. w) I}0 |8 w& K( i2 S+ A8 c
! K# \ r6 P) j+ R$ G( y
int GetTop(Stack S,SNode &e), b- {: |3 `) q
{0 f1 R9 i, f% T9 p: W# D( U
if(S.top==S.base)7 T9 p& |, Y% \" ]+ U* z! K! R) r
{
% |* N6 M+ c; l, l/ w printf("栈以为空!");) S/ [+ ?' R' v& ~- x
return -1;
- t9 P, e5 H0 v2 o; @' D" H, t4 l }
i7 |9 e4 x5 V, ` e=*(S.top-1);. _8 E+ c$ n `9 a
return 0;
" y2 E* O" u- X) k, J" Z% _1 @1 F}5 _* z+ E1 e8 F/ ?9 m
6 D$ x) c$ q% z$ h8 S! C/ e
int Push(Stack &S,SNode e)
( u) L$ s. ~% d, n4 C{
4 r5 b# s6 D9 ]- j* `4 v' B) P A if(S.top-S.base>=S.size)
8 O* S: j9 z. y1 J {, P4 F o9 ~1 X6 z
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
, N6 u$ D, Z+ t$ Y if(S.base==NULL)6 P% h9 K( |. D" V
{- d2 v9 X1 l* h9 `/ x. W: v
printf("动态分配内存失败!");, t+ I5 z8 |2 B% d
return -1;& l( w# F: o# U$ f2 W
}1 g# p1 v; T/ o% |* u# V, ~* b
S.top=S.base+S.size;, r) \0 j) D r- J5 v6 p
S.size+=APPEND_SIZE;4 a3 r/ i7 L; [' h
}
8 N$ h" v( n" H3 ?: _ *S.top=e;
# C! T9 `9 P) M2 n S.top++;
0 e! f! ~1 ~- V; A+ R1 q return 0;
1 M; B( B$ g) c4 ]6 A2 {}
n& P( s: R; ^% M/ n3 i4 z. S9 r. X) e2 f
int Pop(Stack &S,SNode &e)5 ^6 B8 t; Y" Z4 A3 e8 `
{
+ F- y" T+ _) V# G/ I if(S.top==S.base), u# Q: T) f: e$ e) U7 t) ~1 H
{
8 `* k1 L* m) a: z" N1 v4 d* ]' D printf("栈为空!");" x h& o4 v& \8 ?! z, V
return -1;
3 a% l1 I% o8 j% F* q }" x8 d* k2 @, g) n2 b
e=*(S.top-1);( P- t. [+ x8 S5 k- I
S.top--;
7 M; e4 O0 P$ x% ~ return 0;
5 W+ A% Z6 P. j( I F y7 h# t* m}
6 O. h6 z! `: H/ ~/ E8 E2 d% T2 ~7 r' M# @! i3 C* R) b' s/ k
char get_precede(char s,char c)" m3 v# A/ s E! n
{9 I3 Z ~/ J/ C; c$ D: _$ W
switch(s)& R. s8 ?2 Z- q( b* k& k+ B
{
% _) B0 q& \5 F" ~8 l case '+': " o9 e% _0 V7 D
case '-':3 e1 M3 P. N$ S
if(c=='+'||c=='-'), \, N' G: s5 a" y
return '>';* l H, |1 ~, r3 b% o# Y% f
else if(c=='*'||c=='/')
6 p0 b2 W7 r- o. {: _" y- J: I6 ^ return '<';
8 ?" H9 [& z5 Q- p; A6 I& t else if(c=='(')
1 n4 |3 z: f! f8 S* c return '<';3 X9 h* q+ k. R
else if(c==')')
; S3 `% L8 V: x* L. t1 ^$ T return '>';$ A+ ?4 J! V% a; u8 }) z* L5 s* q
else
8 f1 U: }/ r4 t$ J" o return '>';( n5 j" N# H: P! D8 C
case '*':1 s2 T% B9 G( I4 M0 P$ k! t
case '/':
" w9 p \5 B4 g$ X if(c=='+'||c=='-')2 a9 N2 C+ j& N. U4 J
return '>';
& j7 F9 J* u+ N) `+ V& S4 l else if(c=='*'||c=='/')1 W" S6 h6 u# m4 ~& W
return '>';
! \0 c% ]' A; C- l+ B8 t0 z" a+ t6 t else if(c=='(')
( j; w% _! M! D- s, O return '<';
0 J5 i. G3 A( y! I/ `# h else if(c==')')
/ M2 u; o& M" e! E% n$ B* o return '>';1 e0 P7 H: j8 V) i# A; d* _% J4 E
else" N; }; _. B N
return '>';
% K& q' s- R( k- j case '(':
# h' L7 j% L- k if(c=='+'||c=='-')
6 _8 [; r# a1 f! A& C$ L# b5 w return '<';
" y! B; E _7 d% h: p else if(c=='*'||c=='/')
! |0 g& R0 V+ f0 A return '<';, ?7 Z$ B$ p5 F
else if(c=='(')& ]& \5 ^3 y$ W1 P& T {) b
return '<';
/ U$ O/ V# i# ]- x; l( T, S else if(c==')')
6 q# Z& q$ n) W" i/ s( {8 D/ |- z return '=';
9 E$ B" ~; _8 Q/ ?& J else
8 G" X. y. X- p6 }/ m& C return 'E';
; v7 K/ v% o9 c3 r# T' D case ')':
3 d0 p/ w1 w2 {! U2 S5 k if(c=='+'||c=='-')
$ N% ?6 V @6 I+ w) G7 @4 g return '>';$ Y/ ]( [ i: u9 Y
else if(c=='*'||c=='/')
' t% r( O2 f) K$ \6 Z8 _# g return '>';
' { E/ M C7 v/ i& R' x: G4 K. b. X else if(c=='('), E& Y; R& z* ]; a* ?
return 'E';) O, M( y7 b8 J- n- q7 F0 z
else if(c==')')0 N1 j- k4 {+ g) w4 _
return '>';
+ G: l- g @! T9 V/ n else) ]# q/ S8 [+ k5 ]/ v$ F
return '>';$ p' s1 v& E: o, | L3 y# s
case '#':
, X4 ~7 D& }2 l. }- r g; d m if(c=='+'||c=='-')
7 f9 ?# Q2 `& n0 X return '<';
7 p4 j# a) K! U } x9 E/ r else if(c=='*'||c=='/')9 f; I4 J% |" Y2 `0 u" B
return '<';
) C, v# }% G N5 K: D- u1 ^: s else if(c=='('); l& k: @& a5 t+ Y3 y1 }
return '<';; F( V, b4 @! O( ~9 h* v
else if(c==')')& w. F$ }+ P1 [) x, |
return 'E';
( U" n, _" q2 G" Y; \1 j else
0 C# h& j3 V* w& E" b return '=';
% K0 ]/ N% Q' d. J0 Z default:
: u; A4 W9 b. k2 O break;
2 F5 o7 p0 @. l }. x* K D3 u2 o8 G& a
return 0;
7 d9 j! u) K* G9 b+ Z/ G, \# H! a}0 ]9 P4 w! f. o1 E) L' T6 j
7 F+ @5 H3 }- k
int isOpr(char c)
' o$ [$ F) a' I{
: I4 R3 Y* t* \5 U if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
' `# z3 @/ v5 L9 U( L return 0;
7 W+ k5 N/ V! c3 u else $ {( o, ?2 B4 a4 o
return 1;" |) B. r2 m4 n: y; q- w
}5 E; ?6 ^- w# @1 [" K( r0 R
% I% A- F; q6 T9 N
float operate(float x, char opr, float y)2 |, l/ c5 j7 [) t" {7 C2 ~
{' A0 M! k; W: M1 B+ A# u' c
float result;
+ R+ o/ B: J6 k H( }2 P& f: j switch (opr)
$ k {+ _- |; L6 g" d2 l {
' Q9 i1 e* m, K: N case '+':
2 p3 d( B: A% i. L! K result = x + y;
7 F* U$ n' l, S break;
/ X# h0 ~* }, ]$ d9 k. U! H) A case '-':
2 J Y# U4 W. @' X N V result = x - y;& G& u0 l2 \9 S {3 X) Y s
break;; c& S: T6 \7 A: P3 Y( N7 } k3 L
case '*':
9 }& Y! ~$ T* z' g2 x5 ^ result = x * y;2 t) v* f9 U& R: G) y% R
break;
2 ^* A8 c2 I: w W7 r- y5 i case '/': " J- }: _" M' A, H4 k4 D' s
if (y == 0)6 i' c" X: r# K
{ @) l* Z( @* q, w
printf("Divided by zero!\n");
) {1 }+ X7 e8 L$ I. q9 n return 0;" {, h5 B" ]- K2 P+ O
}9 A N( E0 {& x) @+ p
else
3 k( H r! Q' B5 |9 t {
; `. ^3 h/ p. F) z result = x / y;+ G1 m1 x5 `) |( f$ }& [
break;
9 `% U+ d" j: o0 Z8 G }
7 i; n/ I7 d t" _9 E default: / [2 M' A- O. D9 g; p# e
printf("Bad Input.\n"); ( E$ @! j: z& t
return 0;
: ]* Q; g- ~, o% h, | }% I+ K4 g' P e7 Z# x' S+ d
return result;8 N' z1 j6 X( L5 A5 d6 F, D
} 8 x9 c0 C- Q- j2 U
3 n9 ~9 c" [$ N4 N Rfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
E. y$ O5 Q& C+ H8 D& b* m{; Q: u' u3 d; z3 y
Stack optr,opnd;+ a6 w% q _1 a; l( W" V
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
, q* }5 ?1 N: f" n/ W' J3 p4 m char c;. @$ T1 W1 C: `4 V
char buf[16];. ]0 R3 p' k. |& t4 q
int i=0;
1 |# s% _0 d/ ?% @ ; k0 j9 _/ k! O5 y1 S
InitStack(optr); /*用于寄存运算符*/0 `$ [- d/ a7 d+ r. |3 B
InitStack(opnd); /*用于寄存操作数和计算结果*/2 o9 R2 s$ A! i! F
memset(buf,0,sizeof(buf));2 \1 R( m: F9 r+ j' C+ r! Y$ b: k3 I
2 Q( ] j/ V8 S9 u
printf("Enter your expression:");
$ J& Z5 } W6 [ \
& N# A& Q8 d/ ] opr_in.ch='#';
! Z# `. q& M) Y% b* f0 k1 z4 L* n Push(optr,opr_in); /*'#'入栈*/) _$ ?0 H$ q/ B J
GetTop(optr,opr_top);
) ?' ?" G4 d# H0 s2 Q/ m c=getchar();* k( x! d z% [* | q. A8 m
while(c!='='||opr_top.ch!='#') K6 g$ w& ^ _6 p. z$ R
{
$ W" c1 _" O5 i0 ? if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
' g2 w# D0 W7 a; S5 R {
' s: {& q2 B( K+ ?' } buf=c;
; Z! D) w2 P& h# \ i++;
& l. I4 C4 m6 n9 _ c=getchar();
) P, R+ ^/ ~9 z. N/ o }
8 j: ?& m/ @- m8 m4 t else /*是运算符*/) a1 W2 }* M! t. a
{2 c6 Q, B/ `1 `
buf='\0';
8 S8 c5 {7 L8 a4 [7 P if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/4 A F% [5 A3 Y1 T* S- U- w* @
{
9 k8 ]$ @, k6 U- E3 x opn_in.data=(float)atof(buf);6 r$ ^7 S% V5 Q+ Z2 I
Push(opnd,opn_in);2 L1 V' G# T1 b8 ~9 `9 Z3 ^
printf("opnd入栈:[%f]\n",opn_in.data);3 {/ c. M) k9 n; m. H; O
i=0;: I4 L. f0 L5 o/ y7 t
memset(buf,0,sizeof(buf));% a7 O8 g- a( |: U$ m* {$ H
}
, }: [, \6 E" x4 ^ opr_in.ch=c;
) V! C, f3 V9 Z& |4 V) a switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/; u8 ^# c3 o# _* X; w
{
$ x" S: h. [- t" b8 Z% Y% W case '<': /*优先级小于栈顶结点,则运算符入栈*/
) u6 \9 X8 N% T# J Push(optr,opr_in); w- _1 l6 e& x
printf("optr入栈:[%c]\n",opr_in.ch);
2 F7 \, X4 N( _' A% N0 d c=getchar();: [/ l' {! |' U) U# ^
break;
L5 d" ~0 b! d. D# \% S7 h case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
) A) E! G3 s# s2 U9 e: F5 C7 _! G Pop(optr,e);
9 ?& m {7 c9 ?* X# [% {3 m2 {# k7 k- K printf("optr出栈:去掉括号\n");
0 r: j3 O. e; ~ c=getchar();1 `$ b5 k, }- T+ ^
break;
+ b- f# z% F8 ?' t) f case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
4 Z* T {( K' v" M4 v Pop(optr,opr_t);/ F- [. x9 I7 _) J$ ]) v" t
printf("optr出栈:[%c]\n",opr_t.ch);5 H/ f4 Q' L% k# A8 a: I
if(Pop(opnd,b)<0)
3 z! _, S! v# \+ B2 U. F" a {
( o( n z0 L5 b+ B printf("Bad Input!\n");% O5 D. O; B+ ~' L7 _
fflush(stdin);
5 u4 u+ g- I# ^2 G# s" B* W! T8 q- C return -1;
7 P, q" b& i, W! c5 c' Z }1 `. [5 ]2 v! ~
printf("opnd出栈:[%f]\n",b.data);" `& M+ F! \0 n9 Y- _- v" P/ p
if(Pop(opnd,a)<0)
2 _3 B( R8 n a# f( M {
, _. f+ M! ]0 m7 a" d' a6 E# d3 i printf("Bad Input!\n");
4 g1 J; @8 C4 ]9 B. e6 p( a/ y fflush(stdin);) ~* y% A" U# A& o' C4 \" ^& p
return -1;
- ^' r/ U: O9 P5 c4 H- C# L& F }: Y/ A( I# n( m2 l; m
printf("opnd出栈:[%f]\n",a.data);: i% |' @( w2 e/ ]- o
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/5 Y& e0 G. I* A" l% x( g j
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
) b( i4 `7 f# o1 ^ printf("结果入栈:[%f]\n",opn_tmp.data);
! ]7 G$ p8 v3 V- J: _; X break;, v& @( {' c. A- H7 G) G* @9 e! V
}
) }. @9 l0 x) I* e, {7 K }
! l. C3 Q; ?* f) }! n GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
4 O- W7 l J8 X1 s3 g5 M }( J0 ?$ h( k: G
GetTop(opnd,opn_tmp);
$ R: T; D) _* {2 O DestroyStack(optr);& L0 K2 G' ?8 N7 z7 \. A- X
DestroyStack(opnd);; ^: |8 ?3 w( x
return opn_tmp.data;
! s9 v+ y" t, V! J) F. h}
/ |4 Z; Q* S8 ]5 X" r% b, b1 ^+ A' v6 |
char *killzero(char *res,float result)
M! d5 K" I, K{4 U9 A, d; S# ] w
int i;* N! u5 Q* I5 ~% |
' j- A, o6 o3 R+ p( j
sprintf(res,"%f",result);2 u. m( S( f# d% ?6 u' [3 f, [3 e
i=(int)strlen(res)-1;
$ A, r, Y. i2 ^2 W5 [ while(i&&res=='0')
3 d- P/ F+ k* A' D' ^; @ {
/ o1 Q3 S$ \0 e# p- f+ D res='\0';6 Z0 ?9 Z6 T) f* A
i--;
( B% _& W2 P+ }6 H& T K; n- r }8 ]: |$ r; a+ A @) n) C, [
if(res=='.'), Z! h- j# j; }& C3 \6 B
res='\0';- D- ~- `4 M* M1 p
return res;
/ K5 [! X5 {/ B5 _7 a' @4 }6 V}
2 K( p: F5 f) q. n" B: {$ F! y% i9 {# j; {) F l D' i
int main()! @" B. {4 e2 F& \& E4 S% p5 L; z
{
/ a W" P" i4 O$ [' Y char ch;
" V; a% ?+ v" x8 R char res[64];
/ B2 G% e1 X' u0 H float result;% C A4 M4 k/ ~" n' O" ~7 T; E
while(1)- a2 ]1 m( K& ~( S+ N) @
{* n; ~5 P6 E O9 }; q- p
result=compute();: k5 z) b0 W. i7 c$ V0 z
printf("\nThe result is:%s\n",killzero(res,result));+ B( U0 _$ H$ x5 i5 x
printf("Do you want to continue(y/n)?:") ;
n- w; e4 e/ w5 N! G# H3 _ ch=getch();
4 F2 _( W# |& D* S3 \ putchar(ch);
0 f B+ B0 r' x if(ch=='n'||ch=='N')
4 e- j) Q! e4 W, j7 z* }3 I) M8 L break;+ F. L2 A5 H% f4 a9 i
else5 n; C5 J/ z2 B
system("cls");. O8 |9 ~8 M& R* j& E& D; p d1 T$ l
}, w' I- q$ b; }* U$ v; t
return 0;
3 g' N/ D, ^( y6 Z& }( X}$ X; ^4 O; v, J4 j+ ^8 g
6 I9 T: t4 u* c8 m; Y( G
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|