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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
# y1 i G. P! d7 n程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=% P ~: a5 G [2 `8 y
/**************表达式计算器************/6 \; A4 I0 E; w+ W+ X' d3 i
#include <stdio.h>
# f; C/ Z0 i3 T4 \2 u( o#include <stdlib.h>
4 X, h! h; O/ q2 W7 s#include <string.h>$ }& V& j" F* I G' @$ b
#include <conio.h>* i: C0 D# I! H
#include <malloc.h>$ ^8 p/ S8 X: r
3 s- b3 A" I: r
#define STACK_SIZE 100; F8 H9 K9 Y( }- l* I
#define APPEND_SIZE 10, G# R' b! o; i% J8 ^! c
% I, c4 x: |- W! l
struct SNode{
& ]$ l. X! S4 S% h' ]2 d a* [ float data; /*存放操作数或者计算结果*/! j; |# {$ i4 z" A9 b
char ch; /*存放运算符*/
G& K9 H u9 E9 c, B};
+ E: p3 z2 W' |4 z8 \
5 U2 a R3 Y2 {! M8 {" ]" ~struct Stack{
5 y c- p1 ]# T c0 }, j' A: d SNode *top;
# Y; _" l# j: x* J. X SNode *base;, F3 g3 h* I6 Q% k* l! v
int size;
5 r! D, e* Q/ p+ C' t! N# E};
. ?% O- L# }* b: e6 _/ n; X
. W# A# s7 \/ {* m0 d/*栈操作函数*/* x4 j9 \- Y6 M8 f l" M
int InitStack(Stack &S); /*创建栈*/
& q/ O9 h0 k8 D& h; dint DestroyStack(Stack &S); /*销毁栈*/
5 l5 L. v( x7 H. g/ mint ClearStack(Stack &S); /*清空栈*/
2 X( ]9 a7 h5 o& I, rint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/, {4 m) s$ o; ?, M' w7 Q
int Push(Stack &S,SNode e); /*将结点e压入栈*/4 E* n1 Z3 W. t# _ ~6 P
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*// J" P: A! y8 \4 E! S( J
! a0 W p& }8 e' l! ?1 C+ h( `
/*表达式计算器相关函数*/9 @; R5 f. o( ]' o4 N: w0 ^4 W4 u
char get_precede(char s,char c); /*判断运算符s和c的优先级*/1 t# O6 ` o) Q
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
! |; {. u7 ~# y# Ifloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
2 k6 U9 h1 {' S% w/ ~! [6 N' @) tfloat compute(); /*表达式结算器主函数*// W6 e; L. T' h* P
char *killzero(float result); /*去掉结果后面的0*/ 1 I, h/ f! k% g3 J0 b2 A
. C& z+ O. ]0 dint InitStack(Stack &S)5 |* o6 W$ y- @/ c9 n% y
{
3 a+ J! b. P3 p' \1 h# U: c* z S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));) c& Y. T3 z$ m
if(S.base==NULL)
: r; ]7 f2 D9 U- L6 \ {
0 K' z" f3 }2 J$ t( O printf("动态分配内存失败!");
) W6 P: ~- p8 H2 ? return -1;
- L- y& n6 ^2 B1 K1 y' ~ }
& E# _9 E( ^/ Q4 T3 P& Y S.top=S.base;$ m A0 ^- P- ~( e
S.size=STACK_SIZE;4 x7 N$ \0 y" _6 ~2 t0 b, A8 m
return 0;
& ]* c g$ K. _ E# [ t}
; |# W l. n# Y, H9 ` s) U
8 {; b8 o$ K7 m. zint DestroyStack(Stack &S)
8 m9 X! w8 D: m4 J$ Y{
. k2 s# g( Q$ p3 ^+ k free(S.base);: I" D4 z: B" Y) Z
return 0;
6 _# t% ^! J/ c+ W7 @, Q! [3 Q}2 Q0 @) h, f( ^) j8 }
; ]! R0 U7 n. ]( Hint ClearStack(Stack &S)( J& w# }3 E; O. H- [( |. ]
{
% d. F ?/ t& M9 w S.top=S.base;
" \2 Z- P! U/ H. U/ b return 0;, Y" P9 U$ }( b! p
}
' R* p# v" n4 Z7 Q) @* e
! m- k6 P( l9 S" i8 Q5 y- wint GetTop(Stack S,SNode &e)
# N9 A( X+ K' j! i* P8 @{
- B4 v0 G6 v' a+ ~. Y if(S.top==S.base)
+ z7 Q1 \3 H ~( x5 c7 K {: J, Q+ O& ~& ] L
printf("栈以为空!");
3 g$ E6 F, F( G( M0 e1 C return -1;
' @) u$ g# x6 j* \ Q }
- s% I) C: K! J/ ? Z# ] e=*(S.top-1);& i9 M$ z* |6 s* g0 m
return 0;
1 Y9 g3 I( p# X9 ~$ K- o}
% l- j: H o1 H" h
+ W+ ~8 G/ a0 d% x. ?) Wint Push(Stack &S,SNode e)
3 g0 {6 h8 M. Z5 u$ Z{
$ o/ r( A e) l+ @ if(S.top-S.base>=S.size)
2 X3 X6 x* S: j8 f' Z' R/ ~3 ^% M {
, w# o U$ U6 v$ T$ f8 ~) K S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));. S8 J; f1 B! D# ]7 \% g* j, j' u
if(S.base==NULL)
; ?' f5 i! K# Q4 f {
) l) l" j8 I* E printf("动态分配内存失败!");
, r2 H0 z/ \# u return -1;
( a/ K4 {9 S& {3 O6 y }
3 T" d1 s) [5 k6 f6 z$ I S.top=S.base+S.size;
) w# g9 r, J; T2 D" y/ J2 W4 n) [6 K S.size+=APPEND_SIZE;
, O& b Q6 C( | }
' i6 h, {1 s3 k7 ?, U *S.top=e;
8 h$ t& @+ }( \) ~; d+ w/ t4 F6 { S.top++;3 L: [3 n' U6 @2 D; J+ c
return 0;
2 S6 W; N$ E, I1 B, g}
& ~1 c, G- }/ j) V$ H* `
* C8 ], C- T. {, nint Pop(Stack &S,SNode &e)- c7 C) r; v* f$ x1 j4 d" G
{
7 G/ q o( i5 y0 ?3 {& p if(S.top==S.base)8 K/ Z0 L# z8 ?8 ?
{, @# T# w; P. Z$ C3 V# W
printf("栈为空!");
/ ?% o, A$ Z! ^& T return -1;
. M# i5 y$ h* X }7 _0 B) w- _: I7 n/ z
e=*(S.top-1);2 s9 W* x5 R( P& m- t P
S.top--;) p. f0 p8 u3 L' L# U
return 0;
" [- V3 X, j; v}9 O( a) v: Z( M0 o$ U. ^5 p
^; D, G* b2 ?; h* }0 L+ {, L/ n4 \! b
char get_precede(char s,char c)
4 R% A3 m) ^) X/ y$ r{
- m2 t/ ?9 A% T1 u4 m switch(s)
K; u! E' `- d) B( v {
3 r2 W6 _+ T, F4 z3 }' R2 E' T case '+':
+ z3 y3 M' _& X1 E: a$ S case '-':: s$ y) ]2 A7 p2 A; w1 L
if(c=='+'||c=='-')/ R/ n: G, e+ U4 j" f0 ]
return '>';' G+ |$ y$ H+ ?- M0 z( ~- L
else if(c=='*'||c=='/')4 B, N; n' H: [+ ~' K. q6 C7 \) N
return '<';
5 x$ F, [1 O' D) I! ^ else if(c=='(')
; u3 ]* K) l+ g' U return '<';- K6 y( i7 ]: ?: q E4 X
else if(c==')')
* }+ ~' K# ?9 @ return '>';9 c$ x$ A4 @# k) C" Y2 u& n/ k9 m
else
* h! F$ V) R/ y# G return '>';
4 U5 b& n; T& m$ }' i case '*':
8 f6 @2 D2 z) x case '/':
3 b# k2 m2 t' O& B0 ], A if(c=='+'||c=='-')
, J- h# g5 M# T& R. n return '>';; i/ Y; J3 U! d& J
else if(c=='*'||c=='/')' v* C4 O& b: {+ n8 r' W
return '>';
, E' x; c F+ {, P7 L0 J9 h9 d else if(c=='(')8 |3 j4 y( o. Y9 o1 h. p5 ^- H) K
return '<';7 Q3 }8 A5 s3 v) V( Z
else if(c==')')) k) C$ k2 z4 x0 s
return '>';
# k: N) v I0 @4 s2 | R. F7 v else
% i x# }: }0 `2 s0 K) I z return '>';
" \0 x' e1 v2 @ L7 x- ] case '(':
) k. X8 q# [0 r( v if(c=='+'||c=='-')& d$ b+ D6 {' X) ^1 r* U
return '<';
0 g9 _4 }% i9 t# B( t' X( Q9 g else if(c=='*'||c=='/')
; I3 J, h; w2 l( Y9 j& ~- ~# o6 w; @ return '<';. r& P$ Z+ V( M z) P2 Y
else if(c=='(')
. ?+ Z' f8 s% C return '<';. Y c, [6 m# X1 Y6 P5 U
else if(c==')')9 o2 m' Z5 v! S( c4 E o4 s
return '=';/ _6 W$ V5 l3 I D7 v8 ]- i- k
else' ]3 D7 g# G) b0 j7 W- i* J
return 'E';1 H* e1 u/ ?, j7 t: L2 x' q4 n
case ')':
/ M9 B! B+ g5 P% o7 k2 C1 T% t! W if(c=='+'||c=='-'), @* E" P! W) I/ \
return '>';
, \ L$ b5 _7 B8 Q else if(c=='*'||c=='/')
- {" Y7 ^/ l7 _2 ~4 w% t: d return '>';
+ w8 }- F% D3 n7 ?- J5 H! Z4 W2 v else if(c=='(')
0 d8 K( K8 I+ ?5 A9 j0 j+ A return 'E';' W$ K7 e. _7 w6 b( r8 k, V( G
else if(c==')')
" `4 k: g, }, `! n) O return '>';
+ j, i" `$ A% L. H& l5 N4 L; G- f else
2 K5 [4 ]# a0 ~% n% l- X9 J return '>';
! D7 h* ~6 g: @, Q |0 H: v: @ case '#':4 `" |6 N; K2 U, `
if(c=='+'||c=='-')9 V/ D5 R# t+ L# q" e( H
return '<';
! l: E2 W j" ~& z else if(c=='*'||c=='/')
' H3 o+ T' g. c5 X( O$ t3 f( @4 M return '<';6 i4 D7 O; |7 q S! ]9 Z
else if(c=='(')8 T7 m6 r# d" }* [1 N
return '<';9 j# y7 K8 q* D
else if(c==')')
" Y+ ?' @0 R5 I4 \6 w* q return 'E'; z9 N! G C* m! \( E9 j! O9 [1 h$ j
else
) B [9 b4 i2 n4 ?1 H5 E return '=';
# M# B' H9 _- N' N default:: \* j) {3 h2 @
break;
8 n; z' N8 b+ ~5 s }. _; u F: g6 N
return 0;
% L, d7 }7 r R# b1 i}
5 X: e: [; K9 T. l' V' ^: G9 _: o, ]' C; [! L! I
int isOpr(char c)
, Y! [( S5 p# K! @; G{
2 r+ r3 {- D$ _6 a0 o if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
. q6 q3 X+ Z" r0 B( v+ M return 0;
7 |2 x c3 R* k) Q else 3 w K% K- T( B9 R) B3 o
return 1;
2 J X S C$ g4 l" O% n6 ^}% ^ g( \) ~3 L' e: C; i& {$ v# o, z
. L" P1 @, l; a, }2 v4 H9 p8 m# R% Bfloat operate(float x, char opr, float y)$ i9 E' }' m3 x- o! `
{2 c& a4 H$ _+ C! j/ r8 r
float result;- J& ^( q7 B* ` ]! b7 P7 J3 v
switch (opr)3 g" k9 R; G* L
{: U: f' X& m( x0 U) j3 U. q
case '+':
) M# {9 M" o! v0 k, o2 ^: C result = x + y;
! r; {5 ]/ U& y& d! K break;( J' n" p8 q, B, a
case '-': 8 S9 ?$ d; y: B4 V$ \$ M% j
result = x - y;
4 S. C0 s/ g7 R( r break;; _ y O6 d( _+ a
case '*':
' K$ u4 v( T6 z1 g result = x * y;0 H4 B: B. A0 j8 z+ e; H
break;
9 i0 C: L5 @! _0 Z5 U case '/': 5 D5 t- T; N- T4 ~ R( M: f& K2 n
if (y == 0)
) X! A* K. y, g( y0 ^ {6 \4 U' p5 D# B% N% z
printf("Divided by zero!\n");6 I5 [1 V% q" B& a( H' O( F
return 0;' r3 y0 J4 @# R
} U8 }9 @& ], g9 A2 n
else
7 I6 T, y5 u; F% _! s3 E5 o {
- f3 f0 ` y1 B$ ~3 v result = x / y;2 T" a0 u" R# D( _7 N
break;( v' @+ D/ o8 H+ u% N) N
}
3 v# R Q% W! B- M q default: % g, ^# T1 D9 N) d& V
printf("Bad Input.\n");
+ _4 T$ a4 l) Q" P return 0;4 r! I% Q% A* o, n2 I E
}/ x: O: d& \4 e& Y+ h
return result;. A5 u+ h1 n* k$ G3 \5 z8 f) o; ?
}
$ J, T" m9 a. {& @' c
: _5 G+ v3 ~; i, A$ v2 ]- bfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
; l" a; a4 ^/ `/ u" u2 H1 I{0 g$ u4 ]' J& x6 G' o7 g2 |: K
Stack optr,opnd;
2 Z4 r' r6 j% M( ~; E( z: ?+ t struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;( K( H7 q e0 _. x9 l
char c;
9 \, c$ I, v% I! ]4 x% u% a3 U% V2 n char buf[16];2 k2 e M- W( }. e/ q
int i=0;
! U9 \7 J Y* k) l+ k2 f, w. A) `2 u
- s: ~- F. y8 p5 k* Q5 j5 B InitStack(optr); /*用于寄存运算符*/
5 o5 M# b' U$ F6 R: \+ ~) k InitStack(opnd); /*用于寄存操作数和计算结果*/
* I; w& b7 V( B" p. ? memset(buf,0,sizeof(buf));
# h& C! F2 N' {, R4 q8 b 6 ]& h- R6 p: z& P
printf("Enter your expression:");- T* p$ c7 w" K1 n. t4 K: a& F; p( F$ q
9 D) J! G ~6 V/ y+ s* m; c
opr_in.ch='#';: S/ w- E9 R; i/ q; F$ f( f9 l
Push(optr,opr_in); /*'#'入栈*/
7 q5 V7 Q% H, ?. B GetTop(optr,opr_top);
i% A, P! p: y0 T! Y$ w( T c=getchar();5 k# q; U M$ \, L, c' W
while(c!='='||opr_top.ch!='#')" y" g) x* W3 `9 x+ P3 w8 R- w
{3 i8 b* J, s/ u) F3 G
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/- ^& K: G0 S0 m$ S# O' Y
{; w3 W$ j5 k6 C! F4 Y
buf=c;
! L% T" k# w: Z. D+ t; _ i++;
& A- b& A w! L3 ~ c=getchar();
3 `3 T8 `5 |9 L$ }: G }
/ D; c* Z' J# k. F8 j. W else /*是运算符*/
9 n* o* q- _* d& v. {. q& E! x {
* D$ p t, ~/ ], H buf='\0';9 u0 O/ v: X! Z; Q. n
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/9 e' o( J3 G. b3 q' ^# q" o
{7 r* E( D) _5 z! H
opn_in.data=(float)atof(buf);/ i# e: K& i* ~, _8 K
Push(opnd,opn_in);
0 t8 c2 {3 c2 T. } printf("opnd入栈:[%f]\n",opn_in.data);3 M" p0 x0 }5 P& H1 K
i=0;# ?3 K m; U: f7 T+ A9 Q* c3 g
memset(buf,0,sizeof(buf));
; G* I, Y( N, `" E# H- W }& I' \) X' ?. V( F2 R' \* [
opr_in.ch=c;
: ?$ i+ r9 O7 x' m K+ j6 z2 n switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/2 K/ f3 W- p( ^ K" u/ A
{
7 \/ P- A% G( E$ Y case '<': /*优先级小于栈顶结点,则运算符入栈*/
7 G* n1 A. ]) T, d. [% K Push(optr,opr_in);( H! u+ m" }! _
printf("optr入栈:[%c]\n",opr_in.ch);( z: f4 b5 o9 \- R8 p
c=getchar();
8 N Z9 P/ w( {0 H: x break;1 E( {3 t) \, @& i/ K
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/" t: m. N; v/ {: q
Pop(optr,e);
5 _% V& z" J+ t* n) d. i printf("optr出栈:去掉括号\n");
+ N, i% d' d6 [$ r c=getchar();) H& S2 s2 I- a9 v! L
break;" [0 ]5 N0 K4 o* y$ X. c& @2 b# a
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
# L# [* d2 J! d; J1 w& Y8 r! T Pop(optr,opr_t);/ j* Z3 b- N3 ?5 q. l6 P* W: ]
printf("optr出栈:[%c]\n",opr_t.ch);3 w, \3 k a( @& H$ k+ }* ?
if(Pop(opnd,b)<0)
* R/ A" l& a3 H% F7 [ {1 G; k# F8 O% y' B: a# k* o" W1 c' x
printf("Bad Input!\n");
3 y: k E+ k0 a* T5 X v fflush(stdin);$ A9 l% ~- g5 E. H- {6 s
return -1;. ^, O3 s' B, P* k* R: [
}
3 a+ i5 t. d" s, @" ?! v printf("opnd出栈:[%f]\n",b.data);7 k: t o1 M' E s1 }+ P4 B) Y
if(Pop(opnd,a)<0)
7 m# x$ N; T1 g2 I7 K. `% p8 U8 M {
$ W/ n' z- b ]1 j4 y# f printf("Bad Input!\n");
$ d2 u- D. ?$ Y fflush(stdin);& O1 m) L/ z# q" o) o, e
return -1;
0 O( z+ X3 k& S5 {9 f }
; X& {* y- l2 i. O0 }& _+ j printf("opnd出栈:[%f]\n",a.data);
- m9 Z+ w0 ~( h4 C opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
! j! A0 ^6 f3 L Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
4 K! ` f2 g9 k _/ k printf("结果入栈:[%f]\n",opn_tmp.data);2 g# X5 t6 D# t7 b, M
break;
+ l: S* F: X) w/ ? }, S1 Y0 `6 _4 U/ z% Q$ X8 \% o+ z5 X
}3 Q8 ^4 \6 c% r( _+ d
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
7 @1 H9 `( x, O, ~# ~2 b7 A; ] }( n" t! o1 T, L" \; R5 M4 p2 W4 w( `# M
GetTop(opnd,opn_tmp);
2 |# n5 b$ Z: @ DestroyStack(optr);2 s3 Q \2 ]3 ~( N; s% T6 s: g
DestroyStack(opnd);
7 f, A/ S5 |; M. e return opn_tmp.data;/ o3 q6 n0 B) ]. r+ J- j
}
4 J% { e6 M3 [, m9 K1 b Z
/ g' {9 V8 y0 c/ v" i' m1 H7 Rchar *killzero(char *res,float result)
+ T. c3 i" U4 z2 _9 p( A9 s{
0 j! Y! u5 x3 M! U, [6 U9 ^ int i;
$ V! e$ Z2 Y7 ^: l ^( ^4 l5 @7 C
# ?6 H; Q, e! i+ f sprintf(res,"%f",result);
% ] g, T7 t/ i" S2 g i=(int)strlen(res)-1;
4 G0 J, n! T, {6 N) ^4 O2 t( z* g while(i&&res=='0')4 e% b5 G7 F. K, ~' `. Y
{
1 x3 c$ Z1 F0 [- B( W res='\0';
9 q0 w! f; w+ `" ~ i--;
& F6 [+ w% N2 p3 k6 g! E }
/ C1 h. T; N% ~+ ^8 z2 G; x if(res=='.')
4 ^# l; Y( _5 M) O# m5 x" A res='\0';
, @: n2 K6 z# X+ [ return res;
, V7 n' [1 K X/ c1 h, f: S}
/ ?2 n; [% w6 R* }1 _1 \- B( }; b/ l/ b+ c% M( A7 `) H9 S! H9 {
int main()% C* o9 G+ i% ~- @+ [) O# w& p* G
{- F+ b* O; F0 E) J, |0 Q
char ch; F5 @ S' I5 I
char res[64];. o. H# \4 I3 @' C0 ^& G
float result;/ F4 `! ]8 A: H, Y5 u
while(1)8 C' ~* J; J2 E3 G& H/ f- v
{
3 `; B5 R: S9 G- p result=compute();
; D% i1 u& a% h: R0 j printf("\nThe result is:%s\n",killzero(res,result));1 q6 F, w! ]; ]* t# }- S! q
printf("Do you want to continue(y/n)?:") ;" I# m* e7 K5 Y, }( J7 ?
ch=getch();( F+ U% p6 E% s
putchar(ch);6 V) D L9 m3 Y( p& S1 O& t9 L
if(ch=='n'||ch=='N')
- a, v @- ^3 M9 Z0 ?7 X break;- [8 A! X9 G9 e+ h& c# {
else
: L5 ]2 H3 w* a: }$ ]1 Y$ x3 `3 k system("cls");$ O) G+ U* W# ]6 E
}# y9 Z/ [ F0 {
return 0;7 \1 M: ~, X( y/ v! ]+ T# J3 I
}- k: ~8 @. X- v, c/ X2 V5 r
/ Z+ ]; s U9 _8 g n% P
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|