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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
& f- @2 {2 T, q' @0 x程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
4 z. Z# C: w8 O# i: H/**************表达式计算器************/7 S$ d' v% H6 o5 Z
#include <stdio.h>
$ H7 K5 K G, t" G#include <stdlib.h>: a* `% v, @& Z1 b, K2 K( o
#include <string.h>
1 ?# o; S) H+ N#include <conio.h>/ Y6 x# c$ F4 `! v; }; h
#include <malloc.h>' y8 O: U6 e, b! G- j' n
6 c6 u2 p( A9 ~* X, c2 h3 r3 b#define STACK_SIZE 1007 M: O+ h3 R4 Q; e, w
#define APPEND_SIZE 105 d' g9 W" P ?
* F0 B* I& x' I# D- c, Z, B. ?
struct SNode{
+ _4 G4 p6 R+ e float data; /*存放操作数或者计算结果*/
5 v q1 N( @* F6 C j, | char ch; /*存放运算符*/
. M j& S5 |9 U1 ^: S. g# `. }. M};
' A4 K# b( O3 D+ d, I
4 [7 p; V$ W% m- k. _2 {struct Stack{
- D1 w( {7 l8 O; D( R SNode *top;
% g* ~! O$ J: b& O: S SNode *base;( D1 L5 R) F4 G( j. |5 j
int size;
3 ~0 O( _, K/ i J( r1 C4 i};
& }* b2 S" h8 ?
+ w! M# r8 H( F( L+ P/*栈操作函数*/+ C4 m4 ~# C3 V* k& x
int InitStack(Stack &S); /*创建栈*/1 c! X! E+ R7 P+ z' Y4 ]4 A
int DestroyStack(Stack &S); /*销毁栈*/
0 |; u- l) \+ H# d! F4 t, g0 `, c$ \int ClearStack(Stack &S); /*清空栈*/" b9 m f7 K" H# L- E. f
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/( _0 p) f9 V/ }2 q! q3 Y) h
int Push(Stack &S,SNode e); /*将结点e压入栈*/+ ?$ N. b0 W! c( x. J& i+ T
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/2 u, a5 J& Y) S7 n7 X
- n3 z, p9 l' Z3 a& k% y/*表达式计算器相关函数*/2 h( V! n G* n" L3 I R3 ~4 Y
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
# S4 S1 s8 S* Z6 M* cint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
7 t5 a" g; `, y' T6 m' E# @float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/' s0 w3 y! P R. {# |+ s
float compute(); /*表达式结算器主函数*/
' b+ O1 h' c: j2 Xchar *killzero(float result); /*去掉结果后面的0*/
4 \0 Y- ~" [6 ~. x
- s. G- w& v, d2 lint InitStack(Stack &S)+ k& Q3 J1 Q( s5 S8 @2 a
{1 |; [' s( g3 C( `
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
_! ~' j0 \+ p9 h2 _ if(S.base==NULL)
& I- k1 J \$ b- S$ ? {
' f ? D! I' H7 X printf("动态分配内存失败!");
2 P" ]. g( `& w) f return -1;5 Q5 k! Q7 b3 j! x: S a* N
}( g/ I2 [. L, |# \" h
S.top=S.base;
/ t4 s$ U" \5 T, v# {" O& I7 i S.size=STACK_SIZE;" K) c7 B& X. y4 Y
return 0;( T' j6 r2 k: [& |
}: j8 E5 _4 I& K6 o' v0 t
$ G+ p- Y& O$ ]3 A. L# T
int DestroyStack(Stack &S)
% g) o: f# z8 K1 @! o: c) _{$ a9 X, f( R( ?6 M% \: `) `
free(S.base);
0 C$ q- s3 a* A- a return 0;
9 @# q+ R. v" d/ u8 s}
j5 n4 V+ U5 h, T% [0 Q% [ {! |& x! F) w0 v% o1 `3 v
int ClearStack(Stack &S)
2 j$ V S2 u1 {$ v) y h2 A- N{
; y' o( Q* g! n0 K6 P4 ` S.top=S.base;, U* A8 Q3 G! M& O( U. H
return 0; b% b* q) V1 q9 d; [# z) _' D
}% v5 ]) a0 y( N! n" T
) x! _; Z4 u" t/ F) I& s6 dint GetTop(Stack S,SNode &e)9 g3 F. c) j+ ]; C& S# h: l- }+ f
{
/ ?! P/ w1 [ Z1 H+ u if(S.top==S.base)6 U1 k$ D" u' k, e- k
{9 }9 }3 f8 h5 v0 h) n: `- e: _, b
printf("栈以为空!");: A/ n: o7 { t1 `' v/ p
return -1;
- M# l3 s. _. o) u" s$ X: d4 Y' D' g } W$ {% j' ^6 h0 r) Q
e=*(S.top-1);
2 J# R/ J& U7 J return 0;
; R9 V, g+ ~2 I) g}! K' Z- Y0 O' T5 G, s: D. _
* c- u4 D5 u' O( a0 C+ e6 oint Push(Stack &S,SNode e); d$ c$ v, {1 P9 r4 q+ W2 I
{
% y4 |6 w( }0 e' I$ m if(S.top-S.base>=S.size)6 Q2 k: k( N3 o1 w1 M+ J. i
{* ]5 D3 E! p! Z0 r- [- c8 I3 N. H
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));$ f; w; B) X( d4 P/ q$ g- m3 R
if(S.base==NULL), d6 J( ~+ M9 b' |
{: v- [ V! t. W
printf("动态分配内存失败!");
4 v: C" _: h, Q return -1;
% Q7 W5 o+ R% H' Q }( p3 p" b) j! t& l+ V/ J
S.top=S.base+S.size;
" ~2 f2 A" H- X/ I5 U S.size+=APPEND_SIZE;
5 [* \, @" i I# v3 |' {/ {% v4 h5 E } q+ z w8 s* \. p! j! J, J
*S.top=e;; V8 o2 X( M. D" E5 ~# z
S.top++;
`8 S! n" v x( u) m( l return 0;
6 G8 k2 U: }" ^! B9 g2 Z}
# }3 b1 Y7 R% u0 T9 a& d( j- {9 ]( }
% B1 b' u: J/ o6 ]" }7 ~$ Qint Pop(Stack &S,SNode &e)
+ ]" H* K6 k3 ~6 m{
u3 g2 ^7 E/ o6 h, R4 k, [ if(S.top==S.base)" [! e5 ^6 Y1 Q5 w4 a4 b
{5 q" I2 ~ Y, g3 _1 X. F
printf("栈为空!");9 c3 v, u' f( q* N1 T% o2 N
return -1;4 i+ I; c* Q( E3 H# p4 v
}; v1 ]1 K+ Z* F s& v' s0 }" }
e=*(S.top-1);8 ^$ W, |0 {- v: i
S.top--;, O" D& _/ t1 p; P
return 0;
1 R+ j7 K% Q1 q0 r- | S0 x}# p0 |# s/ c, E3 T1 V3 n
. `5 F5 Q& \4 m6 V" }5 U
char get_precede(char s,char c)
5 W4 U% o' v" A |) ?{
7 I+ m& [% n( ^4 W( g6 G& k. m$ m2 J switch(s)0 Z2 V4 ?# Q7 z. U
{
! ~! ~3 J' O" ~; Y+ e7 t0 \3 A0 k$ ?" E case '+':
5 h5 E* @) T6 h4 x0 b" y& D case '-':
n6 ]) X( {+ \+ g. L8 h if(c=='+'||c=='-')! n" n* ~7 L9 T0 I. a/ M4 ~
return '>';
0 |4 g0 j0 k: v: v else if(c=='*'||c=='/')8 u2 W& Q: n. m
return '<';
) _% J) R0 T+ `! u1 l, a( d else if(c=='(')
8 e& f" p/ ]; }2 Q return '<';
% k" F+ T' U: {; z; J8 d$ W else if(c==')')
: E$ s; Q( _# o- D return '>';
- Y0 W, `% s$ K' y8 [- w else
$ z' Q) c5 l7 G% n T5 w return '>';
. p9 U& t9 S) q) R( ` case '*':- I* v- u" _9 o( c: D c
case '/':
; X0 O+ n, x3 q( m" _+ n if(c=='+'||c=='-'). d9 U/ |; W3 o& v7 t w
return '>';
* c& p/ J: ?$ ?) O1 u else if(c=='*'||c=='/')
' Q1 l6 g0 m( U' r, } return '>';
* h% ^- d2 ? }. u' |; c else if(c=='(')4 y+ W( v- \6 ^
return '<';$ M1 s4 G& B% X3 p
else if(c==')')
; H l5 Z1 D: S! }/ I: d return '>';
! [& B- ~9 {1 y6 { K else
! J# B( P$ z, Z& Q; I% _ return '>';
% v. u+ c' w, C7 L case '(':" Z7 d' [* W4 R) {& [/ c1 w/ k1 c
if(c=='+'||c=='-')+ C- n& k K, g7 R1 e9 \
return '<';
: q3 h& C1 K2 F/ J9 T | else if(c=='*'||c=='/')
( e6 |1 E) {& f2 [: G return '<';
& K2 g7 R0 S) W1 K* m) M else if(c=='(')
; i! b2 `0 e, S( k2 I* Y2 } return '<';" R5 ?+ z. `6 {5 @7 G, o8 F: b
else if(c==')') ?8 d/ |/ h& o- }+ o
return '=';8 C* Z6 m- Y5 ]! @( n# J
else5 b7 [5 [0 X. V% W+ [
return 'E';8 V# g' Y- f! A& V: D! W0 o
case ')':. k+ ]$ j8 j0 \5 C1 F& {5 v0 i$ Z
if(c=='+'||c=='-')8 g O8 f$ z3 @
return '>';2 b3 q- c4 | H+ k
else if(c=='*'||c=='/')
: _5 o5 y, J! ^ return '>';
1 p% K7 b6 @& _3 D5 R) g else if(c=='(')! { z+ Q4 d% K3 n7 _9 R
return 'E';
4 U/ C+ ?: w; _+ V: f/ A else if(c==')')+ v7 D2 L9 O" z( P) t
return '>';( [) C I+ R: t" J( p" E/ P
else
* s3 h' B1 D3 ~ return '>'; j9 I1 e7 Q* G4 R" J" s2 j! E3 g% F
case '#':3 I* @: k. E! z/ @: k+ h9 i" X1 O b
if(c=='+'||c=='-')3 V" r" y! A0 w" |$ ^2 H% O; H( |
return '<';, g/ _" T: _- J0 W9 Z# j$ I
else if(c=='*'||c=='/')' v N' S8 [1 w' H
return '<';
; a/ m2 h5 r& Q else if(c=='(')3 A- n2 ]2 G; Z$ U* T% {4 }: x
return '<';
- T, z/ Y/ A) x& O* ^ else if(c==')')
1 f* ?5 ~, T9 u j* ]% y return 'E';
@, q) n( n) R/ o: p else
g. d. \- V; y7 X5 ?" H6 T return '=';
) _2 D" @5 l6 B9 U& W default:8 u) e( h: V: I# S/ C3 y& w% H
break;- y+ M: O- O& O- W
} E3 \. U! ?' ]: B3 w
return 0; 6 M# j1 s2 S! ]7 q; K) I
}
) n ^ K4 o# G$ w9 o+ p
1 C2 b/ l, N5 p' b4 a5 I) t- xint isOpr(char c)
% H# J2 O: g( p% ?{
& u9 U) b: ?. n$ z if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')% S9 _/ N f* U/ L# i
return 0;
7 _4 x4 X C8 T$ l( ~ else ) }, Y/ I0 P6 f- P* i1 b
return 1;& p* F+ ]$ a- x9 f6 O
}
0 j% y2 I/ s8 C4 ? e2 q: x, e/ L j* a u, P
float operate(float x, char opr, float y)0 k1 v! I' t* q
{
$ }. C G7 B- n float result;
# `7 S4 a. j/ o switch (opr)8 |2 Q, M. L: M5 l4 Q. L
{. R6 K* J# [. t& n
case '+':
* D b1 ]8 Z3 ] result = x + y;
1 f; I* ]6 L; \1 C. e, ` break;9 C; v5 a& B3 B4 z7 _5 a# ~8 b2 E
case '-': 7 j5 f, E, f F9 X
result = x - y;# g$ I" K; B6 n9 H2 \2 @
break;
/ C' g- a' Y0 H0 s5 a case '*': ! R+ M+ l& V' c7 b) ^. j+ L6 L
result = x * y;
- R. V5 w' c3 \; G break;& `! G1 B& e! D0 p
case '/': * W- a) r; @. K( r
if (y == 0)
! ]- Z: B# \ `/ z {
7 O2 k4 u0 v$ j printf("Divided by zero!\n");
' y- F9 d7 o, Y/ U return 0;
6 I4 H8 ^/ n- A, y4 M3 |) O }
; J7 S U" w: l& w+ b else4 O. f( E1 W( l |+ y
{+ Y" i* t8 ~* }4 i) z% T
result = x / y; i. X R, m% Q# u" W3 b. d% o
break;
" p0 X: [/ a; M3 r% N% B }
/ n: J" U/ [) @' J default:
% m8 ]/ a+ ^1 T* K- D% g5 j) j& F printf("Bad Input.\n");
, a8 Z7 j) n' Z return 0;7 s2 t( T1 @" `7 M" x2 k+ R5 Z- I$ s
}: d. H0 t6 j9 z/ y; V8 Z/ B u
return result;
; R0 x$ {8 E* g( L* L% S* o}
, @* S2 O; L$ w7 G
: t, n' J4 n# ?2 q6 Z$ G/ e/ {float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/$ x+ L K2 E2 P$ l, v! w
{4 s* B4 [4 }7 q' ~ [2 L
Stack optr,opnd;4 y$ F, F) \4 M; |
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
- E' Q$ p. B3 t7 H char c;
# [" o) X4 ^ P1 a, N6 b char buf[16];: Y# `8 n/ y1 T: H9 X& V
int i=0;
}3 B2 o8 k& t0 j" X! `2 L) g
: ?# M6 z/ y. x+ }0 _( U+ ] C9 j InitStack(optr); /*用于寄存运算符*/" \4 z# m9 P1 P' {
InitStack(opnd); /*用于寄存操作数和计算结果*/4 N* x$ m( y4 Z
memset(buf,0,sizeof(buf));& c) g4 N4 R/ v# k* E
9 e1 A- C7 V* I1 e& S+ l printf("Enter your expression:");/ j0 O z6 N/ [' W# Q5 {
8 c' X! a7 ?" @ p Y8 ]& a* z
opr_in.ch='#';8 q6 F" T9 O( s
Push(optr,opr_in); /*'#'入栈*/- J3 }9 q J7 U* z- B
GetTop(optr,opr_top);
+ `" u& W7 M7 `5 @. O& Z c=getchar();
' W; P% q- N+ n; O b1 x( K- P5 g( O while(c!='='||opr_top.ch!='#')3 l$ Z1 A: ?9 {( Q7 V
{
* b5 U \) q. [/ W( I if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
: _/ D4 b1 t0 M! X) B0 E. N% M* F7 j {
8 r6 r4 m ~2 E D' p- E8 n1 U, R buf=c;
, U9 t2 N4 W' k) d8 {6 c i++;+ R' U4 Q3 h7 A- {
c=getchar();" [. i3 [: d. N! t( C# M7 F1 ^) n
}
3 i& {, Z* S$ t, H( w2 ? else /*是运算符*/0 X& ?: @3 C7 J/ A. c4 |
{
+ U# @! `! `+ ?9 X- P buf='\0';
4 k! ~- [, w6 \, H9 ] if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
# Z* [+ W+ R( V, p9 M9 @ {
+ s2 m# Q4 c I+ e$ N: L$ t opn_in.data=(float)atof(buf);
9 P: n. |! P# M$ ~ l Push(opnd,opn_in);6 U% Q" i+ k. l1 {; N6 w6 k; B
printf("opnd入栈:[%f]\n",opn_in.data);
, I* t% R" Q7 F# J i=0;' `' [, o7 U' H
memset(buf,0,sizeof(buf));$ q5 ]4 w0 W# s* n
}% @6 {, ]. D$ t
opr_in.ch=c;& k; [- w4 h4 }) o
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/8 l# U3 }# z4 T) ~
{3 l p( ~% k. K0 D6 n, n4 R ^
case '<': /*优先级小于栈顶结点,则运算符入栈*/
/ ]4 K7 K1 G1 d Push(optr,opr_in);8 X" O& u' J/ C$ q8 V$ z* b
printf("optr入栈:[%c]\n",opr_in.ch);
& P' q: t: k. K7 y1 u$ o c=getchar();! G1 a1 @6 ]6 i% \
break;
% ^- }7 a4 L9 p0 G! _ case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/' d) q/ Y" {7 r) A5 R4 |
Pop(optr,e);. Z2 O0 j' g n1 c5 S5 g
printf("optr出栈:去掉括号\n");3 D! f0 f+ M4 `( T' X
c=getchar();9 R1 Z9 ^9 `' A! S8 E
break;
. j! F: z2 `4 l9 U# { T0 H$ I; b4 Y case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
' W8 o9 Q9 s) W( M; ~ Pop(optr,opr_t);
8 n$ u( I, `: k% Q; A printf("optr出栈:[%c]\n",opr_t.ch);
- n' o4 }& p" \) I if(Pop(opnd,b)<0)
; H m1 S: W; x/ f" m3 e c {3 q- f- |* A' f! O
printf("Bad Input!\n");
$ \8 H8 J4 h8 `7 Q) t7 z fflush(stdin);- _- U- e; c4 R# a1 O9 h! z; W
return -1;' K5 D" p* c% X
}' e8 l) O( {% }/ b% |
printf("opnd出栈:[%f]\n",b.data);* V: f8 P; W0 E
if(Pop(opnd,a)<0)1 C: C; N- J+ }# M+ d- a0 c
{
5 i5 t' F: n3 ] N1 N* I- A printf("Bad Input!\n");
7 }% \+ |% ~1 Q1 D; d1 @* [' [/ y' a5 @ fflush(stdin);) _! R2 I& L5 E8 `5 W; X
return -1;2 U6 ^' y# Y$ _
}" [9 F4 f/ g8 v
printf("opnd出栈:[%f]\n",a.data);( n' `- I+ g! W& A5 L6 E$ q
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/% x8 d: P T8 J/ b
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
1 z ?" u4 ?5 e' k printf("结果入栈:[%f]\n",opn_tmp.data);5 W1 O+ v4 t1 x. ~
break;* T8 N" t. l- n e& ]
}0 v/ F; D$ [" B5 P! W9 c
}0 ]- |/ O c$ n3 {# f6 {/ T" a, K3 @
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ * V# A3 z9 @1 ]; @+ \' M! C3 {4 ~
}
, B& q* j/ ^0 r GetTop(opnd,opn_tmp);; A+ z% ?1 a$ r P# T/ |" d
DestroyStack(optr);, Q/ t; a# g7 A# [; n( Q; C
DestroyStack(opnd);
" M& ~, z# A7 c. [5 L return opn_tmp.data;# R; G) \ g: q3 Y3 K. g1 t
}
1 K+ p5 t$ y- ~2 w! z/ s
# B0 J( ]4 X8 \& K ]5 e/ ]char *killzero(char *res,float result)0 g' u( z: U' ]
{- ]) B$ R7 I! D' E
int i;
0 d% v6 A) m) y
- z \6 |# N2 v sprintf(res,"%f",result);
1 Q. ~" F. h3 L$ G' m* N+ t i=(int)strlen(res)-1;
: t. N6 o' a! i+ e% d( {# ^) G while(i&&res=='0')5 H4 @( C: V8 ?9 x5 F- ?7 g
{+ Z. Y; M0 f+ Z: ?/ l
res='\0';
4 f) g' a1 c% R4 i: e' _& F! b# p i--;
1 P* z; J+ ]& x# Q }1 S6 `5 k" O' w4 V) U. o! u& Y- t5 b
if(res=='.')
# C* e- D% F- J' ~% A2 j+ H7 S res='\0';
; v4 `/ }: {: Q! @2 P return res;
e0 R) {6 _0 s/ o4 A6 L6 K}! a0 ?; U3 z, M
6 }4 S2 B) A9 x3 j% aint main()
; I' [2 I. O1 _4 C6 [, P' I+ W{# F5 m8 i2 f: E6 [( v
char ch;
( l+ c: f8 c& c0 A2 F char res[64];
2 s" ?: h3 Z, U! Y+ o$ F float result;4 G8 v2 \: X5 g
while(1)5 [% N9 M" U. y* B! p& ?4 E1 v! C
{
: U# m) V- W* G/ z9 H# m) p6 o result=compute();
+ h0 T& c, g$ d' M. V& M, \ printf("\nThe result is:%s\n",killzero(res,result));* C0 ] R! r" H9 I2 Q" ?* D
printf("Do you want to continue(y/n)?:") ;9 C0 U A- l7 g, B% `
ch=getch(); {" D5 Y3 M. ~2 ~
putchar(ch);$ y' e, g R8 A- J3 u# L
if(ch=='n'||ch=='N')9 V+ v" ^. ^' ~1 v$ V9 h/ {% Q
break;
+ ~2 u& ?0 Q9 }* I else. F* K0 d4 Z, B4 L% c0 l
system("cls");
7 Q3 {4 S" e4 C$ W# H }
5 f% R8 Y- }- u t' @2 z$ Q return 0;! V% r7 }6 p# v
}
* e9 q6 g% `; y9 f( h5 X5 t7 L% g: i# F, q+ r
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|