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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的., P/ \5 O4 O2 t5 ]( z
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=8 X5 e! ?8 E: r
/**************表达式计算器************/; \2 | U6 U! {: u$ g$ _- Q
#include <stdio.h>
' |4 K# @7 R8 B#include <stdlib.h>. Z3 p \( T) o- i& ^, f D
#include <string.h>2 U; y6 p4 U/ o7 x4 k
#include <conio.h>) t* F5 ^) o: S; t
#include <malloc.h>2 i" J+ k' m+ j+ c G* F3 D
8 Z9 N1 a \0 q d$ f5 }" f& A) }1 F* L#define STACK_SIZE 100$ j( ^6 ~0 ?' K" L, L4 \! L# J
#define APPEND_SIZE 10
9 {/ e2 G0 _+ ?: X- G; s, ?/ G4 O- l/ H/ Y+ y
struct SNode{2 ]5 J! v( I, r, M2 Y$ H
float data; /*存放操作数或者计算结果*/
4 t' D: X z: |8 g+ ` char ch; /*存放运算符*// N7 q a+ ?2 d
};% Z/ i; ^. G3 G5 k0 q) ~9 k p! t
( P- {2 s* u/ K1 u
struct Stack{
' r* d0 f/ ~ `6 ~" r, s& c( L* S SNode *top;) ]1 u8 g) \: Z Y% O f9 i
SNode *base;9 q: ` p! n* C" E
int size;, U# l: h! h' g6 h6 V" a; Q. C
};/ m: g z i$ E+ U
1 N- d/ |# _: q/ G8 q3 B
/*栈操作函数*/# M, a/ F, J. K8 W6 ~
int InitStack(Stack &S); /*创建栈*/7 ?" c8 h% Q. M
int DestroyStack(Stack &S); /*销毁栈*/
! i" W. I' H2 ^9 Z* D$ nint ClearStack(Stack &S); /*清空栈*/5 f/ S& y5 }3 _ H! k7 J* u7 c
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/! n4 Z% K" S2 n- T1 a/ T# A5 E# h0 D
int Push(Stack &S,SNode e); /*将结点e压入栈*/
& S$ d) F/ i8 y2 H- Q6 mint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
6 J) h4 r3 f( [. B- N
% J6 D! u0 B1 i1 {: x7 g/*表达式计算器相关函数*/
$ n7 N# N+ K/ q0 n' D0 A. J, }char get_precede(char s,char c); /*判断运算符s和c的优先级*/
( E5 k& Z# t# N1 V- K2 qint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/) W7 n% p; s9 d6 ^
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/: N0 j% K# c& Y( o5 v' V2 @
float compute(); /*表达式结算器主函数*/0 f$ L2 m8 I( L1 }3 o/ U9 d. I% Y
char *killzero(float result); /*去掉结果后面的0*/ ( u& m/ }) p$ \6 `; f* P. e+ v
: p! q% E- p s
int InitStack(Stack &S)8 {/ X( A- y9 |# Y8 N, z
{
; s: n# n( Q8 N8 B7 f S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
3 X' ~6 U# i* \8 ]% C* I if(S.base==NULL)
3 x) ]' P: E/ W6 W( D {
- r& t; W: Q! @3 C printf("动态分配内存失败!");# O' D. T+ N v+ y
return -1;, d" @/ H; t- h
}
7 Z% S5 F8 H4 c S.top=S.base;
/ R5 g1 q; y+ m' e S.size=STACK_SIZE;
/ n; h/ \& r6 ]; A9 g return 0;
- s& u/ H' k0 G3 a6 z9 D}+ G1 |! b+ P% D0 K% Y9 a5 w
`5 d, p0 D6 _, @5 r; E* Aint DestroyStack(Stack &S)* z7 a3 r% r3 H) {; K9 ]* Y# X
{) V- w+ t# z0 K; T, P" ~( h
free(S.base);6 T9 L: R' ?- G0 U$ s
return 0;
2 I+ T& L2 h+ F}
8 Q0 l! b( {1 B9 `4 h
7 r8 q* j0 [6 F8 u$ ?int ClearStack(Stack &S)
5 u: d( k' D/ b. x{
. r/ }7 c' b8 C/ R: D; v S.top=S.base;
6 k! |0 V+ L2 e5 |6 k9 j7 V8 m; D+ F return 0;8 o, I9 h# g0 `8 w
}
7 A% F( n P$ {2 f' @
0 }4 h% y- F8 n* c2 I6 Gint GetTop(Stack S,SNode &e)
, V1 E }! V0 T: M1 G/ C{
( s2 _, ~ |. } if(S.top==S.base)5 v( V! f1 Y, x
{# K6 C$ j* r) I L( t2 v
printf("栈以为空!");
4 R. A% U, m+ l3 c) X return -1;
6 \) p* r# g" q9 H+ i0 o5 \ }
8 g z7 B/ [ H. L z e=*(S.top-1);: |. z4 S3 K I5 G
return 0;, Z2 Q, J8 Q; y# i4 f) d D
}
2 D, I& D7 ~7 l2 l$ u, E5 m1 u, Q6 ~- U9 a$ l' ~( A: o( m+ f& Q
int Push(Stack &S,SNode e)
# t0 x. A: H" l{
0 B) M1 C' D8 w2 u8 V; }# r if(S.top-S.base>=S.size)) `0 W3 a$ R# S& W; Y4 f
{
c) Y4 S/ l- ? i0 _' W S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));: n& m- s1 K: H0 P
if(S.base==NULL)
! ^' Y/ ?$ }% E2 G! X {5 ^$ f( @$ }) {
printf("动态分配内存失败!");% `! m6 e* k, b. {
return -1;; z0 I5 W9 h9 q# G
}' a/ p& V0 u8 O- K
S.top=S.base+S.size;1 E8 D0 A8 X5 |( M" G
S.size+=APPEND_SIZE;' C& ^! x6 a- |$ i v2 T
}
: ^: u) T8 d+ d *S.top=e;3 B" R( F0 Q, J$ I' o5 M
S.top++;; r' ^% C6 e" J- t! n/ h
return 0;' v2 P! P2 H, B6 k$ E7 ^
}* o! O7 c# h- f6 s& }
$ z7 h" }( h! R: r
int Pop(Stack &S,SNode &e)
+ }% H5 D7 L- _8 A& ^& d{
7 E# S+ _/ q- J- u; j4 P if(S.top==S.base)
) k; _2 C+ ~1 m! z7 y" T+ j8 D {
! G# y e6 K3 M5 C/ ^6 T printf("栈为空!");
% ], c% R4 H8 o& C3 M return -1;& O- t* X4 D! \2 e, e( I3 @
}
2 D1 _; g9 x/ g& T: u/ p e=*(S.top-1);
: d. _5 k& b/ m$ p' j d S.top--;( I! d5 p6 K5 H2 {" z/ ?4 ^
return 0;
( ]" @1 L3 u" X9 L$ T" Q; a1 h+ E}
/ \8 I. e$ i: |* @0 }- a$ l4 Z
( Y- w" K& F$ q Y a* Pchar get_precede(char s,char c): A4 {8 p' Z% M; n
{
+ N+ |. |* |. ~7 B; F+ z switch(s): K/ c: w( e( N3 J7 `
{: Q' d! M8 T5 a+ P! L* h
case '+':
* c* P' o& {7 t4 @$ c case '-':
H! m+ s8 V6 y% h4 u) y if(c=='+'||c=='-')
7 M+ r$ ?: @/ L8 ? return '>';
) H" g+ \2 M |! ~ else if(c=='*'||c=='/')! Z4 d, X# N! P9 G# `' m) r
return '<';
1 E6 B" [* P1 u4 `3 P/ l else if(c=='(')+ }; v* w Q4 B* l# ?8 [& E! H2 S
return '<';5 P: h3 X1 R5 k
else if(c==')')' _2 r0 U; j b$ o# v- C8 k' W
return '>';7 }" S2 {! N! t2 b) [
else * O/ g& s" ]# r8 T3 T+ C7 O
return '>';$ E2 }) {0 i' n) y
case '*':
* X- u! h b7 [; B, w2 S1 j, E case '/':$ S N+ M5 e) c! y) Z w, R
if(c=='+'||c=='-')
/ U9 n0 `% F9 a. l' h return '>';+ L. G" t7 A! n4 a) E) i3 a
else if(c=='*'||c=='/')
6 C7 h- _; ^; |6 z9 Y/ x7 [8 Q return '>';
" N$ V5 ~/ S8 A/ M7 q4 p ^2 Q1 z/ _ else if(c=='(')
6 A1 X5 a& v4 D4 L" F! s return '<';
, t* q, p6 P5 ~ }" @- E else if(c==')')3 w5 R3 d' e) m& f n, J% ^
return '>';
0 y6 ^! \/ ?" g$ h# W* D+ o else7 a4 b1 T+ N+ C
return '>';5 R+ ^# Q; F$ [, |: z% n4 H2 `3 G, j
case '(':
* k, w# v) Y4 W0 S" x0 W- h if(c=='+'||c=='-')
( F5 w7 E4 o+ G" @ return '<';
6 l+ E8 z$ {9 F8 g7 M else if(c=='*'||c=='/')
% u% w! V/ i: e return '<';
, o+ N' h/ W4 G& x! d1 _" E else if(c=='(')! g! Q1 B& p- i- T5 Q2 R4 A1 w
return '<';; {: w9 g K# P0 b
else if(c==')')% k' ^! u& V$ V+ _! [& l4 ~
return '=';5 ~3 g. O" F( M1 p' O$ q
else
1 g3 f. ^* W7 ~- s8 ?1 ]; r2 Y6 M return 'E';
+ T( g% o" T6 l! s. T/ u case ')':
- N* a |( E+ W0 E, E9 F$ e/ A if(c=='+'||c=='-')* |$ X" f: c6 N2 A! X9 i* M
return '>';
, O# y: L) A- J$ h: G3 [ else if(c=='*'||c=='/')! E6 g5 k1 k% {' J1 b2 {
return '>';0 I. ^! P0 C# I4 J
else if(c=='(')
+ Q! i4 t$ j! l8 d return 'E';! o9 e% \' A( S2 n& ^" T$ N5 n
else if(c==')')' e& r% ]" V' e* R% [
return '>';( M# ]* f* x; r: s: k5 G
else
; Y5 b: H/ V$ L a2 F return '>';
, l& G4 u9 S5 d d5 e8 D4 k case '#':
. n# `, i* {+ L' {# _$ ~ if(c=='+'||c=='-'): Q1 v3 R) K* c- z: Y
return '<';+ j! a. S5 L/ o; v4 c: r3 S# ~% w
else if(c=='*'||c=='/')
; L( G( a' x6 Q1 O# A return '<';
0 k! Z3 Q: _/ r. G) r& e else if(c=='(')
, }6 @/ J- X( u! i- B$ K8 E return '<';; H4 h4 h0 Y! F5 K
else if(c==')')
7 n! X, r. T6 ^' d b return 'E';' S+ R; z, C/ h: \) p4 F+ F
else
3 E- G( F: L8 F& T return '=';
- H$ R3 L9 r5 r K3 ? default:0 W2 g* ]* X' b; |& h
break;+ O0 q W/ ?. L8 P* b3 Z k* r3 f
}
! j% v- D; o# u6 Z0 M return 0; 8 c# z6 u# D0 K8 o
}4 Z; y' f' y0 n o, w% l
0 Y: X5 G. A$ g9 }2 y9 }$ Uint isOpr(char c)
, S5 e6 t; G! V; v{1 Y3 f0 ]* v: h1 m/ Y% T5 X
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')+ y, Y* G8 X; Q. X: [2 N
return 0;
% l: c A$ H! E/ B) p1 K else " b6 D, Y2 z' r. K2 G6 ^
return 1;# f( z3 x& {6 z" M5 ^3 }: c( G! H
}6 c7 A4 m" m2 E3 Y# C
_% y2 D% u, {+ }
float operate(float x, char opr, float y)- T/ C& @0 b/ @+ }! b t
{3 @! E, A8 z4 Q. w2 G; A
float result;
: m8 b/ L' r9 G8 W0 g7 f1 F! Q switch (opr)
$ Y- J6 U8 e" S' C! U' x- E2 o {3 \/ K, ^ U" d1 N
case '+':
9 G B4 v( j! S- _0 H result = x + y;6 g* ~% K( l" r: m
break;9 l: C: ~) D1 u2 e. i/ j p: P
case '-':
% q/ d$ L' m$ R, X: o result = x - y;+ W" U E' V6 l5 J' [
break;4 u! O8 @/ L0 F- [1 {/ B
case '*':
1 r: Q$ z; Q. k, w+ U2 O result = x * y;
/ Q" s# [6 [- @1 _5 q0 q: C1 E break;( i. x ~0 p+ F# @
case '/':
4 y' M5 `% ]1 Z. x5 g' ~1 Q: P if (y == 0)+ x6 u+ X R5 f0 Y+ X% ?
{
/ `. s# A6 d& w printf("Divided by zero!\n");
0 B# \+ r3 E; Y' ~! |# [$ u, [/ W2 I return 0;
8 k* N7 S: V$ f }
; Q/ p& X/ S& Z! W1 ~- R else
2 B( S; U0 w h( l3 d1 q* O {/ N2 s+ ]- W' Q) f
result = x / y;
+ Z9 |- w. ?; v. p5 P4 [# C- b1 H break;
6 k8 k3 S8 M; u# _2 m" Z }2 V; L$ s A% h
default: * e; q6 m) ]/ z7 J2 {% j8 ~) [8 m0 C2 _
printf("Bad Input.\n"); ( e& B% g1 e- q
return 0;+ I2 u+ G& _, K( d
}2 T4 L4 x: ]# s
return result; r- I. W+ L8 s9 ^1 d' M
}
6 q+ `# Z' w5 E. H5 Y4 o; L, I! a/ @/ G- ]0 D
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
8 o7 L h- l3 Y U7 i* D2 b7 z0 |{6 U# c4 N' { _1 M# y( Q
Stack optr,opnd;
' Q5 X7 M5 L- Y struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;" m5 z3 w0 B% S1 S7 b
char c;4 W- M/ B" T1 N9 U' g( B
char buf[16];( O, u5 `4 o1 T5 t! {5 o
int i=0;4 r. U3 _; q2 N9 a
7 H5 L9 ?# l, b" W1 q2 c. {! K- e
InitStack(optr); /*用于寄存运算符*/
& h3 ]- p1 j8 V8 N2 I7 ` InitStack(opnd); /*用于寄存操作数和计算结果*/+ v; X- G' K0 `% o" n
memset(buf,0,sizeof(buf));
& r' i5 v$ D8 L1 }0 R, J 0 X# X* j2 f& S {, k/ K. ]
printf("Enter your expression:");
9 ~6 A; p4 K( n$ p; u , P* `" I. ^7 B$ r, A
opr_in.ch='#';
1 R4 k& S% ]: p Push(optr,opr_in); /*'#'入栈*/- }) A0 n) }# |+ k
GetTop(optr,opr_top);" N3 N* @4 v0 [* r6 n
c=getchar();' K/ w4 U ~1 L1 q7 F' r
while(c!='='||opr_top.ch!='#')
" g' h3 j8 I. C; f/ P* P/ _ {
1 |$ D! `7 P* ~% q if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/: [; r$ B0 `5 B2 P
{
& [% U' }: |. p buf=c;
5 G- A$ O m: ?; ]) I i++;3 h& @ p0 t2 I/ ?* K
c=getchar();+ H4 [) ]+ \1 v$ d9 }2 k* a
}
1 R( {+ d4 ^3 @, F5 y else /*是运算符*/
/ a0 G( P6 [+ ?8 y' F: P {4 O/ }7 h6 d- [; B8 Z, q" |
buf='\0'; ~. {! V* X9 j) @/ L
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/* X6 u: u) a( x9 Y6 t/ c/ x5 q
{, M- d- T4 Z$ ~( [
opn_in.data=(float)atof(buf);# n/ L+ I& {4 F! n6 [7 o
Push(opnd,opn_in);
* u* M* v+ }4 i& z: R. `! G printf("opnd入栈:[%f]\n",opn_in.data);
4 ?( V% _- J0 H$ T8 v) L0 [1 x i=0;
: K9 z- | w; p- S" x" m memset(buf,0,sizeof(buf));3 t% {7 Y6 l, }! M8 ~
}
. L) E- Z1 g$ k- r6 O+ v opr_in.ch=c;
. z8 h5 J. n. x4 A0 l switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
3 B1 L8 q) S- S0 ?( }$ o3 ^7 ^ {% e, ?0 Q/ R; @# y
case '<': /*优先级小于栈顶结点,则运算符入栈*/: ~7 V7 Y$ T/ \' B% k6 Z. s
Push(optr,opr_in);/ p# `* F- P S
printf("optr入栈:[%c]\n",opr_in.ch);
, h7 ]7 r( t- S3 p. U c=getchar();
: q/ t5 l6 ^5 h% I break;
5 Q0 R4 u' t3 D0 S) l case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/6 b# P6 L, r4 X; z, ]8 L
Pop(optr,e);
/ Z& Z9 v1 N, L4 R printf("optr出栈:去掉括号\n");
6 a5 u: F4 @3 z) N- w c=getchar();
! ]# }4 d/ P( g7 C" k break;0 ^5 C, U5 Z6 r3 r. h
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
6 U) G0 r' a% c7 K Pop(optr,opr_t);
' y& B1 K. [- U4 h. ^0 j printf("optr出栈:[%c]\n",opr_t.ch);
) c1 t& f, a2 `% h5 t% |2 q if(Pop(opnd,b)<0) L5 s8 x# s* h% g2 C
{
7 ]" g5 u2 U0 A% j5 }& s printf("Bad Input!\n");
. g6 a8 v' _! E( i+ q fflush(stdin);, \$ W' F/ ?+ M1 l3 {
return -1;
/ D/ I3 `0 s# M }9 {7 Q+ H; b0 p4 A
printf("opnd出栈:[%f]\n",b.data);9 w: }# F2 U; j6 g" S! @8 I) `
if(Pop(opnd,a)<0)/ m2 j0 x2 K( P! z Q
{
4 o! o3 F2 O& i" D# c* K3 D2 Q9 q* c printf("Bad Input!\n");
. D% Y) N" F( W" z fflush(stdin);
4 A# x" D' o" ] return -1;. e m& X$ _) i0 \
}8 A+ u; D. d0 ^0 j4 k
printf("opnd出栈:[%f]\n",a.data);
z, }$ C9 H, _0 ^" Y opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
8 C1 a z2 L# P* M, T1 n Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/) p6 D% t+ q. C! R
printf("结果入栈:[%f]\n",opn_tmp.data);" K0 F6 O; J8 P" K) A f9 v
break;- m) I: U; C) `
}
/ V0 `% U6 L( g& \. U W6 L: D }: ~6 d1 q$ i& N8 x' j5 O
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
* w' O, ?0 P" b8 S8 T }
4 C4 B" C. q5 Z+ h: {9 [ GetTop(opnd,opn_tmp);; z( ?- N7 _5 D/ Q* h& u
DestroyStack(optr);* A+ J8 x( B1 E$ A
DestroyStack(opnd);
, a) v4 `: r3 r) h1 l return opn_tmp.data;5 a3 F: P' c4 F' ?- ]. [1 h
}5 J6 I8 S: n, U. Y2 |
8 B% v/ ?' A/ ~/ zchar *killzero(char *res,float result)
; R9 @6 s( a9 J. q0 x{
- b v) Q& Y. S. h+ s5 W- M int i;3 e8 P: e% F I% _' q' t1 c$ ^
/ s S6 g& b; m) b _& s& V sprintf(res,"%f",result); |# ]. r* Q- S y* k8 P) Q
i=(int)strlen(res)-1;# k" N* G/ [4 {$ h
while(i&&res=='0')
, w w& Z& V" {% U- I9 o4 J! E {
1 {4 u- S- k/ L res='\0';
& ^' }2 }& ]2 H, w9 A$ z# X& Q i--;
1 U# `" [. P% F* h; t! D0 M. u }
1 ~& K( s8 p$ x( \( P: \ if(res=='.')
. j4 Q3 r% U. ?9 P4 t8 s res='\0';
+ m- Q& [' Y. E, W) D0 A return res;
/ p1 o9 m1 g1 n _ t}
' P: M2 }" U4 N: ?/ L: e' Y
" H5 F4 F, O5 D c8 qint main()( V# k2 a" x1 d, @+ \
{# {) _* I1 Z% g4 l7 i" v0 k
char ch;
3 @2 s3 p- G o3 u char res[64];$ w; `, k4 B E9 {6 x8 o
float result;
% i; h# ?1 R- O. m' k: j while(1)0 w! _7 r2 K) i9 Z4 K L
{
4 T+ U6 |9 p1 G1 p result=compute();
i# ~+ G+ |: D. h6 f; I3 Q printf("\nThe result is:%s\n",killzero(res,result)); y# ~2 Y0 q% b
printf("Do you want to continue(y/n)?:") ;% R+ p2 U, u/ s- R$ \9 A
ch=getch();
8 ?* e6 ~" y0 f+ r. w& i1 w0 ? putchar(ch);
6 z% j. t# q9 n1 a& w% U& B if(ch=='n'||ch=='N')
* K5 }$ F: q$ | break; f0 {6 Y9 R, f0 f3 i/ Y& ~
else6 U3 v0 `" E% [5 V. Z5 N4 i* d
system("cls");8 B! x7 z0 w/ B, J( }
}
' R) L; @/ x5 G! B' P, ] return 0;
, J) X" P1 o7 U}
4 J5 W8 w/ x4 `# s% X5 d
1 l6 N7 E8 H( `4 n/ D: G[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|