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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
7 h8 x& T" H! B& p e程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=) m$ `& I( P2 @* o; k
/**************表达式计算器************/
. h1 J7 v& k2 s+ [#include <stdio.h>
. F4 ?3 q$ n# C1 a6 @2 E( `#include <stdlib.h>$ m9 p- E( f0 k. _# u
#include <string.h>
: j; k& v3 M8 k1 j! w, x6 R! L9 N#include <conio.h>
4 I. I# m. Q! R( l$ b& T#include <malloc.h>
; b& z& t5 z- q" c
# C: I( K- D4 u+ U! z$ X$ g' E/ N#define STACK_SIZE 100
, \. ]: k. O9 f#define APPEND_SIZE 10/ d# z8 W3 `) f+ o6 D2 T r
7 I0 R F5 k5 S1 j
struct SNode{
5 Y9 H8 U- t3 E2 m float data; /*存放操作数或者计算结果*/
i: Q8 d0 E, s$ H3 h1 }6 S char ch; /*存放运算符*/8 q1 n$ d7 b) C8 @) _
};* z- T% K2 ^3 T: b1 z# S4 |
6 u2 w% j# C# e& x' H$ d$ mstruct Stack{
% A' ]8 X# a3 K SNode *top;5 ]7 E: Z, P7 L% L4 q' n/ ?+ L2 H; c
SNode *base;% t! e0 _2 t# w" o1 U
int size;
( N: ~& Z( B5 d% N! S, y6 E};
5 G) P$ Z* I; Q0 H% }0 u( Y! {3 c2 |- F5 j* E( A# o
/*栈操作函数*// J R% V$ \/ f# j$ r/ \5 G
int InitStack(Stack &S); /*创建栈*/
$ L' M7 L4 J: K! c8 I; w* J) ~int DestroyStack(Stack &S); /*销毁栈*/
d$ l) R! g$ ^$ F* Vint ClearStack(Stack &S); /*清空栈*/! D0 k# C. q- x, ^
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
& z o6 ]$ p- L, ?int Push(Stack &S,SNode e); /*将结点e压入栈*/
7 u% X* K+ S0 x4 J$ ]int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/: C0 O; [* M) _$ b U( v! G2 W
8 v4 t, y2 ]; J/ p$ G: m
/*表达式计算器相关函数*/1 s& D0 F0 j& ^8 K" A5 w$ o
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
9 V8 W& K. \4 z& Oint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
, Q/ J, ~' c- T3 X. x+ O5 cfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
: c8 I2 t, V+ H) p8 e4 Xfloat compute(); /*表达式结算器主函数*/
' U+ A1 R' A- |& ~7 y+ s$ Fchar *killzero(float result); /*去掉结果后面的0*/ # y; k) ?9 M8 f; s) ^6 w1 E; s" }# O
4 s0 I! r! U- ~" |. kint InitStack(Stack &S)
: `; P6 K* N9 E% B{
* \8 P5 }& q) U6 L0 f S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
1 k$ g% J. Z- c5 v' F2 [ if(S.base==NULL)0 S8 F/ L% d4 d' C4 g( w
{: X6 b" {( W k( a2 o3 U T0 w% ]7 \
printf("动态分配内存失败!");
$ a2 V0 a4 H! q9 V6 Z; V return -1;
7 ~& B% f& o- k) _$ G9 i, q" K z' O$ h }
2 M P$ @3 R5 O- o8 C7 _/ i S.top=S.base;# a- `5 P2 f7 B
S.size=STACK_SIZE;
/ X# r6 W ~" C; V4 y return 0;* t' A0 g0 ^0 `) n" w/ m/ ?7 P
}
5 d; G* m/ y4 D! W& e, w
6 e6 Y' n7 O, D$ R+ v5 aint DestroyStack(Stack &S)& e+ `. k5 G0 X
{5 }$ l+ d8 J ]; g6 O2 |0 z
free(S.base);- |" m4 V; X: Q/ ^/ _
return 0;
5 l" ]* F, m$ |3 Y- e}4 s0 \; @" e+ d2 |, E n9 Y0 ?
}7 u0 z( F/ {# [- E( o! B* {int ClearStack(Stack &S)
# C5 [; S b g" Q1 j8 t{% V$ w% k! ~" X: \; Y4 z# C9 \. K
S.top=S.base;8 M! v3 ^/ V+ c/ j9 e _
return 0;( w0 V- Q- \$ {1 c, b
}/ }4 z, ~! }/ n s& z8 f
7 S4 M1 C1 B) K/ G
int GetTop(Stack S,SNode &e)
# [$ F( G0 i8 X3 X{8 S7 b5 m3 M5 t9 l- a% w; B: X
if(S.top==S.base)5 b, L2 L9 x: w F/ R* u
{* i( ^* g, Y9 V
printf("栈以为空!");0 M" T) e# d( w/ t- K, @/ Y4 N2 e3 X$ n
return -1;
$ `* S8 \, V3 D9 ~- g) n }
- C; l+ E5 J5 \ C e=*(S.top-1);
& _- G+ |+ B, X- W; w3 u( k return 0;
" S' Z2 D1 j3 P}
# Q: ?* m) p+ m' U
3 y$ W# H! s- C5 Pint Push(Stack &S,SNode e)8 }. v4 K- f, b$ o" C2 Z4 }
{' p0 i8 o: S; D; s% Y7 l6 w1 Z
if(S.top-S.base>=S.size)( s! g7 c T1 `7 N' Y! h7 S. Y5 ^
{ G; W O; U4 C
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));: P2 |5 t+ l+ x7 G, @
if(S.base==NULL)$ h! w, i: i E* U: u4 v' ?) L
{
" O$ e, M q. z5 f ]6 J0 a' B printf("动态分配内存失败!");
' Q7 v% g! W" @ return -1;2 h% ~+ F3 l9 Q- @
}+ l# r7 `* M' o0 U! i D
S.top=S.base+S.size;5 b( P- U" i# Y. t
S.size+=APPEND_SIZE;
~7 F5 b: \+ Q" D6 `8 l5 Q- r }$ w+ Z6 X4 l# R/ L
*S.top=e;
: u ?, ~9 P" f1 J1 ^) C O S.top++;' R8 @% o4 K7 x$ h( } d1 }
return 0;
4 K3 b' ?0 _1 j& v, J}9 k+ ^4 p/ K, d. k/ c- i J4 v3 W9 E! H
$ E5 p7 z/ Y& p
int Pop(Stack &S,SNode &e); ~& g8 L. Y" G! n! ]9 {
{
) J( {5 J% W8 w+ a; x' ? if(S.top==S.base)
- z( n' p( L! w2 } {
4 `! z" u! D$ s% o7 G printf("栈为空!");2 s+ D6 `) }2 ^% Q) t$ F# J
return -1;' m6 p0 R: A* _, M& v& x
}; a% Y# x+ O) A* T2 V0 U
e=*(S.top-1);
: ~9 \; f0 ^; ]* v& `2 I S.top--;+ e7 X* o% u0 S% c9 ^+ |4 J% b7 U
return 0;
9 N: c' z$ {! h3 I/ g) ~+ L}
- e8 @/ l% T- l, K- H2 s! q' P& L. u
char get_precede(char s,char c)- k; H/ H) o" W: G0 \2 g; Q
{
3 X% n, J b3 q3 e0 O switch(s)5 Q% [% X: S7 B
{
9 V* w1 B5 ?7 ^7 m/ z8 a; Y case '+': # |5 W4 p$ X2 _1 A* K# K
case '-':
, F7 s) G7 V" O/ i1 H3 b8 Y if(c=='+'||c=='-')
+ l y6 G" q) b* A1 q R5 y return '>';
$ q G5 h! d, d7 i. ^ else if(c=='*'||c=='/')
& p8 X) b c0 t7 X X return '<';
8 l+ s. s* e, t+ x; k% J4 j else if(c=='(')
7 {$ N7 k7 l: N$ h+ e8 l, m return '<';
% T$ g: \+ z _$ s; B J# F v else if(c==')')) y: x6 G. M) R+ [' ^0 ~6 j
return '>';
# N6 c! ^) t I N9 K% [ else ( }4 F+ S& _: c" b* Y- e9 w8 w
return '>';
; I# [7 y7 T! R case '*':
7 { L/ C$ I, [) q6 J case '/':
/ k$ @3 _0 h. ^3 `6 b0 T/ w; Q if(c=='+'||c=='-')/ [8 t& }3 S9 a1 _5 d1 [" y* ]8 g
return '>';( U; X& P' e8 b0 f
else if(c=='*'||c=='/')( h2 ~3 ]$ i" N2 @# w3 c
return '>';
( W. z% x# L$ l0 M& n3 v else if(c=='(')( Q1 {! Q' o. y7 K
return '<';* S: @) f: o( V! g; F
else if(c==')')$ N7 T9 R8 N/ F2 d: A
return '>';$ m: x3 n7 A; s3 k
else. Z* I$ V$ A* {2 P( [" z( k8 l
return '>';# P- k4 V' z1 Q$ @) g8 }
case '(':
" c* M/ t6 l+ P$ O# y! f, N0 N" Y/ u if(c=='+'||c=='-')
" L4 E; P( J8 ^3 w9 R' l return '<';6 Y1 T8 r% z, M, P( N
else if(c=='*'||c=='/')
$ O1 G5 l' C/ G! E return '<';, w5 }2 G& r" j
else if(c=='(') M _+ w2 w2 F2 x; g4 y
return '<';) ?# i# |( ]* i2 V) u, \
else if(c==')')
. |% z' [7 A: x1 ~& d& @' V return '=';
( E9 G# n; k$ \3 l# U2 t8 G7 A else1 a& [$ C3 H& B2 q8 R& J
return 'E';# S! d; S: ?1 j
case ')':5 X2 Q$ V2 w- T* ^; \
if(c=='+'||c=='-')9 K" A9 s: p2 l* C+ p# f
return '>';
5 l$ B: A- U/ w! e5 D: x3 c else if(c=='*'||c=='/')
) ? }: }* o8 r& H' H return '>';
% Z4 o# A* \2 j4 b" b9 B, x" e else if(c=='(')
0 v5 M6 d6 i, p: e+ e6 t" K return 'E';
+ o% D4 s4 u. }7 y+ v1 _ else if(c==')')- B+ s* H7 ~- B! z& D
return '>';
/ d' X& {6 K2 r7 r2 l else
. Y: D8 H8 P8 r return '>';* O. O1 X; r- ]
case '#':. D! h6 Z3 x! e& i( o
if(c=='+'||c=='-')
' t! ~# ?1 y/ N return '<';
6 v$ [5 B8 ^$ E6 h; L$ q else if(c=='*'||c=='/')
0 e/ X1 R6 X$ ]. g return '<';: z2 g a/ s m. q
else if(c=='(')/ |' z3 m8 e7 Q2 U2 \# v# \
return '<';2 X4 `. |9 l7 S+ z- u& s
else if(c==')')
, j* C* x/ l1 N6 `4 I4 `4 g* R return 'E';
- l1 Z# ?9 J9 q" J1 f else
* O, [4 n3 }+ X; K2 U( \/ ` return '=';
: Q; J! W/ [8 I% `" I default:, R( H* X: }4 S2 Q" @+ J" i
break;
% m, z7 C3 R; C }
* r) E& d7 s6 J# O& B) @ return 0;
4 ?' v8 U* g- D7 L}
" U$ O/ g3 a7 Z3 m$ u. o/ _5 Q: T$ S* }7 p' V: M% F+ i5 I
int isOpr(char c)# Z( o: r; {+ |& g
{& G6 i1 ~- c2 N7 i
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
+ ~0 v& G4 w$ y) A/ C. b" x% I return 0;# x. r9 O, d6 ]6 H
else
! v( ]0 O- B9 d" M2 D9 t return 1;
& x$ P- l- V" ?! [, S" N}
, `$ z' i4 K: W$ c& [( p6 s$ W( B) U5 F0 |- x* c. B
float operate(float x, char opr, float y)5 d s0 P" k# t7 H
{
2 f3 H6 b' S% Q9 n: t8 I+ d+ m float result;
/ t" [ f" [' {+ g$ M" @$ j switch (opr)$ j; d# P' Z$ h
{
6 V: t& z. {3 g7 M( s case '+': 6 E+ {! j# [" e0 H' M8 W6 y) g
result = x + y;
. o% z$ y% ?, ?3 v; i+ D break;( z0 |5 [3 B+ {* ?- s
case '-':
3 P% Q4 n/ O9 o; N' ~7 X& p result = x - y;: o- n2 O4 N. a
break;
h* }# i5 v6 ]7 J6 Q case '*':
3 }2 S3 m6 v4 I( j% P' _) M) I) t result = x * y;. c1 S0 I7 s7 T7 E+ C* f7 V4 v7 F; O
break;& X; j6 ~ n9 V7 @/ e
case '/':
0 y1 z: r: K, ?) g, m, } if (y == 0)
( |9 ~! V4 W% M" K$ s% q0 ?3 h {
' O6 Q1 ^5 W8 z; C0 M printf("Divided by zero!\n");/ ]/ L, t! V3 u9 _
return 0;
/ C& c+ y2 k5 _ }
6 C2 J1 B9 H7 Q) ~' o# U else+ ~/ _: i6 a: G
{
! U7 V+ n8 }% \1 h& ^ result = x / y;9 X7 A# ~8 f) [1 L* l
break;
0 M1 I, i# ~( r5 y" c$ x }
0 G; d1 x5 M5 q; P ? default: ) O k& ]& e. V" y @8 G
printf("Bad Input.\n");
) y3 Y: {0 B' P return 0;
6 ^6 V! Z5 }" O# w" ~+ T3 @% Q }
: e5 U3 m7 _* a( s9 p return result;
" j9 z* F Z' ]5 `} : ~/ G* @) i6 M
0 g6 X! j/ h8 v& tfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/' N) U- C/ P8 I- d
{% f' \" c# e$ z$ b' ]
Stack optr,opnd;- S/ k& I j- H- _: F
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;: z& V3 R% q* U$ y8 L3 H7 ?
char c;
8 x" p3 }' K$ P3 A7 m/ v7 A char buf[16]; o% I. _4 {+ E/ u& A1 L
int i=0;
, d V6 H# t; E# C1 r6 J3 P* w ' ?3 V" O. F( _
InitStack(optr); /*用于寄存运算符*/$ [9 D+ y: Q- y2 @6 H0 M9 D1 g" j. p
InitStack(opnd); /*用于寄存操作数和计算结果*/
6 t, F4 W9 \2 m- o memset(buf,0,sizeof(buf));* L6 I8 ^1 p; s$ l) c( B3 o" L0 v# l% R6 ^
" l6 @# ^; n* v* T5 v9 ? S; q
printf("Enter your expression:");
7 o( M4 N$ ?/ n 9 P# i& B* a1 b% T+ Z- v' J
opr_in.ch='#';/ D6 \7 t* ]% f7 p0 E2 F( X% e
Push(optr,opr_in); /*'#'入栈*/6 g; A2 S* z$ U( c- f1 A
GetTop(optr,opr_top);# ^. ~" r7 @2 j2 d- p* }
c=getchar();6 `! Y1 o& V) Z2 U2 }8 R
while(c!='='||opr_top.ch!='#')* N0 R. ^7 E" H1 I* F
{* M# X! f4 I+ C ]$ Z
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/* E6 ~5 N. A, i: `
{: [, C! m1 M- ^. Q! i! o' @
buf=c;
4 M, Y( d4 m8 Y; {$ |( u i++;" P- F$ j# d5 P& m' f: u7 e# `
c=getchar();5 {; o l8 B; i
}' t+ @( n5 N, n) P/ S2 V2 c: c- f
else /*是运算符*// h- O. z& M* ?
{
0 ^6 g) w: S! r5 B9 N( ^0 N' V buf='\0';
: e p5 T# T$ e2 q7 G if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
" `3 v! N4 T5 C3 A1 e2 K0 ^ {
1 V5 |7 b5 P4 G' o3 z* I& q, ? opn_in.data=(float)atof(buf);
7 }) T; Z. ^* K Push(opnd,opn_in);
$ O# k, u. z& F5 Z& k printf("opnd入栈:[%f]\n",opn_in.data);
. d5 z6 l6 r% q9 \2 U3 d1 O% C i=0;/ u8 ~/ p k" I& D0 W* ~( P
memset(buf,0,sizeof(buf));& Y/ F6 V5 V/ U* u7 P" J& J' U5 W7 Z
}* A8 \6 {& ^$ }1 G* G6 `
opr_in.ch=c;* E$ V( s# G3 M0 L3 S
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
k0 U' R% w5 o6 B1 ~, i {
- X$ b1 [) B2 O case '<': /*优先级小于栈顶结点,则运算符入栈*/) c9 p d. W$ t, _4 [
Push(optr,opr_in);; }5 P. o X- f2 {6 @. N
printf("optr入栈:[%c]\n",opr_in.ch);
6 d1 @- r" u$ `- B6 q6 e) u c=getchar();
4 v+ T3 B. W9 m: E break;
1 \+ L' C( ^; Q$ S2 @ case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
2 Z, R. N$ q9 \* ~% y3 I% M4 y Pop(optr,e);
$ A3 e" B% `$ U. V# s I printf("optr出栈:去掉括号\n");# B7 t# d6 V% W" ^
c=getchar();+ T2 h' S& I0 Q- k, W6 u9 ?
break;
/ C2 E2 b: Q3 s1 I case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
) c& H/ r) ~# r3 z7 } Pop(optr,opr_t);
8 \: p0 B3 T7 ] printf("optr出栈:[%c]\n",opr_t.ch);0 Q+ P2 Q. Z! I; B' A' j" ^' O7 u
if(Pop(opnd,b)<0)
: Z( b' W- ~. Y6 F {
6 ]* X+ B8 P: f- u2 @% x printf("Bad Input!\n");
- S" M$ f( K3 T0 k2 ~! L fflush(stdin);$ f$ W' h; j% x( o: ~
return -1;6 N/ b1 g! a1 w, G+ u
}
/ l7 W' Z# J: Z/ e! h$ C! C printf("opnd出栈:[%f]\n",b.data);
5 y. a6 k8 a. P! G- b if(Pop(opnd,a)<0)
' F8 Y" u6 U- `+ k: f5 h {/ e1 z3 o( @4 J! k; F' u
printf("Bad Input!\n");1 i8 ~& X; S5 ~% {1 X& f1 @8 x
fflush(stdin);: D, W- `2 s% X' r/ ?
return -1;0 }6 W$ Y- D/ f& X* _& T7 ?
}; I4 |% q& W4 M4 `5 n( A
printf("opnd出栈:[%f]\n",a.data);
2 ~% ~2 o7 t* U2 P. ]# K opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
- C' j4 M- ?" {# S. S Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/; B- R" t) S6 }$ `0 o- }
printf("结果入栈:[%f]\n",opn_tmp.data);
# l8 _& Y7 W. E B- Q- | break;- a' q) }7 o) O! @3 p+ e; e
}- ^+ i$ s1 |9 v0 z
}
7 ~! J' n( w p8 {0 H& _ GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ , r/ |; E- U% `! p
}5 F7 \/ T$ z3 P3 C7 f6 h# [
GetTop(opnd,opn_tmp);
& `# d/ Z ^# j; t DestroyStack(optr);
, i: A8 C9 k+ g+ T& ~ DestroyStack(opnd);
, p! e% I6 P% m/ Z8 ? return opn_tmp.data;
, P6 K% ~' L) d7 O* W- @}
, d3 s, X* b) {4 Y0 Y4 ]0 R8 |
% y# g* M# G0 g1 Nchar *killzero(char *res,float result) m+ g- v. x" w: j2 H! |3 k% W
{
8 a" ?5 J1 z0 [ int i;# i% N& Q5 Z& g! P9 d# M
2 F8 w9 \0 w# V8 C* D, i! `- i2 G7 k
sprintf(res,"%f",result);3 K, K0 _' R# @6 Q/ z
i=(int)strlen(res)-1;, e& W8 @3 {& | w% q& t
while(i&&res=='0')2 f$ J! ?& l2 L- Y* s2 m# w- l
{3 Z. R D+ }4 y6 c9 Q
res='\0';- o8 d- e% ~8 [/ k' P* [( g
i--;$ c+ M4 x! F$ R. t7 w/ r+ M* H
}
1 n) Z; E& s7 x if(res=='.')- c# n) ], G: s# Q, S7 S$ _
res='\0';2 @: _% \1 M: W% V
return res;; E0 h/ }! }) d1 @4 Y: v
}
% k# L: r- A4 a4 s7 M% |
, D1 t- g3 |& P' s, xint main()
! d- w: r p" ?! n2 H' b' |! g{
% c. w: G, l/ \7 z char ch;
1 n4 H1 g5 L- D5 {5 Q1 R3 e char res[64];) j; s' O' S: N- ~8 X
float result;
: f6 @- w. K w, ? while(1)
' D: T3 f1 V+ D5 i2 p7 Q5 |8 ^ {
6 s9 M, L0 w! y! Y- h; n result=compute();1 k) e. h0 Z& @) K9 g
printf("\nThe result is:%s\n",killzero(res,result));
! B9 f L# }# A' U2 A printf("Do you want to continue(y/n)?:") ;3 q; o4 b4 m- R
ch=getch();3 p8 T; `8 D1 \6 h. a& O$ c
putchar(ch);
* {9 q% }8 P; D! G6 I% S6 _. \ if(ch=='n'||ch=='N')
5 r' ?& c9 T( \+ A; M* A break;# E( L9 `" [/ d1 u8 Y
else
5 X* r$ d$ X& d! w+ Z0 p$ X system("cls");
3 h" ^3 D5 |( S }$ q8 q) O4 c) _, ]
return 0;
1 z" q6 [' w& @}/ ~6 z, U" G% L0 u2 \# ~0 k1 l
* y( c( O- Q }7 b# I9 \. ~. L
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|