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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
- j' N, x7 V' }/ ?$ P8 K程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=4 ?7 s( ?; n% R6 e
/**************表达式计算器************/# g0 D; ~0 c3 W, _
#include <stdio.h>
/ u) V7 p/ t2 Y( F. q#include <stdlib.h>
5 E2 Q9 e9 k/ x) Y' T( A* C#include <string.h>
0 N- o0 ]: u8 J- p( @* m( R9 q#include <conio.h>. b. x9 Z; K* w! V! B
#include <malloc.h>
9 F' W3 s6 C8 G
0 ?9 `6 N) ^0 N( @' \5 D#define STACK_SIZE 100
3 D- Q: t7 \3 R9 p5 z#define APPEND_SIZE 10, m! A7 P0 X6 D4 p4 Z
0 t7 D: \# j: I. y. Nstruct SNode{
p( u o, ]; C9 i& ~/ f( \ float data; /*存放操作数或者计算结果*/( k% }$ ]+ x g
char ch; /*存放运算符*/+ `2 e- K$ W! h& c0 o+ v% g
};8 ?' C: o' Z; w+ _3 G+ E- O
* k9 w3 P% g' I) t4 a& Zstruct Stack{
/ `( n& e. q. d# S, x9 |, p0 H SNode *top;
; |& B6 V* o& V/ J" [, a SNode *base;
7 H0 J% E" s/ m9 r; p1 J3 ^ int size;
' M; \! j% M& }) @2 H};, o2 l; [5 m o9 C' U
" ^1 L$ w7 a5 Q9 f2 f* v
/*栈操作函数*/
, j! C G+ w0 d& Bint InitStack(Stack &S); /*创建栈*/
3 g" ^5 n7 m% I- ]" o6 g. \int DestroyStack(Stack &S); /*销毁栈*/
1 {0 Q) b! L s( h/ [5 {int ClearStack(Stack &S); /*清空栈*/4 ?7 e# `( D/ X0 A* ?$ j' u& G4 _
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/; t; @* Y! B7 [2 I
int Push(Stack &S,SNode e); /*将结点e压入栈*/* @- u6 F+ s; k1 Y! S' J
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
; e. v" @. V! F) s W* ` S. N9 k9 J3 [' X! z; L# `; ^
/*表达式计算器相关函数*/
( q% ]0 S1 ~" R1 m$ b/ l) g" Pchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
. n. E) i( Q3 q3 p; Y2 ^int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/0 Y, d; w8 k: z) Y& m9 |$ r9 I
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
4 V" T* e( J8 s( H# T$ ^4 G8 Cfloat compute(); /*表达式结算器主函数*/
1 z9 w& I7 \* T+ \% I" z M$ y* Ochar *killzero(float result); /*去掉结果后面的0*/
) r3 F2 d4 L' c* G) b; X; x) G2 B2 g$ o1 c' _
int InitStack(Stack &S)5 @) Q7 M* l6 i+ q
{3 E3 e+ A. Z, Z
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
; m0 J) {5 o3 W- |/ T' w; W+ W1 s3 Q if(S.base==NULL)
% d4 X" {1 x& `+ Z, p {
2 ?6 X: J: l+ M* e3 U/ k$ p7 P printf("动态分配内存失败!");
9 q+ i( ~% @1 E. V$ K return -1;
% L( v% A* U: w9 @; p. w! Z6 a }
- K0 D# {. f, Q+ a1 T S.top=S.base;
" W5 L/ [4 u H9 W( U/ q' G S.size=STACK_SIZE;$ o# y4 v% G# I, d
return 0;
: z. q% P- V, s5 q6 C* ]' \}
1 k3 u; Q$ p" ^7 G/ k1 z; o$ q6 d: `1 Z9 A# ?( `1 {3 K. V7 [) x
int DestroyStack(Stack &S)3 B) {; w! p; B+ g
{1 u* U9 N- g/ ~7 W) x! V
free(S.base);
8 T5 a0 V3 v* | p4 {; s return 0;# _/ J* R. Z$ o. ]) y( w- k
}
% t/ H. z0 p d1 _5 F) Z, d1 B* d$ [5 ?2 A5 Y' p0 y
int ClearStack(Stack &S)
. ?3 K! O' {4 C6 u8 K8 ~( m5 P/ ^% G{/ u1 ?) f: p4 l0 J9 Y8 u
S.top=S.base;
2 z7 @* P$ V" {1 q9 A, g% i& y return 0;
0 N0 K, U& `- d& w+ s. ?# N}
6 M" w1 r) R7 R! `: c0 c
* k( X) B& Y2 @' q3 A( N) Gint GetTop(Stack S,SNode &e)
* ~+ L% h# z- y6 L7 U* c1 H{0 k7 C: ?+ \2 t4 _' g5 y0 ]. _
if(S.top==S.base)
% f. C$ G9 n, j( \" I6 B! V {' B, S8 v" t f4 j% H/ s! w0 o `
printf("栈以为空!");
* [2 J# F8 `/ S7 _& K; T return -1;- f! n, k" M) c3 I0 W
}4 e6 t2 q; b# Y- x
e=*(S.top-1);! T! e9 h" [( F8 X
return 0;7 }5 w% ~9 B. I5 X6 M5 y) {' {: U9 C
}
8 p$ w; Z! e6 ]5 |6 e. @+ G% A- \3 R
int Push(Stack &S,SNode e)
. N E, I* D% y5 l, x{
( i& ?# i3 ?# F8 S' f' ? n, J if(S.top-S.base>=S.size)
3 [; j) K4 {8 o6 ~ {: z+ p6 v7 b! ^: G0 a
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));) S3 o5 w% k6 ?2 l
if(S.base==NULL)! |* ]0 E2 A; G2 E9 F+ h
{
6 F2 s9 ~/ U$ n, j: h" } printf("动态分配内存失败!");5 M6 g, r8 v9 w2 f1 ?6 O b! {
return -1;
$ e/ F. k, U+ W1 N: W7 A }
6 R% ?: i8 Z$ g. N' }5 H S.top=S.base+S.size;- ~- X) E3 Z+ w% W
S.size+=APPEND_SIZE;% K! o" N+ s: M g) P Q
}0 h# k) t) S; J; K( z' A6 t
*S.top=e;. w& O- z5 C# P- X/ z
S.top++;
& f) G# l. h( J+ ~3 r return 0;
, P$ w' _5 f, m; l- @}! v1 W2 ?+ P; `- a8 i4 `
" }' B6 g* ~/ L4 @; Jint Pop(Stack &S,SNode &e)4 q% M6 |7 r8 X* x
{
8 L2 V. P6 F* u. f. _- ` if(S.top==S.base)
4 k* t* [5 H4 s. {% b% @ {
" B) \. N; l1 N3 u0 C printf("栈为空!");8 K4 @# o. S% n4 b8 ^( I' f$ W
return -1;
+ t: E2 m4 W) m. k }- n, N! P% A. E
e=*(S.top-1);. x6 N; _3 |: @+ {6 _: ?$ t9 z
S.top--;
C. g3 s! z4 }9 G- L. f m return 0;
; E- Q1 L: B# M! Y- {; a& K; H3 i) v}
9 @8 U7 f$ S8 a7 F+ a' P
1 L9 p2 ]+ U {$ g( C, `" Tchar get_precede(char s,char c)
4 m( S* G% f8 K$ O{
# L( o4 A$ m; ^' j switch(s)" T7 Q" j7 w3 n. A9 L+ u
{. ~5 u6 Y- W# p* k% e
case '+':
2 X% ^! o# Q- b' O case '-':' K* B m% M4 E ]! m
if(c=='+'||c=='-')
# t! Q# v; X0 V' K7 G: K return '>';
: m; P5 f1 K! e; { else if(c=='*'||c=='/')" O; N) G6 b4 B. i( e" r
return '<';' \6 Z$ A& u+ D% F& U% Z4 c& s- f
else if(c=='(')9 s) i$ B0 u9 r
return '<';
# k0 @; z6 l8 Z5 N else if(c==')'): l% G+ T6 s; w& j$ d1 _
return '>';6 Q& p: t. i8 H, r% `. b
else $ y- y: s" x4 O/ n, M9 B
return '>';
3 p C) ~# b2 z% P! ]. x case '*':0 x: o% p: O7 I( ~4 U5 B$ [! W U! s
case '/':
4 ]; R9 p0 g3 d( W: W3 W% T if(c=='+'||c=='-')
3 \ M+ e0 G5 f6 ?1 P E7 t return '>';$ u& _5 Z/ `$ I* Z8 l% m1 _* [
else if(c=='*'||c=='/')
- u/ v( P6 s! k' C: E return '>';
; C9 U; ]/ I5 Q- ^ else if(c=='(')
' E! _/ r* ]) j7 L3 ` return '<';
4 m) M9 P' b( d i; G) U. F( l$ q else if(c==')')$ z4 K4 W: S. b) p7 q4 L
return '>';4 e5 w/ U- S( S6 W
else$ Y: T* k' x7 u3 o3 Q8 ^
return '>';
/ m1 `1 d" K# |7 g2 a% q case '(':* k. q/ z( J: y$ C( }
if(c=='+'||c=='-')
$ c) b2 P7 J. r R return '<';( m5 h$ l& a% w- O' m7 U, m
else if(c=='*'||c=='/'); T7 ^) e. [, P
return '<';7 P% d) f( R$ U( e
else if(c=='(')
$ |) p! [# W! o5 v; |+ C3 L return '<';
% `' q3 `! D2 a% x% m) V' A else if(c==')')# F5 V1 y& J7 L1 G0 L
return '=';
) K c8 `# B7 r( T2 k0 S else1 E+ [ I$ y* i& T0 H: o: a/ c
return 'E';
5 \; |( ^, U* I* _& N& U9 U case ')':
0 T- \- O7 @) k C; @* [ X! T/ f if(c=='+'||c=='-')
+ ? X; T8 f3 N! j2 B+ P% m return '>';
* {( ~: f( I7 p# \ else if(c=='*'||c=='/')
. e X+ ?1 C, V8 X return '>';7 o- v( o( Y- A) x5 t! [
else if(c=='(')# {( t; [& Z$ f, j
return 'E';
3 @, e0 G* a, I! I else if(c==')'): J' O; m; C) j! C% {/ X
return '>';! D$ R) ~# b& W* r [- x. a
else' y9 l( s& s- L/ A* p! ^
return '>';
7 `( m# X8 p7 p% L* y7 |4 |# l case '#':
. q1 h* S7 h5 r" C if(c=='+'||c=='-')6 _ M9 K' h4 d& p5 ^: B
return '<';' p+ S$ z- t! l7 g
else if(c=='*'||c=='/')9 C4 t6 i9 P% ?" i$ |( X6 r* D2 I
return '<';
4 x/ P0 d% l. t% ^6 k! q7 R else if(c=='(')
3 X5 q* I. r+ G+ V( e return '<';+ r9 w8 ^) u5 e2 v! f
else if(c==')')1 h- r2 H0 `: e, `/ b+ Z- Z$ V* ?6 F
return 'E';
$ Y) _6 T7 n1 w# N# H+ s. c' f else
+ \3 }+ A$ g: h, q5 k return '=';0 v5 ~4 u; V' F3 E% ?( f5 F: h
default:, y4 e9 t/ ~- P! x" T- s
break;4 c% h' t+ Y" l
}
, F. A" R) O' r5 j4 _ return 0; + Y; X/ C. B J2 ]9 u9 f- s
}" e2 i X# ]5 i' [$ v
' A2 [. O) ]# ^ M7 O% E
int isOpr(char c) V7 P; w' g4 e" j
{ E7 J2 q3 V! f. m+ ?! ? `+ s
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')7 O% ]! ^; v1 Y% u( T5 Y
return 0;
. x. B! ^! }' w- N) ~3 ~ ] else : C: q* f% w/ y
return 1;4 z4 s$ t6 I6 Q1 j b
}+ c ^' W3 P1 |/ a# [% m" t
4 ~" c2 b" U+ k; u4 ofloat operate(float x, char opr, float y)" b o4 |6 w. M: @! }& }
{
% t7 b3 k! n4 B4 }/ W. H float result;
8 m ^9 P9 b( _; r/ F& G: f/ O switch (opr)
9 t- \5 d4 G7 O {+ ?- b( [8 O5 ~, \
case '+':
5 ~2 }- r, z3 k G9 U) T0 g( f- X r result = x + y;
+ V" ~, s+ ?# \: _& r; b" B2 ] m break;7 n& C* M8 O& X/ r
case '-': 6 Y2 J+ T& y4 m
result = x - y;5 A+ Q) H4 H* E i' M( L
break;. U- j. W) d. Q! r5 h' O
case '*': 1 u* V5 n2 n# g0 C: l; {/ ]
result = x * y;
6 d( k9 O7 V$ x. F- \* H break;
& k: V# w/ N% Q case '/':
1 L( I: a, k5 j- r i D* p2 ~' r& |- V if (y == 0)
1 m5 U& v4 c" `6 S: J2 p {
k+ y! | d8 M* {' c* J* F6 S+ s4 [ printf("Divided by zero!\n");
" t9 b4 j2 S2 t2 p! g9 L return 0;
* z' t0 `) I. u/ h }2 L$ b9 [# y$ z! }
else
. o* P' ~, }' g7 V3 p. H7 [ {
& q% q( \# E" [% h' m result = x / y;) i0 Q7 S( F6 o5 n, U/ c l( g
break;
8 G+ p# d0 o, l& D3 u5 Y1 g/ H' y( u }9 t" {. O* j% a3 M! D- q
default: & r/ W' h/ `! P& s/ g$ g* _! v
printf("Bad Input.\n"); e. u) Z# M+ _9 e. e6 V. M
return 0;
5 E7 h: V3 J3 {. c8 L9 a- J: h. f }
' c& L# S, `5 R+ n: R/ _* w return result;
+ o; U/ H0 S# s) ?}
6 |1 R! m m T* E8 k8 w6 e" c; B5 q1 W
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
8 Y( t9 Q2 s" j! Z& N3 }. X5 R5 J# U{
, A; J2 p u T4 y* d2 I Stack optr,opnd;% c5 w8 E7 ~4 [7 X
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;! ?9 ? C* v" N/ M7 b& C# S
char c;6 L$ G" Z4 p. P7 }# r( m/ W
char buf[16];
* m" o' U6 s% \ int i=0;
! }9 N- D; U9 S& Z: o
4 z8 A: `- E- q# L q1 X InitStack(optr); /*用于寄存运算符*/' _/ a/ J7 e. _0 J
InitStack(opnd); /*用于寄存操作数和计算结果*/3 i4 Y5 x8 j( H# b
memset(buf,0,sizeof(buf));
; W- Y; z9 f `. @, x+ w f* C/ d
: H/ ~, B& B" [: |% b printf("Enter your expression:");' h* R0 j7 V) M ~: l
g2 {7 K, K; N, u# C opr_in.ch='#';
# [4 ?, Q/ y: w5 w9 N5 g6 `( g, k& e Push(optr,opr_in); /*'#'入栈*/( L0 s- \5 E. z) j% g8 Q3 `
GetTop(optr,opr_top); F" g! T: P6 G* q
c=getchar();6 X+ h* p7 P j! `9 ~* I, p. f* J
while(c!='='||opr_top.ch!='#')
$ y1 E* ?8 l Q& D- |. r8 U {6 \, s% C4 O; i" u
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
( |/ l+ f: W. b( ^ i7 m6 | {3 V; y. S. T# R( U2 J
buf=c;" r* t) _ Z' ~' q H# q
i++;
0 ^/ i5 {$ m, _+ M c=getchar();
4 \% }3 x% R; u4 ?2 |2 R }
% Y/ t, u( @& U( J# c% u else /*是运算符*/
: y% R% x8 I; i7 _9 g, m {/ H6 u j+ M7 g e9 ]
buf='\0';* ?5 `+ G4 F% g0 I' p( [
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/3 Z8 C4 E) j3 \1 W/ Z5 O
{7 z! w; T/ Z( N- v5 F* e
opn_in.data=(float)atof(buf);
6 J7 m. ]5 E* D0 O+ I/ w ~" Z7 Q& T Push(opnd,opn_in);" L# o; t- ~2 H. P' R
printf("opnd入栈:[%f]\n",opn_in.data);
& ~4 S2 a4 w5 o6 F$ U i=0;; D W. s2 _% E
memset(buf,0,sizeof(buf));6 Z- T5 d' K/ a
}$ F$ r6 k$ T, i; l7 y( L9 _
opr_in.ch=c;
5 U: |) o: _+ Q# A5 U2 l6 u# | switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/8 i" v7 b. E; `
{
$ m7 J; w+ @3 J$ I* I) G case '<': /*优先级小于栈顶结点,则运算符入栈*/
# w! Y, o* I3 \8 S$ q Push(optr,opr_in);. q( P+ N8 l8 h: T# i1 U% j& V
printf("optr入栈:[%c]\n",opr_in.ch);. A7 W" ~ X w/ x2 x: V+ R! {
c=getchar();) j& F& F/ t4 e8 i- t/ G7 S1 o
break;) ^! Q; k4 q0 e! B1 v8 [: {
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/( Z) B+ t8 ?% ? q, L
Pop(optr,e);3 t; G0 w3 t7 @ a8 q, I
printf("optr出栈:去掉括号\n");
. ^& z0 k8 p! o# s' f c=getchar();& ]$ h7 p& ?, z
break;. u! o' C1 ?$ s+ F6 e
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
- ?; B- I5 z' q+ H7 p2 ~ Pop(optr,opr_t);% U0 f6 M D: a+ }) A7 [
printf("optr出栈:[%c]\n",opr_t.ch);
+ Q. a, U, j) Y* { if(Pop(opnd,b)<0) o. P' G; j% b+ T- D
{8 g# s6 J& }. V" Z+ H# k
printf("Bad Input!\n");; j; l8 n& N& p
fflush(stdin);# t: O- l& _* ~! H8 O. Y
return -1;! f6 t! q* @) B6 y
}6 @) r6 } Q7 D/ C. `
printf("opnd出栈:[%f]\n",b.data);
& S0 ^! s' L5 D- h! n* t: y if(Pop(opnd,a)<0)/ A) ]. B2 ?& a8 u6 S" K
{: i* r+ Q2 H4 E* e' E& j; W
printf("Bad Input!\n");
: q' p/ P& @3 x- b. B, J fflush(stdin);# A! H2 `6 e! D' o; N+ X
return -1;
! Z8 }# T& q) _* o }% e, H9 x. N' ?! x( x: n+ x( n; I' g
printf("opnd出栈:[%f]\n",a.data);& o0 C2 \- a5 c( T$ o- R* t
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/2 \' q2 W. S7 X
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*// f% g* j5 m" C# @ `& Q
printf("结果入栈:[%f]\n",opn_tmp.data);
]0 w o% y* r2 ` break;, ~2 X' b s; f
}
! W/ p! m# t+ y* d }
7 Q2 \" s- f6 n7 L/ j; A GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 7 B: z2 w; y( g+ i) l
}
1 a- g5 ^* {+ p. L6 } g; m GetTop(opnd,opn_tmp);
% e0 h' y$ N& W) _6 t3 o, H! ` DestroyStack(optr);
8 e& b; z+ [! h& |- ` DestroyStack(opnd);
; |. m s7 `* M- T- o$ g return opn_tmp.data;
' r. d1 j; U- z0 E4 a) O0 u5 V}
% C7 @. c% z8 T3 z" Q
2 ~. x( d0 @9 ?char *killzero(char *res,float result)+ h0 R9 ?; |$ b- z! o1 j
{
; f1 \3 I- c9 a& `+ c int i;- c, n3 @+ I) n4 v3 l9 u
+ W& P# X; k' a: j
sprintf(res,"%f",result);
! V" n0 ^. M" @! z# {8 L i=(int)strlen(res)-1;7 a( H2 F+ z* W& C) E
while(i&&res=='0')
7 E3 g3 J' g; ^" @ {
, X |/ R7 r4 ?, m7 x res='\0';
: |; D+ v' K1 |# P0 ^ i--;
( |, @3 w f: _9 \. ? }" M i6 n0 Z I. b, M! U" {
if(res=='.'). v& J' ? m, b, {* Y! @# N& @
res='\0';- O$ O& e2 [- P! {" g# k
return res;
& `5 m' x+ _ H: T3 m}" x' B& U7 U8 R: r4 i+ d! V
$ N8 y6 a% I8 ]9 y9 Vint main()- [4 g3 W5 M0 [& }* W) D: M
{* ?5 p+ R" h' P. C0 W
char ch;* B- W# E8 n8 }
char res[64];9 q5 U% [# D9 |* u
float result;2 v7 u8 u- s/ K) u' m
while(1)
- f! }0 L" q& Y5 C6 F {: }/ W" F( N2 V4 i
result=compute();; f7 d# i4 X- p" \4 L
printf("\nThe result is:%s\n",killzero(res,result));
' M# l/ y3 H. ]7 _$ s g: \ printf("Do you want to continue(y/n)?:") ;
5 N: x8 d: a: r4 E ch=getch();
8 a5 _0 @# d' D/ g putchar(ch);
$ _! C1 |, k+ n6 z. g/ l if(ch=='n'||ch=='N'). ?1 l1 S4 Q1 [1 \" I7 ^) D Y
break;7 h3 d: n; Q$ u9 w
else
, @+ l0 B( _) G system("cls");
, b! h' Y* Z2 X0 Y* s }2 N/ X* z8 O$ b/ P
return 0;# V$ i: r- `2 d0 i" A" A+ y
}
$ x" H* r1 U. o. N" T
9 k' |' p4 y: `' h, ?" l[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|