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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
' U* S. b! m$ S4 z: _* t/ b- {程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
8 X* A" h9 Y, g% ~ y, h: M/**************表达式计算器************/
0 g- z& }( ~ O5 T; j#include <stdio.h>
" W8 \8 r+ f7 n8 r& s#include <stdlib.h>9 p$ }* |' d1 W7 I( f( n
#include <string.h>
. c5 G3 i! g+ l5 ~% s3 U#include <conio.h>
* ~( C: Z s" v#include <malloc.h>/ e& A/ v0 N) e% C
1 k, a0 I8 k, R6 U: Q3 h+ V* u
#define STACK_SIZE 100% [1 f" L6 F( o# q" O
#define APPEND_SIZE 10
6 y8 r: p& R0 p* @3 E6 K; R) z2 l% ]7 \, ~' U% D/ Q
struct SNode{
: u9 S* Y$ p4 \, E+ { float data; /*存放操作数或者计算结果*/5 N6 e8 i4 D( W- [# G; P3 v* S; H
char ch; /*存放运算符*/
5 X: o- ?6 k$ g6 ^, R};" r- G9 Y# k/ I
/ b4 _, N( w: R. M& Gstruct Stack{% m, C" B% z: s1 r7 r
SNode *top;7 t- s, f1 M7 O+ j2 ]
SNode *base;% j5 H4 S+ l; |! n6 ~( E8 h
int size;
. L: F' c) }8 C. R! p};
8 G. j; ?* X" L' j1 p* `) t' q" \! z6 [2 w- m2 H4 z$ }% M
/*栈操作函数*/; v0 B1 }0 E, D5 _) l/ g" I; a+ T
int InitStack(Stack &S); /*创建栈*/
1 \! Q9 @1 ` @ aint DestroyStack(Stack &S); /*销毁栈*/
- S% H9 k/ B& ?, X( J0 c0 N9 Iint ClearStack(Stack &S); /*清空栈*/
- A1 v$ n; \: }! X4 L$ l: \int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
/ f% b4 c0 A- J/ T, i# y4 c# q" aint Push(Stack &S,SNode e); /*将结点e压入栈*/
+ |- O s+ c: P! s }int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
$ x+ a& O$ S# ~3 B8 \' }+ m
5 K, |! j7 [: i1 j/*表达式计算器相关函数*/7 H( |* f2 K# O, C7 X
char get_precede(char s,char c); /*判断运算符s和c的优先级*/ ]% p: B# W1 t2 _! N3 v$ c6 ~
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
. k. c! e5 c& p# W3 o$ T7 Q& Nfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/$ C: H2 S, @* v C# T3 R+ G
float compute(); /*表达式结算器主函数*/
k9 C$ g: H1 l6 q# K9 a! Rchar *killzero(float result); /*去掉结果后面的0*/
( y: Q2 k+ I# Y8 r5 s
; ?0 u" ]1 S6 G8 @int InitStack(Stack &S)
# \ {; ?( F) h5 E7 S- T{! {9 I* A) o# F8 x0 r* V7 M8 r
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
+ F3 ?' H6 S' N% v' l if(S.base==NULL); s6 t4 u! m7 U4 {5 n6 _4 W
{+ S% V) F/ @/ ?( T
printf("动态分配内存失败!");/ U1 C' q. Q4 g0 O% P$ [
return -1;0 e- g9 Z3 l8 O6 Z" N2 [- K
}
7 M3 G9 j; g1 q" G! ~! e2 v S.top=S.base;
5 q1 R! d' A. |* e. J# v- h S.size=STACK_SIZE;! r) B7 }5 l8 A( c& a6 f* V2 Z; \
return 0;4 r% u0 O' I- ]4 z' j
}! [1 q% W& }. t9 P5 I0 e6 p
1 z# [% Y! D0 \6 h) g
int DestroyStack(Stack &S)5 _8 W7 V8 N6 a7 G* Q2 k2 G2 ]
{: j3 _' q: R( m C! o
free(S.base);9 g5 _) q: Z) A' E; }$ x* D9 g' i
return 0;# _# x9 X$ V. J3 W0 I1 }/ e. U* k9 d
}2 j& r0 y0 H& ]+ R/ h5 B6 J
( u! M& i Y) Q* o( r1 uint ClearStack(Stack &S)
4 V3 r. I) h3 w9 Q* M{+ L4 [/ _- r' s" b1 L
S.top=S.base; u/ q7 h( [8 t7 n' O& O$ O7 F
return 0;
) c4 R' y2 s# ^) _( Z. o) O% S}7 Q) }' k# X$ L; \0 J! m
5 d5 Y* E) s: V& pint GetTop(Stack S,SNode &e)
1 N# o2 J7 Q$ A5 z- v" R{
# m" O" s* M( |$ t) W if(S.top==S.base)
- Y7 ^8 d0 d! z3 b, S* R3 Q, q {$ }+ e- }% N& q8 `6 `. r
printf("栈以为空!");
: a) D q# h( `) N5 F4 v5 q return -1;
+ C4 J% m5 y+ q9 p/ V" y' Q- P/ r }
( j C b5 g% F; T1 k e=*(S.top-1);5 K& [- S* I+ a; Z* s) u# l
return 0;
3 g+ \8 B6 C1 V5 A3 F}$ b" B% z7 y" N: e1 H* U
- e# _% V0 {# O9 Fint Push(Stack &S,SNode e)
, z$ @% } H0 c; t \+ c{
3 q8 W, L- m) W- z2 @; u, b if(S.top-S.base>=S.size): F" n4 h! U8 t8 J! `& p g" c
{
. d& U+ P2 d5 D' |+ S& I S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
0 y7 w+ E* C% X0 w$ B) C if(S.base==NULL) G1 w) n% q+ e5 x$ I
{
* F9 k' c' J0 m$ {* ?! V printf("动态分配内存失败!");/ x7 d8 t( J: Z: `. @2 Y a$ X+ `$ t
return -1;$ D2 s+ V* g" d9 D- _
}" r/ P( V! Y+ _, _) K+ S) m, [
S.top=S.base+S.size;
1 T9 B( ~+ m# f S.size+=APPEND_SIZE;- H' Z0 h1 Q7 s7 j5 H
}7 c! s6 O* r) @* d' A
*S.top=e;- j5 S! u- s% W' d: ]2 U
S.top++;
5 _+ W$ g( U& m+ d return 0;) x- K' f% k, _6 r$ \2 p
}
0 Q) p$ r0 I* ~6 X* ]: r* f; Q$ N, g
int Pop(Stack &S,SNode &e)4 t, Z5 N. }2 @! [
{1 X2 b" \& i" P6 h3 H9 d: J
if(S.top==S.base); ~- S3 c' @3 j1 E; Q, t7 D
{
9 w9 p* R' D; p printf("栈为空!");# V+ x. y! I2 U; N4 z/ `
return -1;
3 K9 S1 m; M$ s- ?* q( g- H) L& { }! i3 _8 Z% c4 P6 x2 f
e=*(S.top-1);3 o* b& L6 j! c+ Q
S.top--;+ \$ I; H$ p; y$ i( K& L# m7 O1 L% M6 J( d
return 0;
j2 ~+ s* _0 z" i b' n3 x}
4 H/ Q7 G3 S1 b5 s3 D2 |) m7 g: C2 g1 t. V5 U# M
char get_precede(char s,char c)% c/ T- L0 l% x+ S
{
7 l! y0 l: E3 `% V switch(s)1 N8 o0 f. x" E f" f& t7 i E
{
* u+ Q/ n, M% D" z/ l0 r case '+': ' R) s" a4 d3 V
case '-':
: R) T; O! n! K$ E6 m. d) m- C if(c=='+'||c=='-')* k& _; l. m6 J. y2 {* g/ v1 A8 x! r
return '>';5 K- t) L$ [6 \2 d/ ^7 {& L
else if(c=='*'||c=='/')$ p2 }& |# |6 r7 \* h# m/ j
return '<';' y( c+ l8 P# h g0 j- j2 U6 @
else if(c=='(')2 s, c. h6 K& z9 I8 }- }
return '<';
) O( V/ E5 q: r else if(c==')')% i6 J! t$ I7 z- a( W3 Q
return '>';
, O+ K# s! z" ^/ W4 C! L" B else Y7 h6 _% ^5 W+ t6 f/ [
return '>';! @; |. m' |% }. ~* c0 \
case '*':
% X$ o* _; o7 c3 s/ G: p6 K case '/':& X9 P8 V6 Q; W) [7 V; C
if(c=='+'||c=='-')% D# X- r9 u+ E$ O* A
return '>';
+ b. e& [5 X- T! w8 o0 ] else if(c=='*'||c=='/')6 K! U4 i9 V' ~! y2 o7 y# u
return '>';
* M$ Z9 i! v1 I0 A4 [ else if(c=='(')
@, |7 [7 o6 I! n. V return '<';
, m7 |4 W$ A- W/ O6 L Q. h else if(c==')'); T& C& f. G5 {6 w" t3 B, G6 ?
return '>';. K8 Q7 Y( C2 K/ k: |% x) X4 W0 R
else. q$ v& Q0 N4 B2 t
return '>';
. q/ P9 t# a: u4 _) a case '(':$ d& ?5 ~( j# g P
if(c=='+'||c=='-')" f7 H9 r7 K: i J
return '<';# W2 i8 X ]8 r8 v- l. V: w
else if(c=='*'||c=='/')3 D- R7 R: W# T! S
return '<';; v3 ~* u' p6 c# {! n. O0 F" F
else if(c=='(')9 U4 G6 [' t$ V& G
return '<';
5 t' y; A& N" @4 g) Z else if(c==')')8 C4 j( Q# z* s
return '=';
/ U5 C8 ^* p2 K+ J* b" a- w else
$ o6 O1 Q* z2 J' @4 Z. q, p. F+ o return 'E';6 }6 \& }8 Y& N; _( i+ n9 ^& ^
case ')':
- D" F* T9 X; l if(c=='+'||c=='-')
. u0 n- d: U3 h+ P4 o( A# k) g; C0 t return '>';0 y- i" D4 a5 n6 G+ B& H3 X! ~
else if(c=='*'||c=='/')+ {8 _1 ]" R2 z
return '>';" ^, N, g% U. v& F! y
else if(c=='(')
5 ]2 E6 ^! Y" ` ^ return 'E';
: t8 p+ ~; V$ E& r. S U. U7 Y) Z else if(c==')')! k# `; ~8 L3 r3 X% j5 W1 N* y
return '>';
5 u5 Y" ^3 V d) i% z8 T$ |1 j' k else. O5 D, ` _6 Y4 Y7 L
return '>';% u" U. Z# i* q3 ^) a
case '#':
: f+ p. f( Q6 z: V! ^ if(c=='+'||c=='-')" a0 X. A8 ^( o0 x, i
return '<';& w* |" p! p1 K# ~
else if(c=='*'||c=='/')
' n0 A1 R7 l; ^ return '<';% K6 C# p/ ~- n
else if(c=='(')3 x' f4 r7 U3 U- N9 l, R5 X* e
return '<';
, p @- f7 y. B+ X$ z: ^3 g- | else if(c==')')2 p/ r5 l5 _, l; y0 q. m
return 'E';# U" V' ^% S- {# a4 p4 A9 [* `! [
else; N2 ]- @4 X0 t; [) m% z# d# k
return '=';/ N% y, w% Q, W, U6 V, J
default:
2 c. i: b7 {, l' } break;
, R+ L- ~+ _) F$ h# r }8 [+ c4 z% D; _4 r6 \
return 0;
- `* @; ]) ]6 X, m( H}* I1 `/ ^. L5 r$ g: A
9 F* M8 x8 H8 ]$ a9 Eint isOpr(char c)4 ]# i1 |" R# ]
{: q4 r# a, D1 T' Q6 `# F# Z8 D
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='): Q5 w( [; O3 e' |1 G5 s
return 0;
8 Q1 ^% s) u9 f0 J" F& t2 k else 6 U2 u- Y( p% H2 @1 e* j
return 1;4 G$ s( h$ B- }2 I1 }# C, O, h- K
}0 }7 h2 x- m0 m ^2 X
7 J! k, r, @+ z" m5 @. k2 T# a
float operate(float x, char opr, float y)/ L% }9 f; M0 D t
{
" E; A3 H9 W9 m3 Q5 y; h float result;% @0 z; ?$ S5 L$ H# d+ G! e( _ p
switch (opr)9 a' G8 U! e. l$ ?3 W# `& m
{2 {) S* x: ?$ `& u/ @! a: L
case '+':
# J5 O& c: H( d& K* a result = x + y;
/ G. p D. w$ ~/ f& r# y: f break;) s' P) [7 k" |, u* a8 I/ w7 x
case '-': 8 i4 K( r& g! J y# A7 N
result = x - y;- T7 V8 `: I9 c3 f8 c
break;
# A7 b+ L8 G |4 P n Q+ H) o case '*':
( q' o% w) S* S% C6 Q* w1 d result = x * y;
$ _$ u1 B2 G. [6 B# g1 A: h( Z break;' i- S$ Q l- [1 J
case '/': 0 H3 O: v" \* G! i
if (y == 0)
6 X1 Y7 X9 o Q, Y5 ] {
* M- `* ^, K- r# d. @' W printf("Divided by zero!\n");# U! H$ i$ N, @) Q8 [
return 0;) U7 t- N* Z1 m1 \
}
X# y; N- C' s! _" l# w else5 t: E9 L( B, e: ?* h# @2 w. i! N! P
{
, ^# m& a/ m# f0 z3 L0 k result = x / y;
% _" C( y/ \6 |% S) E3 s" N break;% `4 W& R6 n7 @6 n
}
; F; R' J2 O- B/ T2 F( S. V default:
9 v% E! u+ c& X# i4 \1 ], `- p printf("Bad Input.\n");
/ `: Y Q1 w! a) B8 a& E& E return 0;
& D0 }; G3 i8 M" N) h. B }3 [& ~- v8 J& ~% w0 D
return result;5 G" H y+ R7 g7 e# E7 b
}
; W1 a% g1 q5 L9 @/ M6 M( ^4 Q7 {8 N2 `9 U
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/1 m: Y6 Z6 [5 z8 c
{- j% ?5 [, A$ u5 g
Stack optr,opnd;: h: Q, I* C1 F9 r
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;0 {. G& p1 b$ I9 B) G4 ?
char c;2 W) D0 h5 q( k! }1 m+ f& T( H
char buf[16];
" b7 l! `( U) @3 r# e* L int i=0;
4 \, ?( a5 t7 Z7 z; c8 k2 f
1 R' {0 l! E3 S2 N6 A" r/ M! _ InitStack(optr); /*用于寄存运算符*/2 m4 P3 l3 V9 U0 `
InitStack(opnd); /*用于寄存操作数和计算结果*/! H, n4 q$ R* T0 t4 z; N+ J
memset(buf,0,sizeof(buf));
) b# _2 x; q: `) Y7 c. H; V 8 [( A* v) U# p1 k
printf("Enter your expression:");
* ?* U( v% p' q5 [ , L4 z2 r' \% u. n! C( M$ e- ?( r& H
opr_in.ch='#';' P* _. }' l6 u* p W- c4 v8 d
Push(optr,opr_in); /*'#'入栈*/- _; F' k) w0 U
GetTop(optr,opr_top); w; W$ B6 V4 M/ z
c=getchar();
, Z7 w5 \- c8 E3 `$ P$ L7 c' ? while(c!='='||opr_top.ch!='#')" W) ^5 r& w! G! w
{
1 w; {4 v0 E+ _5 m+ c/ D if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
+ q, g/ ?( @& M+ @! ?9 }2 y {
( W7 V6 X, J# P- S2 b# k buf=c;
5 a: F! G1 M. t' m7 T; {, @ i++;$ x5 a: P: D' w$ F$ R& y% a% @# H- ^( Z
c=getchar();
+ h- O2 O8 j% q$ c" U. Z }! j% o- j6 G( [; m- V" A" ~; h/ H
else /*是运算符*/
! B R! Y) q6 n& [: e6 p {# A5 E, G3 W( z
buf='\0';
3 w* \* U s/ r* I& g4 |6 [/ s if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
7 y' b7 b% X6 ]9 } {
, C+ c& O! Q6 v! @ opn_in.data=(float)atof(buf);
0 Z0 m) @8 B7 E# N o- r( H9 i% N5 \ Push(opnd,opn_in);1 n' _" y7 w6 w5 |5 l$ e/ {! @
printf("opnd入栈:[%f]\n",opn_in.data);
+ e3 S/ g7 Z: B1 y i=0;
- Z/ }- N) s' r1 ?) I& ~ memset(buf,0,sizeof(buf));
5 u; E' B. E# B }9 b6 z) d" C4 K4 |+ c {- g+ _
opr_in.ch=c;# o% l e9 Y9 e: c
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
2 ^3 B0 O) l7 Y2 b# A m6 e {6 d$ I: c( V$ W" Q/ [* ~5 O
case '<': /*优先级小于栈顶结点,则运算符入栈*/: H( k7 v% ?. J- L- \
Push(optr,opr_in);
% Q( K1 b, D1 y6 O/ n' R7 q9 l$ g printf("optr入栈:[%c]\n",opr_in.ch);
3 {3 ^6 j/ n3 D/ x c=getchar();2 a/ }% Y, W) C, d
break;, u- }. J2 l, P# S5 o( j. o+ T
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/0 {4 Q/ y1 F( `6 Y
Pop(optr,e);
- V* n5 T; C! U printf("optr出栈:去掉括号\n");5 e1 @, D. M; [0 |3 n# K3 G
c=getchar();1 w% }/ K. F; w2 L
break;
) L2 y8 f: f9 d case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/% M6 ~8 M3 `% y( ?
Pop(optr,opr_t);
% ^& m, L8 I0 E( a/ t+ T2 d printf("optr出栈:[%c]\n",opr_t.ch);
! W2 V+ K- V* L$ o% n if(Pop(opnd,b)<0)" ?# v4 s7 q, j5 j7 U
{4 W: d* y$ V) n. Z4 ~, ^
printf("Bad Input!\n");! g4 Y& E' b1 [* G& i
fflush(stdin);, p/ A. f1 r3 m- i
return -1;
! P7 {& `2 c9 f! h7 r4 Y }( N! @- y* Y/ N: R( V
printf("opnd出栈:[%f]\n",b.data);
5 v z* A( i" ?9 f% @ if(Pop(opnd,a)<0)
x5 n1 t7 t# b5 U8 k0 O2 o2 I A {
& A: }9 h8 A, a printf("Bad Input!\n");
' `$ ^! T9 d' s1 e, n fflush(stdin);
: _" o3 a7 R9 x2 C return -1;1 V- D6 ?- e5 |7 ]: M3 z% y( P
}
' \& m4 ~/ x( i. k# d4 q( }. Z printf("opnd出栈:[%f]\n",a.data);' p7 G0 ^' L4 p. _" Q7 C7 q9 s
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/$ Y' I8 K; y3 I. O% W
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/- y) q2 t0 |% N% ?. }% _! o
printf("结果入栈:[%f]\n",opn_tmp.data);8 M" i* M' [6 z2 T L* Y
break;( q; |4 D4 P7 U
}! R" ?) ~1 Q( C" g" j
}1 ~+ [3 T6 P1 }' F0 |; T3 u7 b+ z* z
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
, _1 c9 K2 r: R( [2 _( { }& {- [5 g& g4 F) w. s. U: ^
GetTop(opnd,opn_tmp);
" N3 F" D1 s8 v: j* m DestroyStack(optr);7 Y W/ Y% H2 t
DestroyStack(opnd);
- R! ]. y0 l0 T; j4 Y ]$ ? return opn_tmp.data;9 t4 d" v2 z. `, Z
}) U$ {# c) e9 k* F/ M* Z' I" w# s9 A
3 ]# t: e- W% g4 ~& w& x) w
char *killzero(char *res,float result)% t0 t: ~. C% F
{' T/ H/ m3 Q" Z
int i;( T) O$ G+ P1 y0 G5 \ g
' l! z7 j8 m3 r9 [) @3 |/ ~- P( j
sprintf(res,"%f",result);
5 C- h: v! r3 l1 E" { i=(int)strlen(res)-1;5 s8 [# I2 [4 s2 a6 L4 a
while(i&&res=='0')
5 ?: k7 A3 i( l- N {
4 }% P4 }2 g1 X1 f+ p5 z res='\0';9 i; o/ p q2 i
i--;
" f+ ?$ e8 ]# W9 w8 c! p }
( z4 i! K+ a) }9 O0 E+ V" I if(res=='.')
) {; L! Q1 d# u% }; n2 s res='\0';$ x, e9 P! j+ Z g! r, t
return res;* Z: K9 ^/ `! i* S: A2 z
}
- L! |- b/ ^1 a; o( v, G
; g% |& B( e. Bint main()9 p7 u8 g4 I* D3 A! s
{
- s- A; S( m* K- F) g+ ?/ Z. } char ch;
1 e+ ^6 V$ b) P9 L6 D5 c char res[64];
: W, b% k# r' V* F7 p9 c4 X float result;1 b E/ N: j9 B
while(1)
" [+ Y/ b7 i. G& b9 _; ?* f0 C/ q {
1 Y( p3 m* A3 ?1 e8 D; B result=compute();! m9 Q, q. X+ X' H& h. e
printf("\nThe result is:%s\n",killzero(res,result));$ z: Y1 n# _# C+ }& R/ G0 l( N& u
printf("Do you want to continue(y/n)?:") ;$ H- Y5 k1 G8 P/ f
ch=getch();9 v- b% E, [3 a) L. Z& c' k
putchar(ch);
4 ~% l. e2 z/ ]2 ~. I# m4 U9 E$ ? if(ch=='n'||ch=='N')' {9 h, R) X# Z; @
break;/ h) U. b9 ^ D( B
else0 S4 V& b: c: |
system("cls");% K4 }! Q" ~% N7 V7 f2 F, f
}
9 P/ K7 {" ^/ I- F& I8 N0 [ return 0;% X0 L4 l. f& K8 b: c) `
}2 T+ [+ g" c2 d! f8 \
) Q" k* H; z* l, d
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|