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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.& M* A% s8 _' e. ^& j
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
' V* y X* Z2 Q/**************表达式计算器************/' T# i/ q7 {1 r, t
#include <stdio.h>
@" I! e% Y( G5 _9 `- F2 v#include <stdlib.h>
: I. k& E1 t. o+ G# G; b5 w#include <string.h>- C! L. H# S$ T3 |8 g
#include <conio.h>6 i1 g2 {8 k- p3 v
#include <malloc.h>3 Y/ V1 b# F; s& {" |$ M5 Y
- l* J* A: a q( @5 c
#define STACK_SIZE 100" u% k% c# l5 s
#define APPEND_SIZE 10
O7 }9 t, |' Z' y# H$ @% c3 S" ]& b
struct SNode{
" N _( v# e+ u c, n2 B4 t) ^ float data; /*存放操作数或者计算结果*/
* A2 f z" o7 d) y; G char ch; /*存放运算符*// I$ v" C3 Z4 y% j/ I7 T. x
};
, V2 {! d: V9 b. }' v% _
/ Z" P l; u2 K) Q% g( f2 Istruct Stack{& @& t/ `, ^+ ^9 j: f
SNode *top;
; P& x( @' G+ n& e! d' G# c+ T5 Z% j SNode *base;) P' I; y* W- r
int size;
8 [9 D! ?/ U' r \+ F3 W1 B6 w, z3 E};
' p8 P1 @0 n; Z f
4 a+ ?/ S+ b T; `: k, Q/*栈操作函数*/
* t2 L; ? \8 l" K' n) jint InitStack(Stack &S); /*创建栈*/$ D6 |6 T, t& P
int DestroyStack(Stack &S); /*销毁栈*/3 `( `0 \/ S* i! d" X
int ClearStack(Stack &S); /*清空栈*/
) S2 k+ u: o: W2 I3 s5 \) fint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
0 R- _; C' R7 @' m' T: |int Push(Stack &S,SNode e); /*将结点e压入栈*/
" h" O" o/ K* }) rint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/$ @; o. T1 c# G+ b; h
% @' q0 k1 O& y& W+ w7 ^6 v/*表达式计算器相关函数*/
; {, P2 _5 o8 ^' b4 L) L# p$ uchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
% N$ Y+ I& p' U) ~# \int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
7 |0 d7 b7 H7 T; r3 e; x5 efloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
# N- P' e" J" G6 J3 hfloat compute(); /*表达式结算器主函数*/
' @( w: f& s0 U9 G/ a. bchar *killzero(float result); /*去掉结果后面的0*/ . P* u- G* Z% N2 z& G' V
. N/ A3 _+ z p8 u
int InitStack(Stack &S)9 O7 @$ f2 T( `
{
" q2 W. O% u a# i/ J S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
9 }5 g; f4 O# z, ? @5 o) J* \ if(S.base==NULL)
# ~) T! ]/ \' _% z1 t* \9 r {8 f" I3 W4 z4 r
printf("动态分配内存失败!");
6 o5 k9 R- t$ z T3 K* P return -1;5 m3 a; W- a6 v7 c
}
+ @6 L/ u4 u C t/ B2 D8 m' W S.top=S.base;& }" T) [! y2 s# D
S.size=STACK_SIZE;
( _' m, z& f6 s# t3 R# Z- I* ^0 W, Q return 0;; R* \% M- z4 E2 i% X
}/ {" o5 u& Z3 ^2 G4 B7 @" g
' W3 D4 X2 n7 l' [6 t
int DestroyStack(Stack &S)% s" t, {5 F2 p' D- h. T
{' w) ?. \; w7 P5 F
free(S.base);" o4 N/ k) ?7 Z R' l* r! \
return 0;
; E# `: ~9 j, l* ?}
3 f5 K8 ^' j' N0 {3 K, N5 m2 j" H) C
; B' s/ g7 N% K5 [) Uint ClearStack(Stack &S)- U; r, V1 m4 |* w. q# v7 u
{# k) x% b s M* G- Q% c- ^
S.top=S.base;
$ C# w9 R9 c K( E2 h return 0;
7 I7 C# C& K) o7 c. L* I}
8 W* g- u& n! i
( e3 ]( ^% X4 C& o- kint GetTop(Stack S,SNode &e)
! t! k5 j. a: S0 `) U8 z i{" a& m1 W9 A8 M) @0 `
if(S.top==S.base)% o! b6 t& \1 r, k
{2 q {/ O* B9 n7 m( v+ q
printf("栈以为空!");0 {8 p- b! U i, N2 n1 }
return -1;
9 J' S! t K) U+ n* V; p }
: {% I8 R& }3 f5 ^# F2 e e=*(S.top-1);4 G: G9 T. y* h5 I R
return 0;# a; L! r% m, B* k; ]
} H% Y$ `. ~9 R. O% G
4 X- s' }9 {8 H0 s. N) tint Push(Stack &S,SNode e)' I' ^& D% l2 e% m
{
' U3 \6 G( X( {7 q: l. a$ T if(S.top-S.base>=S.size)
9 f+ {0 O# w- y$ P5 x0 c {
7 \4 _3 e3 n5 ` S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
7 n* I6 s4 v* e! A1 m6 { if(S.base==NULL)$ u" {' r* I, o# g
{
( a8 K" `; B- H5 I& G printf("动态分配内存失败!");
+ F7 _* z V0 O2 h. Q return -1;5 F& _- b2 F1 b9 |% F* P% J
}* S3 X+ x) u5 r. [! B. ~; o
S.top=S.base+S.size;
" d! B9 v4 y e S.size+=APPEND_SIZE;* D: j6 }3 @# c3 b, v9 u+ h' ]6 f
}
9 g6 X/ l Y* E( D *S.top=e;5 [9 r$ W; [6 J9 U( B& V
S.top++;
6 C+ E* V! l, X. S% W return 0;7 ~6 E4 `2 ? {/ T- {
}+ b2 ?& }% m4 ~
, t Z+ Z3 K c2 V" r- Fint Pop(Stack &S,SNode &e)( C( G$ c+ L, U5 z. ]! H2 r7 @
{
3 x* V8 s, L9 R- \+ G: k if(S.top==S.base)# p( N- d4 q. z
{6 v; _" ?6 S ]2 U8 Q5 Q2 h
printf("栈为空!");" y L/ E: V2 f1 r
return -1;
4 t' l' d) O& V }. s; C r, |! f% J' N
e=*(S.top-1);$ i- g7 W2 V5 {5 s/ b; q; o
S.top--;7 U& W2 ?; n9 }- t
return 0;" Y- d, [$ k6 i
}+ N) l; r! S$ @& D
- G" ]& E! v# k
char get_precede(char s,char c)
/ X1 {0 U1 f& `{( p! h- O9 ]6 T- @, E
switch(s)+ `' N: D. J( R4 ~- _% e
{: [4 g+ w; H9 P7 h0 c/ W+ l
case '+': 3 X0 u' k+ _( G9 T& v, P
case '-':
# p/ p4 r/ }. h( z if(c=='+'||c=='-')% {! @1 [) I0 q$ ]) ~
return '>';
$ E" J2 K1 Y! B. g+ ~ else if(c=='*'||c=='/')3 N( Z! x( ]6 Y4 v
return '<';. J/ R" M9 `. {* P% @6 V
else if(c=='(')+ l9 J/ \; ?3 P
return '<';
2 c2 f- Z" p, T else if(c==')')) O' m. \+ C7 A
return '>';
; J- o& R; D8 T, |2 v) g else
! C7 R7 V) y, i3 Y return '>';
5 D& x) S2 s7 U6 B case '*':5 X& A+ N- m8 ]5 I/ w
case '/':
; T0 K9 h1 c1 ^& u! z, w) c if(c=='+'||c=='-')
8 e0 ?1 j0 D' H, F# a, ` return '>';3 a1 W7 V- M, l- Z8 Z. F9 c% ]' @
else if(c=='*'||c=='/')
- B/ `: q; v$ @1 m" |+ |1 |6 V- I return '>';4 |3 S: \5 e: z
else if(c=='(')
8 C$ u c" M/ I# v return '<';
3 D% J& v) H/ e8 B& |; T* R4 n6 n else if(c==')')- \1 m; ?' B1 ^3 Q
return '>';: _- q6 y. T# Y/ r9 i0 J; B: I
else" y, ~$ p& T! v. @( u; |
return '>';0 V- b! C. d: D8 S( L
case '(':; X, @8 `) P( m" t
if(c=='+'||c=='-')9 j& R# w. c* L. d
return '<';6 G% Z/ W! K6 t2 h; G8 X& |7 ^
else if(c=='*'||c=='/')
' C' f: ]' y, t- d) Z) g! } return '<';
* k; s- `* ^: a& ^ D* S" c! l/ ^ else if(c=='(')
& u- o5 ? M3 v0 e' ~ return '<';
; p# r5 E7 k" U# r* C2 Z else if(c==')')
4 d6 J6 B7 a! i/ g9 [) d2 b: J return '=';
2 i# x) F# o% b0 z9 i9 V8 [ else
" m1 b! x1 Y: N- R3 G return 'E';
& `0 d ~5 r' c9 d% x( A& n case ')':
2 L5 \1 n+ z. I; x if(c=='+'||c=='-')+ m4 j6 f; K* h( _6 X
return '>';1 Z: N2 @3 i3 c1 u+ _, K! ]+ c2 K
else if(c=='*'||c=='/')
0 {0 y8 L& t& W/ V6 U, S return '>';
. b, E. N1 P" w* Q7 H9 k else if(c=='(')
8 I# V9 M3 O) @% r/ p4 ~ return 'E';
: g6 x7 X5 `$ {6 O% o1 `9 _, f else if(c==')')
0 E7 C) D8 P: T: `' H return '>';
$ ~& B# R& _, k- d else* M# i+ u! I& J7 W$ y
return '>';
' L" }2 j& t" Q case '#':: {$ B: N$ L7 d! i% g
if(c=='+'||c=='-')% |( ? L7 B8 P1 l' l j+ z
return '<';2 t% J# b. ]0 W+ T, J7 ]
else if(c=='*'||c=='/')+ X+ N( B& R+ D
return '<';
5 Q4 D2 w3 M5 q- L+ s0 V+ f3 Q' o else if(c=='(')
+ g+ y0 N/ e* y! _ return '<';, N1 Z4 t. A) M3 s. ?0 q
else if(c==')') ~# r" s' X" r+ @- i
return 'E';
9 w8 m4 O, _2 w- F$ w+ ` else# e. f% h& h, c6 i, ], R
return '=';
- T) G% _( r w9 O- R; E! e9 E4 _ default:
. ~+ B. H* s- ^ W( z' d break;
! M* j2 h. K" c. @7 x }' a/ H# o. N9 p8 A$ X
return 0;
6 `0 C% F1 {. F/ L+ }}7 |% b7 l/ t, c8 a, s
6 S& E1 c' u1 Q2 {int isOpr(char c)
; @: N( Z ?& {6 ]1 U( D" A{
& X7 Y; A9 x' {0 L if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
9 H, y* z6 Y7 O. X5 x) e return 0;: ^- q' t! d8 i5 |' J8 [1 x
else 2 k, M0 O" z. z+ x
return 1;- {9 K# w0 J u2 x, X% P
}4 q7 J8 |+ @/ i% P5 p' q
4 I- q9 }+ s4 T( @ Y
float operate(float x, char opr, float y)+ h2 S$ g5 d$ D$ p2 m( ~
{0 W" E& m0 H2 `& T
float result;
! q* I' ^% i8 R8 W$ B8 ?6 n switch (opr)4 U, ^$ {1 J! u: ^
{
# c7 b" X1 |9 S/ W5 A case '+':
8 ~8 w' `2 z: F: \( L result = x + y;7 v# K$ y0 P6 T( }0 x+ ^; H
break;% L* H$ K. Q( c1 O: Q
case '-':
. \' ~+ ]1 ^8 R; L/ w! D result = x - y;
/ C+ M9 z( N' e break;
4 Y" y* W3 q3 v! J; H* A2 [- @ case '*':
6 N7 d" g a9 B2 m8 w6 P result = x * y;
* z6 y ~% S0 ~; m) ^- y break;/ o& s% H! A. G7 u/ v, }& o
case '/': 4 s$ G9 q1 h3 _. z: J& ]* ~
if (y == 0)( q% `7 D" ` l( ^. a
{' h& h5 D) ^# L. R* a! ^
printf("Divided by zero!\n"); D. u" z) y8 H# E% \' _# }0 G
return 0;
# H" i# D e/ U7 [- ~- E7 x1 a }
! V7 v$ ^) F# y4 _) q else: N( \5 z5 E' w& r
{) E+ [ J( G4 Y# m
result = x / y;
6 Z- i) G u% U' I% c0 M, k break;
4 B j8 x5 l. s* k }7 j. T E2 \. r3 ~! n
default:
8 f# u! q% L1 ~0 b printf("Bad Input.\n"); - E. U, h6 ^, o# ^$ `
return 0;
+ c6 c5 Y" ~, }' F7 Z% z }
]# b* x+ q& w return result;0 b4 b# g) e4 U% t2 o
}
1 \, p4 i5 U L k0 k! c& n( @! H# ^/ x9 g, }& K! I
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
* ~ @% y) Z' K9 R' t N{" J6 T& R, e! Z& c% ]$ l( A
Stack optr,opnd;2 n5 M9 A. ^" m% o6 R/ C
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
- Y) Y- p4 p% p char c;% G3 e& ]/ F- ?+ u8 b8 i
char buf[16];
" |- K; s( t9 \ int i=0;
. D. A% {3 h7 i
3 n# ?0 g9 z+ q$ ?; H InitStack(optr); /*用于寄存运算符*/
" q1 p2 q, F4 I InitStack(opnd); /*用于寄存操作数和计算结果*/; }# a' e' a# R7 p* G$ _" g S8 O
memset(buf,0,sizeof(buf));# j( r) k+ q: F* ]3 v
& a8 X3 j# H" \2 V5 y+ b
printf("Enter your expression:");
1 ^$ R& p" j1 V
! D7 {+ N: {$ J2 C* L; V3 i opr_in.ch='#';! i3 T6 v. k+ D! H L
Push(optr,opr_in); /*'#'入栈*/
! @2 q) @. Q1 P4 ~5 l, i GetTop(optr,opr_top);4 R, Z- n* O3 e( ]0 M" Z3 x
c=getchar();
6 D& m. G6 P1 x& q) C7 c( x while(c!='='||opr_top.ch!='#')
1 @2 T: Y4 R% _ {! O- h/ A* r& W8 K2 ]- f/ t; r1 m4 f
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/# O2 q3 X% M# G; Z; {: ]
{
1 ?7 ^2 t6 ?# F: m5 ^9 A: i buf=c;
8 t$ A6 ] o- f! \, F4 E i++;5 z! ?$ v+ C; l& m; q' I7 O
c=getchar();
# V; s2 C/ g2 w7 h. X5 o }
/ |* I0 U' {2 y. A2 P6 T# B4 I else /*是运算符*/
, R5 R" ?3 r' W, W5 k {7 U2 B7 n2 H9 R+ G, b n
buf='\0';
1 x2 A- q2 J- o$ G3 Q' y# X if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/+ Q' a# r+ H: @0 W% u3 c
{
! z/ W6 E7 U/ R opn_in.data=(float)atof(buf);
' c; J2 B+ y K; y0 D% P; r; L% A; B Push(opnd,opn_in);
) a, s1 s7 }2 O printf("opnd入栈:[%f]\n",opn_in.data);) L& Z5 _0 | q: ?/ W
i=0;
/ F( ]" U. ^# I, T memset(buf,0,sizeof(buf));
' M q! u2 J& x3 h }, P2 B6 n& `) e o
opr_in.ch=c;/ h8 i0 z- q- f9 T" [$ [1 `1 `5 q
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/) J' g6 s% @0 l1 t! i
{9 U5 l0 o# S/ ]/ T; }4 [4 ?& O; o! u
case '<': /*优先级小于栈顶结点,则运算符入栈*/) H) w4 Z, n) U; G% x. w; r( ^
Push(optr,opr_in);/ e7 o3 X! x' Y
printf("optr入栈:[%c]\n",opr_in.ch);0 N# F. X1 s8 N6 ^ \+ C" o
c=getchar();
$ S/ p7 d3 G! k: B6 H break;$ b, P! ~' Y r% o8 n% h
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
1 Q$ y9 ?8 J$ o+ O4 N! p4 A Pop(optr,e);
- m* z1 E6 u9 ^( W! y printf("optr出栈:去掉括号\n");
5 @* X2 w' U" T c=getchar();4 o0 N+ P m; F* y) [6 Z
break;
; K" H, ~0 s6 u6 n+ ]. n8 O* I case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
: h2 n3 J8 M* }! c Pop(optr,opr_t);" `* R# n/ M( R& [- N) Z4 t
printf("optr出栈:[%c]\n",opr_t.ch);% m, a( o6 N5 n6 A
if(Pop(opnd,b)<0): S, y( i, S p& B
{
# ^4 M* J- c+ r& C# p) v8 X printf("Bad Input!\n");% e. m* H/ h6 c5 x3 m7 d+ N
fflush(stdin);- A' [# ?( S& Z6 ~! _: ^
return -1;
( Q6 K; n5 u, t/ m: D I+ e7 D( N }3 A+ a! C( t$ o# ^; `
printf("opnd出栈:[%f]\n",b.data);
& m# O8 C7 k/ y4 L- H, [8 D if(Pop(opnd,a)<0)
9 H5 o& D' P: V' g7 X! C {
; T- g7 S( X: z: J* E printf("Bad Input!\n");4 d8 M% W) r- e( X4 J2 U" J0 m
fflush(stdin);3 N2 B0 t$ ~1 N2 m1 l
return -1;% [0 X/ b2 T2 j, z. ]. b; r
}
: D% \8 z0 _7 U# a printf("opnd出栈:[%f]\n",a.data);6 ~; Q5 y; [ J3 w/ [2 F
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/: u1 D' v& B2 v& }2 b. Z
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/$ w( {% O$ l: [+ [9 ]/ z
printf("结果入栈:[%f]\n",opn_tmp.data);
0 x: t0 B f* N3 ?, O break;
% H2 s' X0 F8 E+ W# v% |/ _ }7 Y9 b! I( S1 s* j6 o
}: f) Y- w9 ]( m6 A% t( t
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ % q- `3 X) g; L ?; k& D
}
- J" f* ~/ Q) d/ C1 N% _ GetTop(opnd,opn_tmp);
. e; P2 C" d: b2 {% Q* l5 {/ g) B9 i DestroyStack(optr);4 G' I8 F+ L; F$ d* P7 G
DestroyStack(opnd);
- T7 [; ]: |3 e5 s return opn_tmp.data;% N9 K' q; B" c
}
5 B5 P! c/ s; `/ l7 \' }1 T& [& u( w8 r. @
char *killzero(char *res,float result)
1 T7 i9 A7 O+ b/ {, j6 C( m{
6 R8 T3 L; S& K( j/ Q3 f2 v: G int i;+ @ b) N) ~- m y& Y, `
0 J5 ?9 y$ c C% s, M7 u sprintf(res,"%f",result);1 M5 z. d1 U+ ]: z% q+ [) Q
i=(int)strlen(res)-1;1 `0 d! D$ K, K2 N4 Z4 U
while(i&&res=='0')
4 p/ G1 h2 R7 y3 ]* H8 } {% @ R, v) N& {- h# a
res='\0';
5 M) h, [4 F1 \ J& C4 |) A i--;* E+ k; j; z- Q; g0 @5 S
}
0 R5 ?9 }0 [4 }7 B% X if(res=='.')
3 l) e' `) Y/ H( y( ]8 y% I5 v+ ? res='\0';
. v& C9 i8 \4 |( t% F1 W4 R return res;
5 n+ z) Q1 V A# a}+ b/ q6 |6 z4 N; B5 H/ L' ~7 L
# W0 C4 D& Q% Q
int main()
0 n3 o0 j$ Q b* i- A, f# Q. {{; j% o" l7 Z4 U! f
char ch;/ ? w" l: N5 m: S6 O1 p
char res[64];
7 t( F6 L3 r) H1 X float result;
4 R" \# a& Q* M; F! | while(1)% b' C$ q# _0 p
{
/ q9 F4 F0 D4 { result=compute();0 r# U! \& w, L
printf("\nThe result is:%s\n",killzero(res,result));) Q, D" `% Z4 j8 |
printf("Do you want to continue(y/n)?:") ;* Y/ o' d) ^4 i9 c5 i1 |
ch=getch();
/ _- w! [6 v0 [( F putchar(ch);$ V: L- l2 L: |. V* T% F
if(ch=='n'||ch=='N')5 H9 x/ H5 a4 K h
break;
( v1 g. @- ^' Y8 T$ H else
) w! r, d/ P2 _ system("cls");5 O; j0 R) S$ A/ Q0 H" Q
}
9 @. ^: O* y! i1 O4 W return 0;1 e" ` g6 S S6 t" i
}. m$ p% y }" O. d3 k2 z" G4 D- K
, ^. j3 w2 t& l5 ^6 i9 ^
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|