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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.2 j% f; X: P+ G# `8 u2 ^2 S9 ?$ Z
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
% {" |5 ?2 j9 f/**************表达式计算器************/1 o [9 v' I* a0 V b4 w
#include <stdio.h>3 g( K4 A1 I4 L7 N: u! o8 M8 R
#include <stdlib.h># j4 j5 d3 @) `4 }
#include <string.h>1 Z# g6 `2 j: W+ Y( _: L
#include <conio.h>
! m4 C5 u& q8 N2 y+ A% X3 t* p#include <malloc.h>
7 K9 O( S/ [* o7 U% J% i' h" z
$ k1 u4 L! s& I( F* o# i7 J! m: j#define STACK_SIZE 100+ r2 G! c( i1 d+ S# l8 W' A
#define APPEND_SIZE 103 g& a" i$ y! J5 y. ` n, U
( ~/ v$ a) N5 b+ @
struct SNode{1 {) V- C) u( `4 I" x
float data; /*存放操作数或者计算结果*/
: E) l' o7 \, J( E: p- o' y7 o char ch; /*存放运算符*/
1 t6 j4 ?0 \8 u3 T/ U( t};8 T( P0 Y# B/ |; d
9 x4 {8 f4 P7 T3 E0 rstruct Stack{
& i0 I% a+ B. R- b0 a SNode *top;! ~" a6 K$ E+ ]$ }6 g
SNode *base;5 c' }, M, A% i8 F1 ~+ _; c
int size;
9 v( G# G% I, z* S3 v l};* o9 Z0 u% ]$ S# ~, x
+ |' W+ h9 W3 Q' J* E& [
/*栈操作函数*/) V" l+ S& o3 u3 f& I
int InitStack(Stack &S); /*创建栈*/) x( W& v8 g a6 {( E2 v5 |
int DestroyStack(Stack &S); /*销毁栈*/
# ^1 [1 J+ d+ s: L' g* G) ?, d. Qint ClearStack(Stack &S); /*清空栈*/
9 q* a& ^* B) e( R, ?) pint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/, w I* Q4 M8 L" ]4 {6 ^
int Push(Stack &S,SNode e); /*将结点e压入栈*/
$ u& ]% x( d$ C; f% f( `6 A/ Q/ ]int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/% G* ~9 I# [( b5 X- c( c' S
$ e3 a, ]4 \7 I3 d5 l
/*表达式计算器相关函数*/. s O0 k+ k) Z) x- J6 f
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
# p4 i- [/ X7 i& r, \int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
* ~1 ^6 s3 ^( }float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
! i' O" A+ H5 l( J6 j0 B2 ], Zfloat compute(); /*表达式结算器主函数*/
# f* o0 E1 e w3 Y# T1 |char *killzero(float result); /*去掉结果后面的0*/ * `9 B" t: r* p0 E
2 X. q8 o+ ^7 ^2 g" o9 z& hint InitStack(Stack &S)
6 e( m5 e' G& u{3 ~# G7 O3 X/ @) L5 f
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
( g% s0 X# J- @6 r6 r if(S.base==NULL)
- c! R6 p. v9 N/ \+ B {
5 E9 ]4 A3 `( s* f6 { printf("动态分配内存失败!");
4 |6 V3 {% r6 \ return -1;
, x3 ~3 g: b. m H; N0 r) N5 C }
: l- b8 l* U. j8 \- B% m6 E1 ^- e S.top=S.base;
* |/ X% l% q0 _- e' j \ S.size=STACK_SIZE;& K" W8 \. t0 P0 A: S8 s
return 0;
! z0 g' f1 S K8 q" Q3 F}
4 c! f2 }8 c$ K6 y8 l: E' z/ C) Z, g6 j: M( f/ D" V, ~& D
int DestroyStack(Stack &S)
1 i# _& I# P7 A& T{" E0 D& y% {, p4 g1 v& T; h7 m! z. O
free(S.base);
) @1 }# g" y4 R+ a4 X/ s c& K8 B D return 0;
+ Z" M: t1 e9 C6 L8 f% N; ?2 z# j} e7 s$ C/ Y7 ^* M$ f# z8 ~
9 N/ @* m% [5 P9 f9 ]int ClearStack(Stack &S)! Y9 q- ]) h8 g) j% J# H
{
! z* L6 R+ C+ U- w( e S.top=S.base;
) ?& P8 ?& l# K9 }' U return 0;
9 \! [. n! ~/ y3 T9 g! C x}
$ l8 N) i# h& k
7 n; r+ t3 ]; b Oint GetTop(Stack S,SNode &e)
! @7 }& S* N# P: K5 h, J& f{3 v9 E; v7 j ]( {+ i
if(S.top==S.base)/ @3 d% G0 I# i G
{( U! ~* ~! o( T8 G0 b _: }* }
printf("栈以为空!");
. T4 @8 I# ]: P2 ]/ K* L return -1;
6 e; D: o0 r. y) p4 u }6 a/ ^- b' X' E4 I
e=*(S.top-1);+ q5 _1 a0 Y) P: H D' s
return 0;
3 c0 Y# h5 d" ^) Z6 ^}9 J- {( x+ @3 \, c- z
r, E/ p; e* j* X7 A6 r6 _
int Push(Stack &S,SNode e)' l, @! S- q# x, |1 d+ [( h; B7 a
{. N; l& Q+ L# D
if(S.top-S.base>=S.size)
0 L. X- o# e5 ^7 @2 z; `) h {
9 b% h) {9 E3 p( C4 i2 p+ o2 y8 O S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
% e! [; v& |& r6 e; Y6 a if(S.base==NULL)
& g( Q% i. r1 q& D1 o( b9 M9 W \ {
4 k: M: a" X! c$ C# H1 P$ [ printf("动态分配内存失败!");
, T8 E8 C: N1 `, S: N. \: T- A return -1;/ [0 f' t. N7 O- C
}
% T5 v; N# C' u6 b3 h. ] S.top=S.base+S.size;1 S3 O+ @- X% a- B n3 l8 n
S.size+=APPEND_SIZE;
' Y p9 c' U' `+ u$ N }/ `# g8 J3 _5 z S2 }! r
*S.top=e;
& d, I: x% {* Z S.top++;- f* Y% v% w( f3 T p' P
return 0;
) ]4 q0 R( n4 {5 u. F4 _}8 i( ^2 ~; _2 \( G
2 ?8 N& b2 d6 |4 J# C) t! V8 wint Pop(Stack &S,SNode &e)4 e2 _$ z" Z: I
{6 o7 K9 n# c" {
if(S.top==S.base)
3 R9 q% z) L! b! w {
N$ O+ H& K, u printf("栈为空!");% f& \% ]6 E) ^, _) ~
return -1;$ V# Z% z& r5 q+ t* A
}
! A: e0 O ~ F3 r. A' C; j e=*(S.top-1);: H2 H9 {' Z% }! ]
S.top--;
* j3 k# C n6 ?" Q return 0;* y/ J. Q: N8 v; H7 ?- E7 J
}% A( G% _' Q1 b4 r
- N/ j% V- B) \' ~char get_precede(char s,char c)
' t2 b2 M, X$ Z3 n1 `7 J{
~) t* j1 ^* |9 ^8 E switch(s)# n6 N: u% @" D2 g0 g# H
{( |6 x5 l2 Y6 y4 Z& b
case '+':
, a: ?7 P) Z0 }& [ case '-':# f* F( A9 {6 @4 u' w' `" V
if(c=='+'||c=='-')
) Y5 P( w$ S7 K$ d- ~* A. W return '>';3 }, O3 Z' [4 F3 j) o. E! H; |
else if(c=='*'||c=='/')
+ f' i/ Y# H4 M, x; e return '<';: O' a% `1 A& y. A% b6 T( r& E1 [
else if(c=='('): h/ w" y" ]2 y2 z
return '<';4 G, [3 h8 \1 l- U! c, x, {
else if(c==')')
2 f' W: g8 i7 s* B return '>';
8 w/ w$ f; h/ ?* L- X( w else ' s: h' ?8 q0 D2 e
return '>';) X# U: I `/ M) q9 T
case '*':, h6 k( _ S; B2 V9 `$ }
case '/':- c2 |% w. ? v4 F6 y2 Q
if(c=='+'||c=='-')
) Z" `% l, s% G; L/ A return '>';+ l& r8 _# r% B9 W& K
else if(c=='*'||c=='/')7 O+ g% }! X/ K% Z% s
return '>';5 Q( k% I/ L! R J
else if(c=='(')
' `% F& c! I( R( T+ B return '<';
* {$ `4 i- N8 p. }% H. `3 c else if(c==')')+ c! M! ?0 i# z- U- t! e( W
return '>';6 A4 V- N1 k! G+ s4 Q
else, ~1 `# ~, \& B: C
return '>';
- l* u9 x8 O/ q @# G case '(':$ `2 [! B. ?8 k9 s: v$ E, W
if(c=='+'||c=='-')$ c* A, ]$ Z! ~; |
return '<';7 K$ q2 ^3 j6 m) U7 N( H0 E$ b/ n
else if(c=='*'||c=='/')
8 M' Q) [9 s' ?8 _' D( q) R$ \5 r return '<';
- Y8 {, V( V2 s+ u$ R5 n else if(c=='(')
- P+ [# r8 g2 S4 O return '<';
+ D2 v2 x1 t. Y else if(c==')')
* D. G5 k/ H- Y. l) [' O! h: m return '=';
, `% k5 i; M; [3 f1 y- I1 T. E else
. ?! p& P5 u! K. P* H) O$ k return 'E';
# j5 v& ^3 T6 I3 y' c: u6 s* B case ')':
0 M, q; d4 w* j. ] if(c=='+'||c=='-')
4 a$ M7 A6 Z) c0 B& I$ L return '>';
5 n, s# P( j( o" u else if(c=='*'||c=='/')- |, J3 U/ s, I4 M+ @7 }
return '>';) B& L$ K* `' V% n5 e$ _( q: Z
else if(c=='(')
2 m3 y/ c& g! |# w5 Q, ]% f* t, l return 'E';
5 c2 |- X3 Y, ~! C) { else if(c==')')
) N1 u( ]4 r H return '>';
6 f) j7 l4 C b6 J+ I5 [7 o else
& j& ~* l4 l2 O8 ^* O! \: U return '>';8 X* I/ L# D- }5 F& d
case '#':' R3 s: P- `; _7 A& l
if(c=='+'||c=='-')
+ t$ X% B, e7 X% L0 I return '<';
; D/ Z' F$ l& I3 m else if(c=='*'||c=='/')2 p; C0 }8 G% r% s+ Q/ z" R3 O0 L [# O
return '<';
: f, {0 u* s6 t5 H: W5 V else if(c=='(')
# I1 e2 |1 p5 `8 R7 n return '<';
* A1 F% ]' x0 z8 K else if(c==')')' d: K3 }( g* p3 x. j
return 'E'; J0 u: p+ n1 K4 x3 R
else
( I6 i% t0 \8 r. x1 c4 F return '=';
+ e( |; o3 a# B7 D default:1 X! p0 l$ C) V6 b! }
break;9 N8 }+ B3 e9 T6 M, [
}
1 m8 r. _( j- h, x" N return 0;
; H) ^* D' r6 O1 X2 V1 U7 |) Q}0 ~' Z# A# V: ]4 x
8 T/ N) g$ s/ T" p; D7 y/ e
int isOpr(char c)
. H9 h" L4 D" i{6 C8 J6 `5 b9 i4 @/ d
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')- o; c' q. R5 I9 G- `! a
return 0;
7 b: ~* H' Z8 K$ z else
+ _. m! {" \: E) V7 Y return 1;+ @1 m B6 a+ U4 r1 G* }; s
}4 j! Y5 C; \( f9 U- E& X: A: h$ j
2 H5 V+ I- E$ A# H) |9 n& j
float operate(float x, char opr, float y)* B+ W7 S, h, N
{) N9 [- a& M' Z1 @
float result;
( V& ]+ F) ~4 @9 I5 z& Z2 g switch (opr)
$ W1 Y8 b: K, m {
# H: k( O8 O# K8 Y( [+ L% L case '+': / F1 E3 \" `( n9 d! ?4 z
result = x + y;- W. \* n, I% r" W, E
break;
/ J9 Q% {: i; R3 b% V& I/ m2 o case '-': 9 p' W2 Q B6 D6 b) i& s
result = x - y;
7 u* Y, m$ G6 V- }' F break; j* [) R6 U/ i, R ~% b' {
case '*': 4 s2 s5 z7 T- ]2 @% t
result = x * y;2 s# X" D; o: A/ r
break;
o0 \; T H; |; W case '/': C% P+ [4 E7 `1 i1 _) _% a, b
if (y == 0)3 }: u- m* k! y- ~+ i' u! g2 X9 \4 g/ b
{
8 C3 T7 G. @( F0 n printf("Divided by zero!\n");1 p6 m: ]8 c4 B
return 0;
& s! A* n5 o3 |2 Z; B. D/ Z( Y }
2 [( v( L: Z0 ]" k0 Z) s5 e9 U else
: A6 ]; L) }2 V; d3 v {* c, F! B4 p' a/ \
result = x / y;$ I# `3 r4 F3 L; r! [
break;
: Y5 Z- ~. `+ ?$ s }" ^3 \: x5 v t) d/ n
default:
5 W$ C& k+ V4 e F printf("Bad Input.\n"); . x& T2 ]+ F$ m7 o2 G8 G
return 0;( {8 B/ [3 i3 u
}
/ J' x \. ]7 Y9 [3 v$ D! t return result;
0 o, K" M" \" m2 V, `! X' J}
) p- a# ]% r2 s: j. G& r# J( u1 |5 b4 J% V! o0 j9 D4 e& ^
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/ b8 B, S4 M1 D7 |
{
) e( U0 u, A" _3 I E Stack optr,opnd;
( d" V9 o- T9 t3 f( |' e struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;( n" O1 _& s$ E% {$ z
char c;( ` H8 @) d) N. d
char buf[16];. l" q4 U) D/ c9 {
int i=0;# U* I# ]1 J u6 n e5 s
U* R' p) l+ l& M# N# r5 G# E! E InitStack(optr); /*用于寄存运算符*/
! E0 w1 a# F+ R InitStack(opnd); /*用于寄存操作数和计算结果*/2 W! Q! \. U* q- `# b5 F2 F
memset(buf,0,sizeof(buf));% R3 ^/ Z u2 H9 a
& f# J) B. h; \' t0 A1 F
printf("Enter your expression:");3 X( a: F) K$ O v' h
; i. S9 ~- S3 i& _ opr_in.ch='#';; W0 @& ]: u6 t) q6 K
Push(optr,opr_in); /*'#'入栈*/, g. C) M! h R" q3 }9 [: j5 b
GetTop(optr,opr_top);9 w( o# E9 r7 `$ p; @ J0 ]
c=getchar();
- |" K* ~ X$ \+ Y* b while(c!='='||opr_top.ch!='#')
/ d5 e+ V+ I5 Y* t2 _, r" V {
6 G/ X/ i0 C% o% v: M if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
, j! q0 B8 g! X. Q7 E {5 \' O" O7 w0 c; p6 b
buf=c;% h4 f2 }( P) Q: i
i++;
: I9 k1 U: y/ N c=getchar();+ c2 x) \6 Z# H0 t
}+ ]. b$ Z1 J2 I J
else /*是运算符*/
2 D: x6 A& @# m% P s {
7 k% [1 A) t, t; V$ p5 L buf='\0';1 j5 A) ~+ M& t" y1 I
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
0 b4 A% y+ x) k8 d& k {5 K1 G, H4 g& Q. @" Y% ~
opn_in.data=(float)atof(buf);
. b' @ L- B d Push(opnd,opn_in);- p! [0 U6 p/ p$ q7 ?
printf("opnd入栈:[%f]\n",opn_in.data);
: ~7 y: x0 c5 j: k( B3 G$ w i=0;
. j& N' R# M! u( e memset(buf,0,sizeof(buf));. Q( v, B) G# b
}
& e' b. O' o* T/ \ opr_in.ch=c;
/ z4 l, `) b# v& i, ]5 o switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
6 D& d. X5 \1 h {
# U, e. Z/ |! q! S x6 r case '<': /*优先级小于栈顶结点,则运算符入栈*/4 U4 D) j. U6 Q1 ~# p
Push(optr,opr_in);+ o; `% i( }4 _* T/ a3 b8 G
printf("optr入栈:[%c]\n",opr_in.ch);+ k! W7 T% D0 G
c=getchar();! x) h$ A6 I2 L; o0 u# }( @
break;
8 ?5 N, A+ J# D& o* G8 Z9 B case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/, |" q$ z: s. T0 t
Pop(optr,e);# }6 W5 x' S/ [- z; D9 i
printf("optr出栈:去掉括号\n");% ?9 @2 `* E9 T8 b. t/ D+ T
c=getchar();. _/ \0 B \ `+ ^/ |8 @ D
break;. y0 X% n. @1 H( Y
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
& [5 k+ ?) s3 S" a Pop(optr,opr_t);% I) [( G( i) o- j9 Q; K& N" U2 X
printf("optr出栈:[%c]\n",opr_t.ch);' t9 V) Z) [3 i! P5 @. {+ A2 ]
if(Pop(opnd,b)<0)
; i6 N( Y, C }; ^ {
4 T2 r( f2 B9 C9 z1 f' ` printf("Bad Input!\n");- Q6 C2 r( H9 P- O+ r1 L
fflush(stdin);
- j H6 _3 p. X) o9 g# K& Y return -1;
0 Z* v& \! U9 c6 O }. E' S$ i" e4 s# C! c
printf("opnd出栈:[%f]\n",b.data);# f4 q% ]. \3 T
if(Pop(opnd,a)<0)7 P" ?6 K# m# [1 o9 j( k
{
. w+ Y' R e# B& K printf("Bad Input!\n");
# e4 p, N/ d- _6 ? fflush(stdin);
( b8 s) _3 f) n+ P' B! A2 U return -1;9 X: | M$ D! J
}
8 R; H5 r* Z* h/ O printf("opnd出栈:[%f]\n",a.data);
4 c6 e2 E8 `: F, }( Q) S opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/6 k2 {5 L- S: s- g, G6 w: r
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
0 v: ]3 ~$ ~: |& S printf("结果入栈:[%f]\n",opn_tmp.data);
3 o# r5 v: v$ [! w1 Y, W" | break; y# y N1 N- }& `. B
}
7 Z! i( ]( L2 ~) m }' ]" a o1 p, K5 {! L* t$ b
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
. D5 U9 Q, z$ h8 u/ M+ w z }" O b& o: h" D* P1 ~+ m
GetTop(opnd,opn_tmp);/ I% S- u& i( c0 H( m6 r% s
DestroyStack(optr);0 c1 Z/ A* Y( T0 i
DestroyStack(opnd);
8 h+ ^9 |# W' P return opn_tmp.data;8 M( E' Z& _2 r9 @' J. \& A
}2 x9 D2 L' C+ |& A5 X3 u }3 o
7 {" ~( o/ g" i8 h3 mchar *killzero(char *res,float result)
& F% u, V L D{( k$ ]" s! V6 k4 ?# G2 T
int i;
/ ?* X) |# G4 }0 @" w: p% ^" P; S- B+ U6 C- A3 @2 ?
sprintf(res,"%f",result);
& {7 N: f; N2 |! V% S$ v0 { i=(int)strlen(res)-1;( e7 m; t4 G7 I3 e
while(i&&res=='0')
" a7 ?5 G* q9 y3 p {3 A8 e/ R, B- f$ C. u
res='\0';8 ~, R5 c R; h, E
i--;3 e- L3 G: s* z& S
}
7 j" }0 b1 M& l( f8 i8 B( q* K if(res=='.')! n) ^* V2 K, }! D+ W* B W; V2 g/ U
res='\0';& k2 H0 t' X0 Y! q1 e4 u9 g! `" ~4 t
return res;& c; g. g* Z- [
}8 p f, N9 L8 x" I7 E0 ^
+ [, r# t V; H( w% V [int main()2 p( w$ g3 ?& V1 v4 p5 A
{5 K' T ?3 }% V7 I
char ch; I) c1 M3 T; z" d3 r2 @
char res[64];
. x% A( h5 ]) h: \: y float result;
, Z' h% b* [+ x, V7 I( Q while(1); o% \- e4 t2 w6 O7 F
{# G/ E8 q% v6 t7 ^
result=compute();
6 ?* |. S' }/ k* d) u0 b printf("\nThe result is:%s\n",killzero(res,result));6 N6 R! T' q4 P
printf("Do you want to continue(y/n)?:") ;
0 ^' M! [3 o+ ?( _. K" n# _ ch=getch();
& t) I( p2 \5 Y& h& k' h" [ putchar(ch);
/ z* X. ~) D) r' D+ N if(ch=='n'||ch=='N')
( h7 z3 f+ g2 i/ A" y+ @4 ^ break;8 ]4 Q8 R2 | r- G( A; [
else2 ~% E- I% E" E8 i
system("cls");0 @8 u, s+ @( B. S% b
}0 V- @- b% t; I7 W3 M2 r4 Q0 [2 R# l
return 0;- V/ q" n5 t& [/ e: g
}" F3 C0 D Q- d/ w( C% z
% H( r# J6 L5 ^) p& w8 L4 L
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|