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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.0 N1 E2 D" A# S1 U/ m8 V
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=, d) d# F, t" K2 W2 Y! e& G: \4 j
/**************表达式计算器************/
6 S- ^ r; ^" x2 I1 u0 T! D- m7 S#include <stdio.h>
* Y# t3 ^( d5 `. P( \#include <stdlib.h>
4 @& h4 p$ d5 a( v, {# Z$ B- `#include <string.h>
$ q- |* k* L3 A4 P" K7 K7 d#include <conio.h>7 J* r8 s0 E @8 J/ `
#include <malloc.h>/ ]3 s N. D+ \# ~* K
4 T5 |, {/ s* e5 `. K8 Y#define STACK_SIZE 1004 \# e' L* u, v
#define APPEND_SIZE 10
3 |: Y9 ^3 d0 B0 G5 g$ O3 I, ]% l) p( f6 e; P& H$ F
struct SNode{: e/ ~$ n1 B' H( M" [) ^
float data; /*存放操作数或者计算结果*/1 G: b* }. \' k5 F) i- G
char ch; /*存放运算符*/
# {# }; ~+ {; t6 i+ m5 z9 @};
2 Z9 O+ K( \" P( c3 d. k L
" ?/ X+ q5 t' l7 estruct Stack{
2 e: C- e7 ?# f4 ?! ~% d; @ SNode *top;
9 l! Q5 y9 ?! l& M SNode *base;
. r: v5 E3 Z' i( v& h6 F int size;9 {: N1 j5 }4 N1 J2 M+ Z, I7 M
};
3 F+ h& C; ~0 C! G( ?& D2 ~0 Z' I( m0 |% ?5 e# n4 M: J
/*栈操作函数*/7 B- I, N ]( m% C/ x0 k
int InitStack(Stack &S); /*创建栈*/3 M5 y9 G& }- T8 N
int DestroyStack(Stack &S); /*销毁栈*/8 Q( N$ z3 L0 w+ E" P. J3 b
int ClearStack(Stack &S); /*清空栈*/
% p$ ~ b6 e9 ?4 Mint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
1 j1 u" Y5 F2 |$ p$ N" J! [int Push(Stack &S,SNode e); /*将结点e压入栈*/# A6 j2 j' C0 U) Z
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/7 {1 K( F$ q; R$ J9 A
a; M- A0 A3 n. ^8 i- i
/*表达式计算器相关函数*/
$ Q& ^3 ^; T* |! zchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
+ u5 C& M! w& bint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/8 G) K G7 j: F9 v$ @- g8 M# h: j- z
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/ E8 A- C9 f3 {+ ]5 x
float compute(); /*表达式结算器主函数*/; L0 Y0 c- K( [: Q1 G
char *killzero(float result); /*去掉结果后面的0*/
F1 ?& R3 v* y# x3 H+ e( ^, }4 ~7 x" d1 L' U; K! g8 y
int InitStack(Stack &S)
% z4 Q% l$ E: H J. n{7 ^) Z+ G, f; r5 Z0 Q& h- n
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
" T. ]% `3 }6 Y6 e6 k* n) N8 E3 Q if(S.base==NULL)
, m5 R- I( R Z ?0 d# Z {3 E3 o* h; q" w; L; ~* J2 W
printf("动态分配内存失败!");
1 u# [, E* P3 e' j return -1;, m9 C5 j5 @1 l) M7 Z0 @+ F) R
}$ [8 K! ^9 P2 g: H5 T) d
S.top=S.base;( K- L& t9 W$ F r4 t+ Q3 ^
S.size=STACK_SIZE;
" E6 P: C7 i* F% d& u( w& ] return 0;
, P; J% k) t" P: _0 r}
: j* P I( W. q7 e" H- Q! i) i' @8 j4 z) s, N$ ?
int DestroyStack(Stack &S)) n8 e% r% ]- i5 T. Z4 \' K* s: S
{
- V( R/ J' E/ o8 U4 D; q r free(S.base);2 F0 L" S% @) i4 [1 H9 K
return 0;7 j8 ?: Q6 H+ ^9 }- F
}( H! |+ F. x1 ]7 r' D
Q. P5 O Y% L8 `int ClearStack(Stack &S)4 h" p( _% y3 m: K8 |
{0 t S, s$ X; u% t& u
S.top=S.base;; X; H' g% R7 G X( `$ }- A) R
return 0;& S6 V, i; E9 w2 M8 T b
}
( H5 U8 _3 z1 G( R- J. }& D. _9 K2 H& k' R2 M' U' x3 v4 T; C
int GetTop(Stack S,SNode &e)
# }) _# |# Y% [0 b- z& A{* }9 E1 G3 T& W1 n: [
if(S.top==S.base)
' n: Z) X+ e5 q. W {" T- J) K9 u2 W' H/ p
printf("栈以为空!");4 h/ k# v5 ]/ B* `' m. l# W' \
return -1;+ m8 O/ r- u) [0 a0 W! m' G; \
}
, U4 ~" Z G7 r% Q; e e=*(S.top-1);" ]5 b5 M6 h2 B5 b2 C
return 0;! r3 I$ e. Q. l7 n( c( M! k; E3 I* _
}
3 D' B7 G0 B5 i; E
) F1 S/ w! s& e' ?- r. oint Push(Stack &S,SNode e)3 W( j. N$ S9 X
{$ p0 d8 u& [" n+ X$ g. _ s
if(S.top-S.base>=S.size)2 G \8 J, a- P
{
5 k$ T; H/ W7 T8 y S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); r: F9 E0 \" _/ ^" S
if(S.base==NULL)
9 S& k5 E0 N8 F& ^1 k7 M5 v- N {
" R- q7 |4 p2 i3 {/ }0 R. j printf("动态分配内存失败!");
: k/ j9 _9 r2 ]5 D3 |, k return -1;) j- U! k3 k% r
}) O4 v0 L: h5 O* u) v$ A# C3 B
S.top=S.base+S.size;0 z& U/ |4 _$ t8 g. Z% G! v9 A
S.size+=APPEND_SIZE;
9 y. x6 n; {* p6 T9 k! m) e4 Y }
: f& T8 e8 H4 S *S.top=e;
' L7 v$ z" u5 B& y7 M Z S.top++;
1 ~% Y1 L9 x- c' a# \: X3 W5 | return 0;
& g- q. X: b0 H% v}
! l$ @6 i7 d: I; Q- R, F" l
1 ]! [/ o; m. ^' r3 ~int Pop(Stack &S,SNode &e)
1 Z1 L- k* N" z/ S{7 j; G& {5 D- a: R
if(S.top==S.base)
. ]& I! F4 y" m& R! \ {. o# r& m$ \. t
printf("栈为空!");( ^9 }0 M- f, b; }1 U9 D( M
return -1;9 i, E$ u0 `" d, e7 m' {
}) K8 o/ Y: b& K- a- F
e=*(S.top-1);
- X8 O8 R4 ?, M S.top--;6 g/ h" c; r+ C F
return 0;, Q; f6 i- |# y$ w
}
2 W. Z* C6 S; z& I1 T: m0 b; f8 K
- l% g4 K- a) J$ K. rchar get_precede(char s,char c)
2 z$ W1 Z5 z7 u% _ @/ S{
% o" m" d. d: l l switch(s)
2 a2 [7 q. H# A9 ~8 { {0 W3 [9 a! p/ B, @
case '+':
7 r2 a" y- Q6 {- B% v case '-':3 f" z( L' D$ L+ a4 u' q
if(c=='+'||c=='-') v+ d; L6 F6 b2 o4 W; G! N0 r
return '>';( r% p1 y! j$ _$ e9 R
else if(c=='*'||c=='/'): d( f3 z8 p) r( S+ g, G
return '<';
/ \* y& q' j' F+ u else if(c=='(') D4 a/ x4 m6 L+ J0 B2 i2 Q
return '<';
: @0 `& f5 g- _4 w2 ]1 d else if(c==')')
9 v3 v# [- z% y) K: R8 {1 W# S return '>';9 X9 F [( g! E; M; g' E
else & ~% l3 J0 |$ \3 B" q7 b3 F" k+ b
return '>';7 L- E4 T6 P7 d5 E& d! l
case '*':
8 z0 \& O, @6 H8 l: j9 z6 y) ~ case '/':/ S8 D4 k3 Q5 V7 q* k7 s
if(c=='+'||c=='-')2 D! f b" [: N! z6 X9 {
return '>';
( N R( V. M0 L( D$ Z- E* m- W else if(c=='*'||c=='/')( G9 Q; p0 C" f5 D6 u/ m8 i* q5 t
return '>';9 X9 N* G& W+ i0 Y
else if(c=='(')4 r" s, [0 B: O% }
return '<';0 H9 j# Q1 X% B; Q+ b
else if(c==')')
8 y' ~( w' g. \( p3 l return '>';" J9 y& o# m' {0 V: r# m' p* \
else
* @+ {* h2 L$ x2 T return '>';
- p. D8 Z+ q: h8 V. x$ h case '(':1 V" [5 `% N- i: Y: p/ d2 _- b
if(c=='+'||c=='-')1 U/ S" n. }. M3 p( h- H. }% k$ V# v
return '<';
! ]6 A8 y% V% x/ B+ k else if(c=='*'||c=='/')0 n3 X; Z( f q. N+ U$ }" I) T* `
return '<';8 O: b6 h/ s, J, P2 o& l; b# n
else if(c=='(')
, h4 ^7 X4 i0 [8 b( U3 m return '<';
8 u1 i! U! k8 i1 [/ O& T else if(c==')')
; A" t1 j) M, s; I0 z1 j return '=';
& ?# p$ k- q, L! k# ~- k0 g else
2 D( _0 K* e( ? return 'E';3 { P' \# a0 D! v4 Y
case ')':
8 M9 [3 B$ P' {! D3 F* Y( s# ] if(c=='+'||c=='-')
q! \1 E" M' ~ ?" Y" ` return '>';
: f9 U, v' O/ J3 M8 Y9 W else if(c=='*'||c=='/'), M5 ^& t0 W' X, {0 d0 H
return '>';/ N7 n# U: n( I+ o% X$ y
else if(c=='(')3 c6 S+ ^# K: b0 B" g& J6 W4 `
return 'E';
* ~ a3 g/ j5 n8 F# I else if(c==')')
5 A1 i# y5 p5 q& m return '>';
4 r$ n4 ^7 }$ M) M) `9 r! D/ q else
) @0 Q" A6 {9 `3 i1 M i, W5 _ return '>';6 j. G/ m; K! r* f8 P
case '#':; X9 a4 \0 Z0 u0 [/ u3 C
if(c=='+'||c=='-')
& V1 K) y0 g3 S& x: K' V! { return '<';
/ t# I2 z6 X3 x1 ] else if(c=='*'||c=='/')& C! Z4 O3 w( N. a; J; V
return '<';
9 X9 V8 i# t- y u- S else if(c=='(')5 _. A1 U/ m( q
return '<';
7 i8 J3 g3 ~8 Z' |. C% I b else if(c==')')
3 U$ F' O+ o# h: V: d return 'E';
% I$ H6 [% f$ v1 E- [3 \ else
3 o. b& q+ p$ o' y+ ]5 B2 K return '=';) }) N9 o$ M9 Q, f! D P8 d7 q
default:
; c' E9 I- ^% Y9 B/ P3 z. k2 N8 i0 b$ | break;
& Q: m2 E6 B0 t$ s! ]8 F }
* p8 }. V- N) u return 0; # Z( q% B6 Y9 m
}( }4 y/ R0 Q- B4 Y5 t
6 [4 ^# V# n( B+ P% O; l; C& oint isOpr(char c)
3 r+ {' X9 {0 I. S{: x$ O- C( \/ s6 G: i3 L- v
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
4 P7 `2 F1 P) {/ @ return 0;3 C# ]/ S" @5 o8 g2 q* v+ V
else $ C2 ~6 `, V6 t1 l4 T7 S3 g
return 1;
7 u" t: D; X& M) h}8 N+ Q& B: B- ~3 D# x) K
3 e3 W* j6 ~/ @8 O( L* L7 W
float operate(float x, char opr, float y)
# c* n3 A% V, E8 f5 z+ |{
4 W( J% b8 {, |1 b9 ?6 }# R float result;# E1 K; @: ~9 K/ p
switch (opr)
3 a; V8 w# P5 Q" J4 X {2 K. F% N, i8 I/ P& ~
case '+': H, Q V- W1 z" ^& S1 p
result = x + y;
1 z% @- D) o$ d# ~- y break;
* t" ~1 g" ]0 _) L8 s$ M6 x) [4 p case '-':
6 g' K) X* X5 g% H result = x - y;' t0 P$ n6 s7 ~
break;
4 m4 O, `$ |+ Q! { case '*':
; f1 R% [, b& L result = x * y;$ `( |! n' n! o/ J% i( d
break;
4 I& z6 a% a( [. |/ \" l case '/': 6 C. a; }4 f4 V8 c
if (y == 0)" i1 P# {% b7 O) ^/ @% ~4 s
{
G- k4 r0 }/ Q+ y) i# m printf("Divided by zero!\n");/ y0 S3 d% ?7 N9 m
return 0;
* q8 a% Y y3 j0 I1 C5 x( \ }
4 g- C+ H7 F; s: P else+ Q2 a$ n% B$ F V
{
5 s+ U) [# R3 N result = x / y;
: ]* ]* x% \# w! r) V6 o* ] break;! U# ]9 z5 I% f" T/ t. h
}
* C# _6 X6 D! d" b( `5 n$ I% G default: 0 o2 f3 {, X: s& F, p& O
printf("Bad Input.\n"); 8 M- d0 A! Z9 a
return 0;
" M; Z8 r* S3 c2 a }/ G$ k$ d, u1 Q# S6 {; A/ w- R
return result;% E' ^8 r4 n( ^( \
}
' H: }* g5 O# A$ H9 W j. P7 I+ ]/ X' W$ a- p& s
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
9 D. K0 I, [- U: D b! X{" e% i" h& d' _1 O
Stack optr,opnd;) [$ Y/ a1 E8 d# B+ |7 o$ L
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
/ b/ M) c) V+ y" E5 l char c;
; p1 s% T0 n% \2 j' O/ X char buf[16];1 v( a% ^) q! C
int i=0;" I+ _# Y6 h: T! I) J C2 v
5 W$ ?0 f N: |: i3 P9 j InitStack(optr); /*用于寄存运算符*/
% }1 I3 Z) W g! j' N% o InitStack(opnd); /*用于寄存操作数和计算结果*/
' r* k) B5 g% P memset(buf,0,sizeof(buf));
" z$ O. _8 h+ H# t$ t + p/ {8 W' f/ w+ O. a
printf("Enter your expression:");/ h0 T" y, j- {* }, ~
T/ V. g* `0 L; q! O
opr_in.ch='#';
7 ~, p9 h# \5 V# |8 m# K O Push(optr,opr_in); /*'#'入栈*/( U5 E7 |5 r% }3 g
GetTop(optr,opr_top);* w% `7 q a7 q1 ~$ |
c=getchar();; P& Q/ A/ s% t
while(c!='='||opr_top.ch!='#'); w, v. A) \: e% F* _% i
{ h0 Y) o1 j" ?9 D3 P$ R; f: ]% K
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/ |) U6 w7 ?% V& N! K! }
{
4 I: {7 u! t' R) r: \: s9 O buf=c;5 w. U* J+ ^2 k, i
i++;
7 C/ N2 Q5 L, x c=getchar();
" ]$ Y8 b: ~! O! v }, S+ \1 d0 D8 e
else /*是运算符*/
' y* \. i( e ~ o+ P/ W {
8 J2 l+ L* H9 N! R, @ buf='\0';
) X* k6 z7 L7 ]6 g! E if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
; L6 H( n5 C" b& z- E# F {. c6 Z3 s% [6 [
opn_in.data=(float)atof(buf);7 `) ^7 f- B: E; m& i' |
Push(opnd,opn_in);
1 T. P, C2 A4 ]8 [! `; { printf("opnd入栈:[%f]\n",opn_in.data);" u9 f' B6 n* Q* u
i=0;5 ~5 N; u% S+ y7 f/ {; `+ Z: y
memset(buf,0,sizeof(buf));
( q' u/ N) C9 B }
9 v4 v8 P1 y" @- x opr_in.ch=c;
. ]' y; r& Q0 J& t) H1 J switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/3 C* t& s3 K4 D" ?& X& U# j
{
. V) v- ~5 ]0 l case '<': /*优先级小于栈顶结点,则运算符入栈*/
& `- X8 n# b# o, F% Q Push(optr,opr_in);8 H! w# Q! k5 @
printf("optr入栈:[%c]\n",opr_in.ch);
/ u4 P4 c6 J1 x4 G c=getchar();
- O( i+ x- L8 Q$ k0 p2 K break;
5 y1 ^/ T; T( M case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
0 H* E- v: a1 u" y$ B Pop(optr,e);2 I! G3 O Q$ w( Y) d2 P6 F' y
printf("optr出栈:去掉括号\n");
/ l$ r9 m0 J5 s- Y c=getchar();& ]% ]) J) C+ S, S" l, |9 g. r
break;
" u* f& g9 J% P: \6 G# k case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/! ?: g) h/ M9 m$ G
Pop(optr,opr_t);. l/ c- h% w6 d6 _' R4 P
printf("optr出栈:[%c]\n",opr_t.ch);
7 r* Y [: w: e3 G if(Pop(opnd,b)<0)
7 l9 M$ s9 I" s: ^4 k {
8 P7 w% l4 m1 l0 G' ^ printf("Bad Input!\n"); N ?* ]8 Z( M8 l8 |9 @5 F2 n, i" e
fflush(stdin);8 B5 Q# R' O/ {+ y5 v" r
return -1;+ p- C) n# L2 }& {0 L2 c
}
, m0 g/ e1 S2 `( ?* [8 _ printf("opnd出栈:[%f]\n",b.data);( O0 L9 r' |# S5 Q" B. T1 e- g& h
if(Pop(opnd,a)<0)
) Z' z) E( r7 t% B# z+ F" u {
# h$ h. G! {, G printf("Bad Input!\n");; A! b$ B3 A! d
fflush(stdin);
. F+ O) m/ U( S+ { p/ ^- W return -1;
) g e6 s0 C" ~$ @3 f' s- H }
0 E& l/ F: B2 N! w$ r printf("opnd出栈:[%f]\n",a.data);8 ^5 x* p+ l) X6 m1 }- i3 h3 }
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/. Z3 @) H6 w" _, {; r, k
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/ ]5 R, Q0 g: o+ C" l
printf("结果入栈:[%f]\n",opn_tmp.data);
' f+ m4 j- o+ K: W _$ o2 i! S* M( s break;
, [) F7 A6 p% r' R# V4 Y }
* K- T; ~; t4 G6 ^6 f } i3 d% e; Y) l1 U
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ + l4 C# o0 [4 d0 q3 I) L" Q
}4 t6 M6 ^6 U) D" h) v
GetTop(opnd,opn_tmp);
, ^* c1 O) R. V8 L2 @1 X DestroyStack(optr);
: X2 x$ ?/ T% I; q& ? DestroyStack(opnd);
. c5 r, p0 \7 o$ I1 D. X return opn_tmp.data;
7 o" g- ? Q+ \$ G}
7 W, c: w; j* t5 `1 D& U4 w9 H( i% J$ }2 P- l V
char *killzero(char *res,float result)
; B! o4 s4 o: ~4 I4 m4 j |) s' J# O, q) z7 u{
, p7 T Z& ~; `+ M. p1 t5 p int i;$ i$ T! U' y1 o* f7 D* L
9 g7 I! |6 @/ C, P2 f# z4 _# p& [ sprintf(res,"%f",result);9 z. M6 |" ]4 K& e& @* m
i=(int)strlen(res)-1;1 E$ O( G. O5 n% D) _2 q+ s
while(i&&res=='0')
# f( Z; C, r, W8 D9 }/ z {
: p l' w/ B) S8 A res='\0';
1 O V1 K( d) G i--;
9 e! @2 C: ^( a- u6 m* g }
! x7 B+ d9 L+ ^* t if(res=='.')
i2 c# y9 d( N6 Y- q* D res='\0';5 g4 |+ M8 Q, a: B6 E9 `- e1 {0 j
return res;0 Z, Z, l, J0 E9 f
} ~: O1 o. g E! g8 M H$ t
. }% [( d+ O1 b. {, Fint main()0 V5 V2 P+ Y4 K0 w1 B8 u$ O0 V% V
{
8 t- M4 }- F9 E& o8 @6 k char ch;2 c0 N( E. j f, k3 D
char res[64];
7 o8 q9 Q% w$ D$ S- I float result;
8 b3 _0 y: F- H# x7 R! E while(1)
- O a( I6 A1 V) h8 ~* h {
7 P6 ]8 D7 b* J& h- g- e result=compute();
9 m' T/ j! I) s v; W# I printf("\nThe result is:%s\n",killzero(res,result));
: q4 y& U& x8 W6 }* g- v- n0 C printf("Do you want to continue(y/n)?:") ;
! x) u8 I, S0 a; V8 Z8 \: | ch=getch();
4 Z; Q& j" E4 g3 p+ Q W7 k putchar(ch);
4 Q( |) a' w5 @9 ^4 k3 y if(ch=='n'||ch=='N')1 B# L- p$ f% Q# k' }+ Z. o
break;( ~1 |) X, l3 P6 O1 d" F
else! x1 \; ~" ]* Q* e( u3 b) d: E
system("cls");0 n2 x; \7 P) C( P d, G
}
9 h9 a/ t/ b" r return 0;
4 T6 ]' T2 R; g}( f7 B% ?' f" @0 E, ~
& G0 J8 h; S a% H) l6 q
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|