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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
; T7 t8 x. I0 ]6 P程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
# ]0 y- T6 e( b( s' }2 Y& y* }" V/**************表达式计算器************/; w( p. }* E: Q3 J( s4 r) ~8 {
#include <stdio.h>
. _. |/ N+ x2 s: U2 x; Z# U#include <stdlib.h>, ?: O# {" m3 m4 v' q4 P/ ~
#include <string.h>/ m* s' @# ?% X/ [5 z
#include <conio.h>+ g* C6 i% q- X2 b
#include <malloc.h>
4 ?5 S, d' r6 j1 a9 a8 t9 l- l0 k; y
]& Z; ]& ?7 |" D9 R, T$ l#define STACK_SIZE 100$ ^9 l4 [, E0 C4 |$ j
#define APPEND_SIZE 10. y1 {. x5 E, E) f# P% T, U
* u' l/ h' O5 E! o# t; a. A
struct SNode{
& o! I6 u! {. A3 u float data; /*存放操作数或者计算结果*/+ s; _! f, A9 C9 v; _4 `" w
char ch; /*存放运算符*/6 |0 D2 o. b3 A& C3 U: Z: t
};
; T% A u9 V3 u7 V) i$ C* c$ w$ v# u: b4 F* D: }& i' V) d9 ~
struct Stack{/ d P9 T2 [0 `2 w
SNode *top;
6 y% Z' t% K0 ^ SNode *base;/ R, g4 N+ _ q2 e
int size;
5 \& ?; _: p g1 Y) e2 z/ Z};+ z, y8 p: @+ n+ q7 C' B
; t( T1 _' G+ W$ X' Z. W2 t2 O. ?& T
/*栈操作函数*/
! L6 L1 Z4 X+ r/ C! ^int InitStack(Stack &S); /*创建栈*/2 S9 S" A$ N# A" R% Q& V
int DestroyStack(Stack &S); /*销毁栈*/
. o$ p. t, @( b7 J. f- A! oint ClearStack(Stack &S); /*清空栈*/
0 n# g! x ~) `: @2 a( {int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/1 O5 h t, J6 e9 G: ?3 v" J F1 w8 h
int Push(Stack &S,SNode e); /*将结点e压入栈*/) h/ a) r! }: s& ]3 Y
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/( A1 c; L4 L5 I) D5 ?0 n# G
6 q! W! _/ _1 w+ T/*表达式计算器相关函数*/% C- M/ @5 ~5 d6 g$ q
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
1 W5 P2 T" A) @: Mint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
1 W* M: \0 F2 N& w/ D( Sfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/* ]. v- z: S' M: E- y% _% @( ~6 T
float compute(); /*表达式结算器主函数*/' i) I- N+ }, g- T! ?
char *killzero(float result); /*去掉结果后面的0*/ / w' @- t( \( F# y4 K. }9 S# k
! g( v$ o* d6 R+ f0 q+ Q1 z
int InitStack(Stack &S)( K% P( @! b9 m5 o0 r) U
{
. K7 s9 K) G% _+ B4 a S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));( t6 v( {' m+ M( f, A
if(S.base==NULL)
. ^. O; y( Y: D' u% T* g {! J1 F8 B! ?6 D
printf("动态分配内存失败!");
8 M+ ~: ]0 o- J! B" M ~/ U7 [# l return -1;
: P5 W! C: C2 ^0 ` }
( S* c$ X6 ?$ k- u- l S.top=S.base;8 r0 B# u) j& K8 V3 J- M
S.size=STACK_SIZE;
6 g3 K& G+ G4 m' K4 M" l, Y return 0;( Y c/ L5 F- K8 b& _# y: `
}
2 J) P4 w: b# \9 `; |! U/ s( V7 Y- f7 [7 F: l# p
int DestroyStack(Stack &S)
. ]) F' m, m d" C( c{
, p h6 g. n, q' ` free(S.base);
( u# r/ P3 g! t3 L return 0;
4 O0 @2 r- s) x( Z9 D2 C}
# ? E- Q5 g, u" ?0 S- i `8 W4 _: @
- [- W z3 p; S- [, c: t+ i; {int ClearStack(Stack &S): a5 e6 L0 p3 u8 w* ], r% _
{+ ?7 ?2 E8 Z5 X' \+ ?, I) _
S.top=S.base;
+ U6 m: T4 i5 z: m) D; { return 0;
5 C; a6 [8 Y# w# y4 k0 u}% N( A2 ?# L4 y1 I
4 s9 ~) t* |# Q# B
int GetTop(Stack S,SNode &e)
0 H# J; o" w0 X2 K. r, |" K$ X{* D d) {' r2 S( f
if(S.top==S.base)
* W7 f- b$ l8 X: q: W2 r {* J. T T+ A& e7 u d7 s
printf("栈以为空!");' n6 ~. ^8 T5 ?. n: l) y
return -1;
# a/ x7 e1 [5 M }% `# V* M. s0 T, Y# y) Y1 ~4 W4 @
e=*(S.top-1);6 e9 s- F' ^0 X) r
return 0;
8 o( Z7 c7 _9 e# J+ d}3 z- y+ ^2 o" B( @' K
- _# J8 m) B% ]" C5 wint Push(Stack &S,SNode e)1 N: e+ i4 G; J$ t
{
0 ?% f7 _( }. i+ h3 ?, Z1 p1 L( i if(S.top-S.base>=S.size)
; p" L' q& y9 z2 y8 |7 m {' F' J: }0 w6 {
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
& H3 `% R1 x+ ?: Z x if(S.base==NULL)
2 G% K0 ~0 i0 }, f( f, o {
0 o# t( t! }/ q1 X printf("动态分配内存失败!");
/ ^5 x; f" C/ b5 Z" k# x% A0 [, h return -1;2 m( E) b: f# T' A; @
}6 m# z9 ~6 |- I
S.top=S.base+S.size;
( w: p' ?) G1 v. [" O+ ^ S.size+=APPEND_SIZE;
! h- M* ~/ c1 ^1 N9 I }* K" | I5 R/ k5 L+ S4 y* {
*S.top=e;
4 V2 Q+ f2 V+ D+ O( u* p S.top++;4 {% p( U& N& m; G( ^
return 0; \1 W+ q+ D5 h" [% A
}% O% n2 e f8 ^( Q. k
$ `; x( C% b: B! P# X
int Pop(Stack &S,SNode &e)0 Q8 g P/ j& t+ P) h5 s5 g
{
% B/ U( Z/ q! r4 |3 e) P if(S.top==S.base)
# p4 c7 ^3 R5 G( g* b: P8 T! V7 h {
, }2 Q- Y2 N1 d7 C3 d ]. x printf("栈为空!");, `; _2 L* N' U! N. U5 {* s
return -1;: ?6 ?& V% Q) ~- J+ p
} ?5 l6 y, H+ F9 q& G
e=*(S.top-1);: L) a# h% ~. _* W5 p( O* d- M0 S. y
S.top--;
. r8 i8 w- t2 z# a4 J; _! K/ Z return 0;6 \4 r6 f9 g8 @% Y3 @
}9 U1 G& j7 X/ c4 s2 X
& i& R6 Q: X: A
char get_precede(char s,char c)$ \; V7 }6 c& M1 ]5 P+ @
{
- E0 m+ b9 \: ^5 k switch(s)
$ J( b. ^+ F% C& Z+ ^) T2 G; M {: W; k2 T3 u M: `
case '+': " c0 U0 K ^% Z l
case '-':
. M( u. @ o' L. {. W# B if(c=='+'||c=='-')0 P& x% E& D; Q5 E- D: Y3 X# }
return '>';% R" }& U, K5 w$ [( j- E, a
else if(c=='*'||c=='/')
8 H; s% @- ?' A8 N1 k1 {1 G return '<';. D; g. G9 n8 n' k8 Q# s% \
else if(c=='(')
4 Q( c0 r" ~* b& s" [! s' V; J+ t- L return '<';
) d) V" u* H. N0 `0 ]+ I, L5 z, C' N2 Y else if(c==')')
# e% y4 ?; P$ u+ S+ i; U5 Y$ D" o7 A return '>';& S8 ]$ u4 T: b% t, [
else
$ Y; M r; x |* k return '>';6 R1 k! _# E1 T0 y4 h; U9 R
case '*':
1 _9 n2 G2 n' C! `* F+ y case '/':
! Z" b+ b& ]6 T" h) a if(c=='+'||c=='-')" e' s! z3 `) b& P
return '>';
2 W! _" S% u5 T7 }/ w" W else if(c=='*'||c=='/')8 Y7 F! w* g q$ u4 g1 w' N
return '>';( Z5 Z( N j: z1 I- C' g q
else if(c=='(')8 l; o: @1 r( R; a5 g
return '<';3 C5 r( p+ d8 {! B6 f2 c6 S
else if(c==')')
- o3 l& H* Y; P! \ return '>';" [1 ]2 ?# l; }: Q
else
0 Q0 E* H/ P# [' |1 T) ] return '>';
6 u" G* E3 x+ k0 s2 ]- B! B case '(':
+ g/ V4 x: z) a! ^% a, Z* L if(c=='+'||c=='-')
9 I+ S6 T) ?: H5 | return '<';. h5 J1 z3 @7 i; w4 I5 @3 O e
else if(c=='*'||c=='/')
}1 a* {5 @; z4 Z+ ]8 n return '<';- d$ D6 g. n' [9 F, E+ Y) l. p
else if(c=='(')' X. o! W; k4 |$ ~7 W: |
return '<';! s$ c4 Y( `, k2 H
else if(c==')')
+ h7 o$ }! r3 p2 b, c return '=';
$ L" z2 ^# I: T. w else) ~1 e' }& W4 m% p U! z1 n# E
return 'E';
8 v$ _( L9 _" Q8 w4 S# A case ')':& u. B( ]- g! e1 j% I* d% H
if(c=='+'||c=='-')
& \3 i9 p5 L9 a9 p return '>';
$ T/ O) l# Q5 v9 \& {1 ^; Z9 W else if(c=='*'||c=='/')
. a; g8 @) y) F* T1 L% x0 R return '>';* L. Q4 n( e# w/ E8 Q3 V, B" a
else if(c=='(')# d" _8 L2 s# j4 p+ ]
return 'E';+ b3 D4 j' t" z0 p M7 L) E
else if(c==')')4 `) y4 C. j7 D2 V* }
return '>';
! \/ L: b3 b' G* q U else
" ^( ^: |( u) D5 ` return '>';) g- @8 n6 Y2 \$ }' o& S" b' S
case '#':: u ?# j1 o _
if(c=='+'||c=='-')
t8 b5 B }$ y+ S* W+ A return '<';
$ L6 b T; a2 S; w% _ else if(c=='*'||c=='/')4 q9 {! ^8 b& y5 C' f. Z
return '<'; r! Y) q; \2 y
else if(c=='(')- H" O" U8 T8 l) a
return '<';
0 D' ^' n+ a) w. C' q. @ else if(c==')')# r; H" c0 f, O, e9 r [
return 'E';* a; g5 X, ~7 v2 U
else
; R$ G- ^& Y. a& e2 d8 w# ]7 B return '=';
% [9 c/ P- A1 C+ J- D" C" P8 N default:
7 k# L+ i; J5 q0 M break;6 i3 _; X0 G- D
}8 D0 c" b8 J( k- w
return 0;
( v9 R4 R5 w% T& l- a}. f+ s8 I! H o0 l& l. ^
/ ]' x! `0 F6 L: ?int isOpr(char c)9 G) f/ n9 J8 h- V* x
{/ N0 i4 Y2 i& ?) e# X
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')( |5 Q' |6 U s/ F
return 0;( n0 }7 h4 Z+ [& _' N5 H' @* e8 @3 X
else ; \" T2 D! E7 h2 \! n+ x8 Y4 T
return 1;
7 j% T5 n& _) l9 [4 T}
* h5 c" c" J$ L/ S, D+ r* F+ \/ {. A2 Y7 \; r: a8 X
float operate(float x, char opr, float y)
: V* c4 m8 u- }' R/ f" y+ s{0 z: Y/ u2 {8 V) ?: i
float result;
6 l6 {; ^1 B# p8 N0 \ switch (opr)
( |( g$ i: W3 A1 ?( P) ^0 l+ d! z Z {
- v' z1 Z2 a7 X4 v+ y1 F) u case '+': 4 K9 e0 _1 j# `% ^
result = x + y;
, z# [: z8 n9 \5 {* e3 d4 N break;
" E* L4 [4 [$ X Y6 {- ] case '-': 4 C! X, d7 S* z. ]
result = x - y;7 y/ Z7 S' F7 U' _
break;# E# B- D: o$ I4 [
case '*': 3 T) O/ b5 k) J, x$ _
result = x * y;
/ D5 C) C: b2 G o break;
1 s' b% K7 S' W6 F$ C& }$ i" {+ N/ k case '/':
8 [. j" q2 j: ? if (y == 0)
2 X, j6 J# e3 D0 a! q$ j {2 o0 E0 v* Y( |( J
printf("Divided by zero!\n");
5 C- i) \3 C% L7 e3 b) H5 v9 n0 l! m return 0;
5 t- R1 u' b" `$ O6 ^, g' B) x8 e }; g2 J3 h8 X& d) y+ E' G
else& Q: y1 G0 R' {
{) w% V. h3 u7 v% Y
result = x / y;
# c, y; v/ \4 @# |' E# ? break;; B: }2 I4 v* V0 u
}; }* [3 A* k7 S5 m; ~+ X/ I; M/ d
default: , R4 M7 D& Q1 T' \# I& ?
printf("Bad Input.\n"); , }0 S2 C2 n r4 @, m- K
return 0;
; S" w3 f# `9 q8 h3 Z+ N }, i; K# ^3 Y! G+ u& }
return result;9 b$ N" M8 `8 `" d
}
8 D+ ?6 Z' H7 A: [& u1 a, c4 d# |( g& G" c0 Z6 ]
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/. D$ z. {7 ^: W5 }: W: _9 i V5 n4 ^
{& z! e. E1 ]$ { [' f1 ~, q
Stack optr,opnd;
; p( h( ^6 a1 j+ J struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;" _/ Q+ v% B% J* g7 N% X' q
char c;3 m; }) |- A0 } `1 G3 c# R3 p( \
char buf[16];+ q' U9 S& D- N/ S1 @+ l+ o
int i=0;
* v) D3 L1 q8 \" k
0 [( ?' r7 \5 A5 ^# p0 I/ r T InitStack(optr); /*用于寄存运算符*/
Q: v5 y" K9 w# Z InitStack(opnd); /*用于寄存操作数和计算结果*/
1 a3 I7 M9 H- Z: ]/ Q: x1 F memset(buf,0,sizeof(buf));
/ \# c0 Z4 C8 b; l( m
2 E2 N# O) u& @7 T P) U! O9 @) { printf("Enter your expression:");( b- r1 a* l$ s% K
4 ?$ w5 E6 O6 [8 E1 x: M opr_in.ch='#';
) s6 s( n' ~6 p* H$ }% X- n Push(optr,opr_in); /*'#'入栈*/* X5 }0 S1 Z' b3 s( Q- ?: B- q( C
GetTop(optr,opr_top);3 V3 B0 X b! e5 k4 K9 H2 ]1 Z
c=getchar();6 @7 [; G$ u8 G- H' c
while(c!='='||opr_top.ch!='#')
9 _; X$ l: B& S: i. J% l0 e6 Q, J { `. j1 ^+ W# }
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/- D6 x- |" z; a; ^
{8 z* k) y, l5 J1 l7 i, Z3 z
buf=c;
" D$ M' j- K: Z: Z, N' F i++;, n5 ~( [& t- e% b# g5 P
c=getchar();
& Y# c) J/ D2 g! Y% [$ o$ z }2 a1 b" K- m3 [9 B5 [" }4 w
else /*是运算符*/
5 |% X; r7 i! v( o {2 J$ X! y4 A, |& k) p% h) p! ^
buf='\0';
% J+ f! H- t! \' f if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
* ` K. j9 _, F3 a {
, T' U: F6 ^6 Y1 { opn_in.data=(float)atof(buf);
l* R$ f$ o7 e- ^; ]" x Push(opnd,opn_in);
: g& T: v4 ?* c! m2 b; ^0 S printf("opnd入栈:[%f]\n",opn_in.data);$ N, N4 E" a& F. i
i=0;/ G+ B7 r1 f& M6 _* \
memset(buf,0,sizeof(buf));2 y% W8 `7 X, g: G) }% m
}. i/ }4 Z- S' ^% N" S q/ m
opr_in.ch=c;0 b% \. ]3 b) {6 v3 T
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/+ N5 F0 S. Q5 J) ?
{; m: X% H4 B) u% C3 Y
case '<': /*优先级小于栈顶结点,则运算符入栈*/
0 e' i! I8 m& A7 x9 K6 Z) e1 G( [ Push(optr,opr_in);
7 j0 f/ ~/ w* \# A2 I2 { printf("optr入栈:[%c]\n",opr_in.ch);9 d( Z. `; Z- U/ P
c=getchar();
: M& S% {, d3 H- j5 j' X* e+ Z break;
* t' @* o* J' U0 r# W j case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
1 B- r, j+ {; B+ \+ q+ e6 | Pop(optr,e);
& k8 t9 \$ J6 Z/ ~ printf("optr出栈:去掉括号\n");
0 L1 b% \, ?8 ?$ R c=getchar();' g/ l8 @: t: V8 |2 T
break;
" ]2 `$ c$ ]0 j4 s5 _( z, ^* e case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/- Z, X5 @( F! t
Pop(optr,opr_t);4 t' V' N" j! @ u- n
printf("optr出栈:[%c]\n",opr_t.ch);+ \! M$ n* ?! {9 E. K
if(Pop(opnd,b)<0)' q, }8 v) |! \8 s0 ?* Y0 I
{
! p& _$ E( D& u printf("Bad Input!\n");# |' N4 b$ r6 m
fflush(stdin);
1 Q3 b( \# ?2 w return -1;
6 ]+ O6 e: o# ]" h" v }+ ^9 S- I4 R# ~% q! r. i0 z- Y- L
printf("opnd出栈:[%f]\n",b.data); Y6 P# P. L; l& D2 C
if(Pop(opnd,a)<0)8 y1 B( u/ z( [' Z
{# C9 r: P1 P1 V; z- C: ~1 v* z2 C
printf("Bad Input!\n");* D/ N) A- j6 C+ T2 @ u
fflush(stdin);2 Z8 o0 i+ A- Y6 G0 Q
return -1;
6 |' \/ F) K* Y }" b0 Q, q7 H+ `4 c
printf("opnd出栈:[%f]\n",a.data);
; v# [" L" S% @1 C. J opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
6 M! y! b. ?5 u r. _1 ]+ W% ?7 d6 X Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
) t2 X) i' F* {' g printf("结果入栈:[%f]\n",opn_tmp.data);
2 U- L' \) j7 E9 r break;
e1 Q# e$ v5 u, B }
+ C9 h' h; u& |4 H; m- C }4 f& b& Q6 f. ^
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
$ u$ S: n9 S3 A4 |* x3 x }
! R0 f0 A" e3 ?" d GetTop(opnd,opn_tmp);
( Z: y: T2 B3 \! V DestroyStack(optr);! ?' h! x7 m @ P7 N+ M9 D
DestroyStack(opnd);
' s$ q+ x+ f$ B" q4 ?/ m return opn_tmp.data;: D9 D+ f8 V& ~! d Z
}
4 A. X& f+ k* ~+ h. e
2 C- x; h8 X0 ^4 t# f# a) Z H/ M2 hchar *killzero(char *res,float result)% ^5 F8 M( j ^9 R
{
# S, D: K x- w+ o N, ^/ f int i;
1 S- f/ j8 o1 Y) P7 S
* @' a- A" k2 i9 q sprintf(res,"%f",result);+ {) \! f1 h4 k! T" U
i=(int)strlen(res)-1;2 ^" b& C3 P/ u0 a% S) h/ s
while(i&&res=='0')$ q% s; j" J) f, q v
{+ j: v- c$ A" j/ m4 N4 p. r
res='\0';
% e- f6 I g3 a. S) @0 G" Y& L8 p i--;
- m; A/ i* u1 e1 Y2 M0 a }
% i3 w5 {8 b% v# g5 v+ P if(res=='.')8 K- o' {9 H* O* A1 D+ d4 K: d
res='\0';+ s, h+ ]& h+ [. H9 U% L
return res;1 @2 z* O1 ^+ L2 U8 |1 R: @" X
}
# u3 G, U2 {3 C# j$ c
& y7 \8 s: ]$ U5 w/ ~" [ A) kint main()
! y5 C9 ^9 ] k: ?( x" t{
1 h: m" ^: j0 ? char ch;
* j/ `1 J# p6 B$ L6 I char res[64];+ H% k, \* |! F
float result;$ U1 s; P* g! |' i+ p' a6 a
while(1)0 W) a$ J2 p l8 L* `4 x$ I
{
/ k" j4 H, ^/ { result=compute();
3 M% M2 V% C, b3 Y4 t0 b printf("\nThe result is:%s\n",killzero(res,result)); F7 h7 C9 D8 r1 ]9 s
printf("Do you want to continue(y/n)?:") ;
, G- ]( s$ ]9 I ch=getch();8 G4 E8 U8 S; ?. k1 @' J8 r$ r
putchar(ch);4 \) j5 G: R) y3 c3 N, l- w% [
if(ch=='n'||ch=='N')! N& ]0 n. J: O7 {0 `! |
break;6 \# I7 O- w. N# ~5 S; p+ y2 e; _, ^
else
7 ?! s, ?9 s$ I6 G# L! \$ h7 r system("cls");5 @& F( a$ d& m8 K
}! C& Y( U, j7 D& S
return 0;
1 v$ e5 x3 W; ^0 j$ N/ l% _& T}* Y. Z. t! C+ S+ j- @) |
" o5 i0 d$ a5 {$ B! F
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|