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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
$ u! d. d1 H4 n7 s程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
! }3 q. Y! A; |/**************表达式计算器************/
[5 A0 i8 V- c#include <stdio.h>3 a- Z! q# p* Y
#include <stdlib.h>9 q% t$ G; h* O, k9 p' g" j9 E
#include <string.h>
1 m$ k6 q$ z, E) W- _1 m& N* O( A#include <conio.h>, G0 c& V+ u |7 y( C! n0 [% K. e
#include <malloc.h>
8 W6 a8 R: }4 _6 d. a, X3 q3 S7 ~* r, }" R
#define STACK_SIZE 100
9 M% k9 N/ p' v) C/ a#define APPEND_SIZE 10( ?2 z( w7 c/ m6 i5 M( t2 A, C3 H
' W6 `8 X+ H" }4 ]
struct SNode{
; g: K/ v5 Y3 @' T9 d1 q float data; /*存放操作数或者计算结果*/7 j" V! n# r& I k l# Y
char ch; /*存放运算符*/! D0 Z2 o# @1 y3 T9 r! b" h+ C
};
! k2 Z$ v( R9 h0 O% ?, U- L- i7 i; P, b
struct Stack{( X& k; N+ }) j/ Z$ S; B
SNode *top;9 R5 _. X: D' J+ Q& Z
SNode *base;0 [2 x9 i2 W; L& Z1 o9 O5 I) k
int size;1 E% |: q7 [0 m0 C% ^/ n
};
: w& v' a; J3 F# N+ `- L( v" U+ a5 x6 E- J" B% d8 D
/*栈操作函数*/4 ^( t0 q3 X6 ?5 A
int InitStack(Stack &S); /*创建栈*/
$ y' m3 W% C3 F' fint DestroyStack(Stack &S); /*销毁栈*/
! o4 J9 @/ L, L. O. wint ClearStack(Stack &S); /*清空栈*/
/ i! k) j5 u, _5 Q2 d# Uint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
/ f0 G$ \( O. k+ V, ?+ a7 {6 {int Push(Stack &S,SNode e); /*将结点e压入栈*/
9 l& J6 a' X0 D* F8 fint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
( w1 U: n5 T m+ ?3 I) z- K+ @) E8 v9 X& Z5 I% @
/*表达式计算器相关函数*/3 ?1 {6 S! V. L
char get_precede(char s,char c); /*判断运算符s和c的优先级*/( s! F ^9 v# o
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
& p2 l1 C/ t& U8 Wfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
2 m" z. F, }% V2 Bfloat compute(); /*表达式结算器主函数*/
0 I) n& H& M- U% {0 C. Z( J qchar *killzero(float result); /*去掉结果后面的0*/
# N X, [0 b7 s- z7 g6 w- G" o0 \+ U) y* k; f
int InitStack(Stack &S)' o& J* g- M8 ~0 Z V% A5 R
{+ w( n/ _7 y1 N) u4 c% w
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));5 [( e [1 V x" n) v
if(S.base==NULL)
. O, L/ F% j2 D {
- f0 @3 e3 k$ c/ z6 A: B9 n1 i printf("动态分配内存失败!");
% p: p) K5 K, ]5 ~% ? A return -1;
" n8 z' \/ u( |0 [ }
! l; u) _& _& O% O E S.top=S.base;( Z5 _* E7 P( w; ]- c
S.size=STACK_SIZE;3 L6 j7 h$ C0 B6 ~7 g4 S( ~
return 0;
% _# `% A: H) |9 `5 f' `7 E5 Z+ l: n}
/ l2 n- B7 k/ H& t- r9 C) ?+ O2 B# \+ n# Y& K
int DestroyStack(Stack &S)
1 |8 |& W3 _7 o* b{/ |' B; n) i: t: `
free(S.base);- `4 ]( o* j3 I4 a5 O7 B/ a( u5 F3 ~
return 0;- j- J* @0 ~2 b7 f9 P# h
}1 t+ r n% A1 H3 s
! e* X# z$ P( m4 T ?7 V3 F2 T
int ClearStack(Stack &S)
& R) L. {; \( y{
6 `; `3 g" `! J$ n/ o6 e/ v S.top=S.base;
0 j1 W) S' b' T* N, c return 0;
2 {+ Q, A. F* J+ C. Q3 c}& D, A1 C1 y$ s( ~+ [
. x2 f m+ A2 u9 \ X _
int GetTop(Stack S,SNode &e)
- _9 s6 w9 j) _# B2 A# j U% z{
1 A0 f* u5 F+ S" z4 ]2 r if(S.top==S.base)
# e' O! p1 z0 M$ D# J% ?* \ {
) q/ [, M* C# [2 k0 q" l: _6 O printf("栈以为空!");
- ~6 k1 n! }8 u+ [) H" I return -1;' Q1 I$ L5 e8 ?3 q/ M$ L: y
}$ b" e7 h8 v5 g4 C0 Q
e=*(S.top-1);
+ Q: S! c. x% s return 0;
% X/ [+ I6 b6 R( B6 T}
% H0 S" `2 Z6 O. n, S+ W) f. R" m9 Y$ \( J' n
int Push(Stack &S,SNode e)
: E& Q- L4 J" W6 f: M9 X1 D{0 g: }! o) R+ ]( y+ G1 i) M0 Q) ]3 |
if(S.top-S.base>=S.size); d1 Q' w: D4 N3 Y" S+ ~
{* t' t+ I( g" R0 o, q: G
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
2 z8 u9 H$ h& n* s: Y4 Y$ p% ] if(S.base==NULL)8 {6 S' Y) G( t8 ^1 P$ O* b: `
{# z; @" v9 P$ i. J" J: \3 Z+ z# }
printf("动态分配内存失败!");
G, ]6 \4 _3 l) b6 } return -1;; V" D# u- Z8 Q6 [, o# W
}9 `( n/ T! y4 X! I8 D$ w# y; J
S.top=S.base+S.size;, Z0 ?. P$ P9 D1 s0 ~
S.size+=APPEND_SIZE;% V* V, j5 F7 l5 d! c" e
}
' H1 B5 L9 h7 |8 e4 x *S.top=e;
/ }. T# P* i/ x. f/ t; ` S.top++;
/ E$ _: Y+ i, Z return 0;! [& n9 H" y8 o) b1 |' d
}
) J! c' I! P/ b8 i1 k1 r( j
3 A5 z) W2 F- Y' `: @int Pop(Stack &S,SNode &e)7 ~' i8 d. w' H5 E! H( Y
{
0 l. u& R$ j) N- ? if(S.top==S.base)
) B7 f8 S ~% _4 r) | {
$ s- y: j$ J5 h- ^9 Y printf("栈为空!");% n; h' H9 O1 Q) z9 T e
return -1;5 @ M, v2 W) t$ `$ n# {$ Q7 X
}
/ z3 G2 C$ ^* w5 x6 v9 z e=*(S.top-1);5 F! p) t& V% Y) E/ [" B
S.top--;
% T( N: A9 H! I+ k; K8 `/ ^ return 0;$ T: ^$ w1 L' N: x3 d9 a1 ^! J
}
& C- C1 L3 f x. W# R3 r2 t! s9 v) J, M% [4 S
char get_precede(char s,char c)
1 D$ R, d$ R% C$ [3 I1 X{
7 Z/ C# H5 V/ F# \. \4 i; x switch(s)! }! [& }! x" n/ P" @
{
9 d) R7 \$ Y) [+ M case '+': ! H, r- ?& V* i" F. O d- w* y1 M
case '-':9 P5 v( ]% t, Z& U c, L, v4 q
if(c=='+'||c=='-')3 F1 F9 u2 J: k! @* J4 Z
return '>';
! O; O# O, r* N h else if(c=='*'||c=='/')+ T# T P5 w ` G( N
return '<';
l" l! F6 E1 m7 `: O0 N else if(c=='(')
6 g; S" h& x% W return '<';
4 @# p4 d4 z/ ^6 I; @ else if(c==')')2 M0 e# o3 `+ C* @, u3 f1 U
return '>';
# ~+ ~3 _! g+ T) |/ P) j+ | else
9 J# n4 w$ [4 v( O% B return '>';! m8 q, }$ a s" T
case '*':
8 g& t' c# T, R6 H. M case '/':( m8 P A5 `! Q; p
if(c=='+'||c=='-')2 c4 e0 t- u e1 {, U+ P
return '>';, }! q/ p4 C" c2 p* q% J" @
else if(c=='*'||c=='/')
U, O: s, d4 J% f: ? return '>';4 u2 t/ k& o% J) {1 |8 Q- G
else if(c=='(')2 A: D6 ?7 M5 E
return '<';6 o+ M, J) c7 {3 {9 N2 a1 y+ V: c
else if(c==')')
4 f9 x. A. _! T6 w7 q6 h return '>';
; L2 A7 u2 W) Q& q else( n* G- V$ G2 S9 L
return '>';
3 H* K* e7 m5 c; \- `" { case '(':
7 S( }' s- G$ r+ c+ | if(c=='+'||c=='-')
. F% L1 ~& q6 ?( K- ^% B8 F return '<';
5 m. v" N; j2 V. ^5 O) K/ | else if(c=='*'||c=='/')/ g T& M" L3 N& T# ?" G
return '<';
0 C- A, I4 \( Q% b& X! r else if(c=='(')7 z+ M9 v& e& w( U. c9 q
return '<';4 g' L, g. G9 L" f
else if(c==')')" d X0 l, p/ l' X* c
return '=';
\' ?8 | C' g5 h) {. M2 g" P else
3 b# D+ v0 w8 ~% y2 _" X return 'E';
. N. Q; x1 y4 `1 n case ')':$ M$ T5 d+ w' Y, f
if(c=='+'||c=='-')5 s$ C2 j8 J% y* _ r7 w
return '>';( X- r% \; _& N" v) R
else if(c=='*'||c=='/')
+ L4 y+ y7 Z. _$ Y# r0 K return '>';1 W9 y7 w& v( D
else if(c=='(')" `( J, R* q: ~% v; _, `3 ?
return 'E';
* ]' Q3 j4 c& T else if(c==')')1 N" q' A1 H3 l" M: c
return '>';9 V* H* K0 Q) w2 H4 q4 ~
else. f! c( \& y' `% o- O) l, K5 }2 V
return '>';
6 G" q* I$ `, V' u. d case '#':: N/ C: M3 j7 J+ `* F
if(c=='+'||c=='-')2 r7 O2 P$ _+ T
return '<';
/ b* R0 ]' @" P( I8 J( ~: p# o, Z% w else if(c=='*'||c=='/')( t/ f) A. J! d% |, t
return '<';5 G7 ?. [( {8 x# V- E- {8 E
else if(c=='(')
# f7 P" F, g5 q3 k! T. P; T return '<';* C6 g- q& u+ y h( j
else if(c==')')0 J$ Y9 H. ~* I1 U
return 'E';
: v4 a& j9 N2 h; O+ o' k* l$ Y) ~9 w else
7 N. Y/ r. k k, W" P/ L' b return '=';+ h; {1 B; w7 R4 }: `
default:3 a+ J# r' \3 r7 [
break;$ k/ A' R; u7 |1 f( D4 g
}
& |' Z$ A4 t: w! q7 y+ Z return 0;
& o2 [ E, t2 ?& q1 m, J8 I6 i}
" E) F7 P0 _, N" A6 G4 p3 `9 m7 C8 A
: H6 E& }# n1 d$ h9 T5 Lint isOpr(char c)! i& f1 y# G" y ~
{3 @) Y' }0 ~- U3 C6 }7 m, {4 ]
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')) P) I3 {9 B! y U1 m# x6 u2 [
return 0;7 S9 A; E. S5 C1 M2 a/ _4 C8 m
else 3 m+ t: j' a' o: o$ a) n0 U& {
return 1;
; I" C/ N0 ?5 C& |: G1 S8 l S5 z8 C}& ^8 o, {, x% B9 I2 _/ o
" N2 c2 S2 n' R9 S
float operate(float x, char opr, float y)
: O& r* s \% K9 \5 d{
) f) N" k8 p6 J, |1 _% R float result;4 ~5 O1 G' e( Z2 L8 g- t
switch (opr)3 ?, [: V: I7 G+ H2 N: ^; E$ k' F7 [
{
: B! L% Y% c. L- \1 |! | case '+': & D2 N+ W9 z/ U) @
result = x + y;- F9 X3 z+ w( p9 n
break;
( e& D, Y% O( `! D* Z case '-':
7 n7 m- B! U; u) }: e result = x - y;
) {5 N/ b: |6 r0 K( A break;
{) ?/ A9 m: m case '*':
+ W* p/ B0 d+ w9 M& T0 G result = x * y;. f/ `5 n1 ?. X4 b# _* h0 C+ O
break;9 |' Q* i i; o& J h
case '/': , Q# x9 ]7 n* r8 ?5 {: i, E
if (y == 0)
! P* L" A5 C; D/ B {- O6 \' f: j5 v7 ]9 H5 L. Z) g
printf("Divided by zero!\n");0 w8 H1 J! b( u9 a7 h1 Z
return 0;
, h, F: l2 |& F: D2 K }
& \9 N; z$ m, X else
- Z6 a. f. ^5 h# v9 j! B6 E! b {
' P& D2 v/ L2 ^" C8 \ result = x / y;+ p9 }/ `" _) {( r2 Z+ v2 o
break;
7 g! `7 U% w R; `2 ~& | }( N6 z/ q! N& _2 Z$ q3 |) Z3 G' }
default: + Y2 ~$ c# K" B1 D, T& K+ R( t
printf("Bad Input.\n"); * v8 d9 P' N- D B( E8 h
return 0;$ C! p# T1 B4 W# k) t6 n; M
}$ H/ Q5 D" i! N7 M- f
return result;
; y* j, I( q; R. d}
2 i* _* @% }+ |% h8 h
; Q* ?* e6 U9 U A# Afloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/, P4 c6 }% K6 G
{
$ w: R8 Z& e1 h! Y8 ?# y: b+ J Stack optr,opnd;
1 D! U& Y' `7 E3 Q0 h" W+ `# B/ y: u struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;# J- Y9 z! m. p' H
char c;6 W! I ?7 v! q4 q
char buf[16];' M \/ c: w: n. t; ~: N
int i=0;
8 x, f/ ^) [, J$ u% \3 ]0 q
" J+ |# j4 t. z$ P7 ]3 s InitStack(optr); /*用于寄存运算符*/9 D1 k1 H' u V( d# ~5 m, D
InitStack(opnd); /*用于寄存操作数和计算结果*/+ W. m5 o# L; G( A5 H! z
memset(buf,0,sizeof(buf));; z; ^, L# P( X/ k
1 |/ r3 g" @8 k/ W( I6 I# i! g printf("Enter your expression:");
* [. V( L6 ^: L: `
, U* L2 S) C- w* O1 J opr_in.ch='#';2 f% V/ R B# M R" B" J
Push(optr,opr_in); /*'#'入栈*/ C3 p- [! B/ o) x) Y5 T
GetTop(optr,opr_top);, f& a6 Y$ i$ g4 l* ^9 q& [
c=getchar();6 o7 g" j# H+ M' r0 N
while(c!='='||opr_top.ch!='#')
# J" x# H A+ h1 X: l {6 M a& x2 l( t6 B* c5 w
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/9 y) Z$ w! |# b# Z) Y% t
{
/ p V: ~' O" Q2 Z+ N buf=c;
, n) X! m6 g" I; z: v% X i++;
8 R( _6 g( g5 B9 G) X9 v2 ~- V9 u c=getchar();6 j8 k2 s! m: f) C0 A6 t" M( ]' E
}
: D9 G# `7 e. b, K5 W1 G else /*是运算符*/% Q2 ]) M1 a$ T' Z, V- \ u& d
{/ X0 z& B% @1 j8 D. W
buf='\0';
V+ F' x* o6 s% i* A! Q if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
+ c# J, g! u; \; L {
# Y, {/ d7 _. x: c" I3 D opn_in.data=(float)atof(buf);
9 W- ]1 Y9 B; X) [9 w Push(opnd,opn_in);; x2 u1 s0 t e3 L0 Z( q
printf("opnd入栈:[%f]\n",opn_in.data);; R4 }" J' c8 Y* L! d* J
i=0;* y. O! |" P3 N
memset(buf,0,sizeof(buf));+ a7 v- ?) x. {6 N( x
}
" \ d- r6 Y2 ]1 j6 \0 [: {+ e opr_in.ch=c;% c. I& i) x& r- }) Y/ A: _& z
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/, A! N) j/ a/ q% f, I. [1 ~
{
: y8 P1 D/ k8 U% n4 g2 B% X' Y case '<': /*优先级小于栈顶结点,则运算符入栈*/
) R" e8 t. z( x: v8 x' g" A9 x Push(optr,opr_in);: X0 ?+ ]. B" t/ P* z
printf("optr入栈:[%c]\n",opr_in.ch);
% L) u! h( u+ g2 |( ?( C7 M1 U c=getchar();
: U6 B) }% I. C* Q) Q& R. [ break;
" f$ r6 Z( `$ @' }0 X9 p( m case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
: s: x% m# k. j( ~" s3 H' j Pop(optr,e);# M( H- ]/ E( _" t7 g
printf("optr出栈:去掉括号\n");& R" H( f& s4 P2 I3 w- r2 `+ V
c=getchar();+ }) ~& ^( M( ]: C/ B1 }7 i
break;
, m% t8 ^, r/ U$ ~ case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
# N8 J9 C3 X% R0 E# ~& J9 ~ Pop(optr,opr_t);& m) m. o0 q1 G. Q$ H. \, G$ d& M
printf("optr出栈:[%c]\n",opr_t.ch);
. ]+ D) H3 @4 [1 l4 e* w if(Pop(opnd,b)<0)
- W: Z; M. ]4 \$ B8 ` {
+ x! k7 B4 M( f% c2 l3 l printf("Bad Input!\n");% a' l! {5 C& |/ Z6 ]) \6 _
fflush(stdin);
8 g7 Z$ Z% _8 a$ }5 a7 {7 N+ G4 V return -1;
3 V" @! G/ F7 y; m, f, T W }
6 n- r# u4 A: g8 B5 x printf("opnd出栈:[%f]\n",b.data);. ^& J3 f% Y# e1 P
if(Pop(opnd,a)<0)/ ]& ^* \' X2 x c6 E7 r
{ m* O: D8 D" g+ s
printf("Bad Input!\n");
! r( W# k, }* r: C" R! j" e fflush(stdin);' u/ ~! z Q! X4 U, ~; u
return -1;
' f! a; H' l3 i# S8 K }- T' C5 `* V' t7 W4 D: A( Q
printf("opnd出栈:[%f]\n",a.data);
_; N% w# `2 H/ d+ V/ J! \( z) J% D* o opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
0 I0 I2 r9 |8 u Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/. `' M9 p7 f) w7 K% g
printf("结果入栈:[%f]\n",opn_tmp.data);
3 ?, p. a2 h- E9 B& T: L break;
; y2 c" `3 j# E5 T& p1 T }* T) @1 x/ J2 K6 H( C( c; {1 v8 _0 [1 n
}, T1 t3 ^ @( I
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ + Y) S' V* w' c, x5 P. h; D
}/ Z/ _# n2 n2 `$ p
GetTop(opnd,opn_tmp);( _; X1 K8 W/ W7 v0 ~! u
DestroyStack(optr);
5 v2 ~+ N \( }; l* L) h DestroyStack(opnd);
5 F. f, ]* x4 B% P# x; l% i% b return opn_tmp.data;7 ~: t( O. l8 n5 Z* V- a, N2 U' m
}" T& Z' ]" j9 \( W s1 U* I
& O, ?6 l( B4 G5 a `# T
char *killzero(char *res,float result)
! r1 k3 ]1 e" ^9 y4 z) ]{7 C9 {/ P* D4 s3 S8 m2 Y0 ?
int i;* Y1 y4 Z% h% @* T) w+ ?: D3 N# A
: p8 \" w; O* O+ [6 |" D. ~7 ]) Q
sprintf(res,"%f",result);
7 n# X% d) Y7 X( Z* U* v( U i=(int)strlen(res)-1;% A ~7 D2 D* I# Z
while(i&&res=='0')
. L) o O, o2 c# \; J# f {
( A" \. {; V1 ?0 v0 | res='\0';0 m9 f7 S6 o& X# V' V, P3 E
i--;
/ u6 m4 t2 p# V/ P8 Y }& a- |; F6 d: s* A4 ~
if(res=='.')
0 Q% L( F2 Z6 L6 ^" | res='\0';
8 C' O) b6 {( u, U# y8 o v return res;) ]( X; a0 }1 t
}9 e$ V; h( w( P4 T
! b% ]+ W, q: N3 q4 E, d2 v% P& y2 ^int main()% n6 I& G/ E- D" `6 Y9 i9 z1 u5 N
{
/ \3 a* Z9 r% u4 @1 Z: i char ch;
8 k; N# r/ ^! @8 n; v) H. ~ char res[64];
" Z+ J! U$ e. g" f6 L' q float result;; D* r0 p( y) Q P& w x; o
while(1)
2 A) ~# ~( E; d {& d6 f6 e' w- ~. A. f
result=compute();5 O6 S/ W8 {' L' R0 {6 l' o
printf("\nThe result is:%s\n",killzero(res,result));0 H9 J" n) `4 D6 v- U0 l% _
printf("Do you want to continue(y/n)?:") ;7 Y! b9 y1 h6 N# n) T
ch=getch();2 \; S/ ~* Q" Q: A+ _
putchar(ch);
- O0 b5 f* \8 {- h7 u0 U+ q% i7 y if(ch=='n'||ch=='N')
; }% Y& ^6 A6 j f8 [: n: J4 ` break;
8 K/ o9 T! P( U. ~2 u4 m, z else
5 |& `% f$ K( c9 x system("cls");
* I; V: m" k, N' ` }
) H; E! N1 j" r: V$ Q, Z$ Z: W/ W return 0;
0 F: e3 k" I$ |1 @( W8 [}
$ G' Q6 o" ]% b2 U5 z4 W9 Q" y% ]$ D7 L: V% r: v2 r
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|