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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
+ y- o+ i' Y) B/ e3 X程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
# _/ o. x8 D$ |4 i; V/**************表达式计算器************/+ q7 E# `0 @6 M: q: i
#include <stdio.h>
4 ?5 Z! ^! }: f#include <stdlib.h>7 |5 ^* |% |: o0 ]
#include <string.h>: h: t3 o* }1 M0 U# Q: Q3 P
#include <conio.h>, k/ h/ ~+ E# k
#include <malloc.h>
! C( G' f$ j; g2 G
+ ~ ]' I* ]- b#define STACK_SIZE 1007 G# b! c2 p) l6 R
#define APPEND_SIZE 105 j7 F/ z9 U$ G: I9 L1 @! F) A
5 I3 @! d, a6 @9 N7 z4 {; ]struct SNode{
' a' v1 D8 _8 z+ p% O* E% _ H float data; /*存放操作数或者计算结果*/3 G$ n! L. d [1 p) c$ z. T) n
char ch; /*存放运算符*// l7 b1 n5 e* t) J _& n5 D
};: J0 ]* [' ?& [
. [$ U# Q4 U2 N- y
struct Stack{
) @1 @! l/ Q! U5 Z3 V SNode *top;" m" k. A& A7 q" R) J ]
SNode *base;
- S6 F9 \5 L# t+ k4 ~0 k int size;/ Q/ T1 @1 V$ v$ E6 I4 I1 j2 K
};
, v1 S/ d; r- z& N9 P
: D$ E/ k& t- V/*栈操作函数*/
7 H2 b" S$ P: A, y5 Eint InitStack(Stack &S); /*创建栈*/
1 B# _/ s. G1 u+ v# Eint DestroyStack(Stack &S); /*销毁栈*/4 e6 J: z9 Y* @! A# ]
int ClearStack(Stack &S); /*清空栈*/3 m& I4 U9 X7 M( ]; g+ U
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
% t( h3 {8 ?: W' mint Push(Stack &S,SNode e); /*将结点e压入栈*/9 f9 ~: t S8 j! P+ E4 Q
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
0 o0 y. A7 e( \1 z7 S, q
) j5 y5 J5 }' g( P( w/*表达式计算器相关函数*/
$ A7 l: I4 Z5 _$ A9 @0 cchar get_precede(char s,char c); /*判断运算符s和c的优先级*/; r5 I' T# c8 P! K
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/7 K ?2 c5 t, a$ Z% @8 ^
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/8 }) z, u; E& ~4 _9 g }+ U! y" M6 Q
float compute(); /*表达式结算器主函数*/9 P6 d9 m4 ]5 v& u
char *killzero(float result); /*去掉结果后面的0*/ / @/ p' V) P2 n2 J5 W& f5 J: O7 i
0 l* C# j6 B1 Q! D
int InitStack(Stack &S)
% q2 }' @2 i1 Q. m' m{
( Z% y' ^3 n5 \& t" T1 T& A) E S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));) _: [1 q6 z7 w
if(S.base==NULL)
/ w* Y$ X2 [ {) ? {4 U3 @, }, i* J' R
printf("动态分配内存失败!"); c' k* y& @; ^" D4 o8 z
return -1;* `& ^# `9 N3 D: K# r/ G( _6 ^5 ~
}
$ t4 p6 K+ |5 f) H. C6 q- p8 C x S.top=S.base;) `* i5 H; f7 ?
S.size=STACK_SIZE;
2 ~( l- ~# f: N4 b return 0;
9 u5 I; z# R+ I}! o! M8 y. a3 ?; L0 w
# U* ?6 R B% _- A, bint DestroyStack(Stack &S)
! F) A" S6 |: N7 W- n{
5 T% F# \1 J/ }, o free(S.base);2 |# P! g& f* k1 Z% S4 Q
return 0;4 N8 V ?9 D: G5 c4 ] E/ \
}
( @" @. b& V5 j7 V- M1 `
+ s) ]* M2 j6 ` D. }int ClearStack(Stack &S); b) I/ {! t8 g! S
{0 v& N4 h2 j* u- T
S.top=S.base;
2 n2 O c/ {8 n' q) f7 q return 0;
9 Z& M) |1 H: L0 W8 i/ V# j}
/ L+ k1 F$ \* Q" L' U2 |' ~7 `
9 D. l! _9 ~4 Hint GetTop(Stack S,SNode &e)# Z% ~4 _2 }( V! |- e2 E+ z
{
6 M7 R0 H! n2 A0 r9 g if(S.top==S.base)6 e7 ^4 J8 S# S
{
2 Z5 e. y5 {9 r; D, A& ~$ L printf("栈以为空!");
0 q A! S& h2 j1 A) D) `* z return -1;
( V2 C4 G, l! T) n+ d8 C% g }
6 O. {- `4 ?. y0 k' v e=*(S.top-1);0 |8 A; a5 n3 A
return 0;/ G( @9 p) |. M$ n
}
9 @- A9 @+ ?+ d) ^+ W E5 C4 C z- Y/ @) _2 _+ S
int Push(Stack &S,SNode e)0 k) c2 }, C, A# q3 ]& r1 }0 x4 o
{
7 u1 C+ q/ ?3 A% A1 R( s! t if(S.top-S.base>=S.size)
; p, \$ C+ _- o {
( M. z6 a- V0 G1 K. ^ S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
1 z3 i/ l% O7 x/ d3 V$ L if(S.base==NULL)
( Q' R; B8 D+ B/ e' \$ S {
) A i# L: g& v h. y printf("动态分配内存失败!");1 F( ^. A5 X1 p9 c( t: T
return -1;
+ b' \4 O# A- u) J1 S }8 s. \; h N( p+ E V/ a! T3 n
S.top=S.base+S.size;
6 ?) L7 L# m6 \/ d J S.size+=APPEND_SIZE;
! m- Z0 p' Z G) r }) s) Z2 q+ c& C6 y/ O
*S.top=e;
+ [* ` A- V! S; B4 [- }, H S.top++;
+ ` B( H2 g: Z: I" T: q return 0;
5 l H* Z/ e# {}% v8 y- }" }. \! |8 n
7 p% O! @, V# Z2 ^int Pop(Stack &S,SNode &e)
7 q2 f6 f2 p) z' }" C, w$ S{
6 S9 U+ Y# k% y: f* I4 [% S8 b if(S.top==S.base)
j) Y2 [7 v# g5 `5 e* [- B+ I {5 m# \. A% V4 J- {0 v. ~) l
printf("栈为空!");
, `% Q5 p! o, M5 z0 Q# _ return -1;2 |$ ]' }5 p/ A
}- m: L" i0 {! i" z4 W/ Q" f, F
e=*(S.top-1);
7 f% g4 G* {4 t* e, F2 i4 Y* Z3 \ S.top--;
0 s% Y6 j3 i' _ q7 ]" e6 x return 0;( Y8 J3 u& |5 S
}: Q* J7 g3 W: O3 q
; ]( B* x- G" [# K
char get_precede(char s,char c)6 G4 z+ n* o8 a) u% X- Z
{
7 [% l" J: |, b* v" r switch(s)
: j6 a6 t: b, P: M3 ]0 `( R) m {
! S# y: S- Q) k1 ^ case '+':
7 u& b9 x; z1 x9 k% S case '-':4 r2 x1 ]' ?# V4 \3 Q9 c6 U
if(c=='+'||c=='-')
' |) W3 i' q5 x: M, L f return '>';
2 f S. d* ]$ G0 {3 _- M5 A else if(c=='*'||c=='/')% q' x" @* T* v5 ^; _, Q# P
return '<';
9 h7 A7 G2 O2 b# e3 h9 T else if(c=='(')5 H) H0 K% L* Q( L( F7 o
return '<';
5 w; q# t# B+ n! T else if(c==')')
& @ M ?, ^6 Z/ A& D) M1 q return '>';
% g' P8 p! K a7 v# O( S! l+ t else * u( J" U$ t( L. ?9 u* P" B
return '>';8 B. \4 T# R+ k. n7 b/ i, b _
case '*':2 _1 R' n5 q5 w: e* c+ o; }
case '/':
9 M. R$ T9 B; J# c$ }- c if(c=='+'||c=='-')3 Z- j, f" \+ ?- Z. \
return '>';
" p& U- r" X H) c+ M else if(c=='*'||c=='/')
: F; j! h i. i' y% _ return '>';
2 l& ~/ J% }# R else if(c=='(')* c, t' U9 @1 k: a
return '<';
/ n5 q9 z6 E. M7 N else if(c==')')4 I$ I$ t8 V/ X- b4 E
return '>'; A' O4 g4 M1 z c( @
else
0 C9 A9 r+ O% J# m- o& E return '>';
0 q* `+ @6 o% S case '(':
1 N* H9 \1 \3 N3 c* N+ N if(c=='+'||c=='-')
) Z8 A; K0 m7 P2 }. t: U: ^ return '<';3 v* m0 ?3 N- q
else if(c=='*'||c=='/')+ {3 n, f+ Y$ Y/ x( y
return '<';
8 z" ]2 J& Q. q g" @! E. j else if(c=='(')7 K; u1 c6 V1 X9 G8 |0 H
return '<';
: s, G, Z" i$ Y/ s% Q) @5 v" ] else if(c==')')4 w; |9 o& F5 E. P, h" C
return '=';
3 k8 c' s+ t# L- P) _2 ` _ else
% s" Z# O- L2 I) z4 G3 X return 'E';' G/ }3 V: k* Z |) K& h) k
case ')':0 Q, I3 v: _/ q, S+ B' G" `9 G! z
if(c=='+'||c=='-')
) H+ t) F- J' }( h: e* ?% `+ Q9 B return '>';( D3 |+ _; Z& P4 d6 j3 |+ q
else if(c=='*'||c=='/'). ?& o" ^2 F9 \0 B7 w# L( G4 }
return '>';/ ?/ j. u: x' m6 f' A0 I
else if(c=='('), R+ a" N2 m& E; w7 I
return 'E';. ]% I2 l8 t% [4 u# `, a6 i
else if(c==')')# H6 |" p0 K' _' e. {% O/ z) \
return '>';5 `9 e U" z* j! N# Y
else: ^5 H, S/ _# z% ^/ }% v
return '>';% M5 N1 f( c9 X8 ]# Q, Z
case '#':' Z% W% r' l( Y# c8 d3 w% t
if(c=='+'||c=='-')
6 |( M1 |+ I, |9 M, I; k return '<';
7 ~5 z1 a: _ ^- l# j# i$ _ else if(c=='*'||c=='/')
) y4 ]* k6 H3 F0 G* o' j return '<';
6 G9 F8 V* G0 _: z% h7 V else if(c=='(')% x6 l& u2 Z) i n$ X1 d8 h
return '<';
, C, s" Z4 b( \ else if(c==')')
0 G8 ~( Z$ A6 c6 B4 Q' G return 'E';9 g0 r" r u" h4 K9 O+ k/ {* s
else' Z9 ~" Z) R v y8 E
return '=';- D: I& a! `& b, d! |* h) s1 y
default:2 v: G5 w) `, ?6 X& L
break;0 ~1 b, ]# o' g, }, v7 I) M
}6 v: j3 S4 Z7 G% [$ C
return 0; 0 S5 V9 [8 b8 M
}0 G/ c+ G5 \3 r- J* P z
9 d$ `) B e; C+ F1 ?$ O) oint isOpr(char c)
g& E+ E+ z0 O{
! R0 d% s" P- ] if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')0 q4 [- @% k3 q e/ |, M
return 0;8 v% H+ m! u. ~* F
else ( p5 x: {. `. W1 o* T I" t
return 1;
' X+ C" U4 m/ W. a& s( ^) y}: { T. W# ^$ l" ]/ B7 @ M
$ P$ ~ P1 R6 ~0 u0 P9 jfloat operate(float x, char opr, float y): q0 }: Q+ d* m( a
{- j; H1 T: M% s' v9 f/ e. i7 s3 p
float result;# T9 w; N7 ^: A; ^1 H! ]4 I" l
switch (opr)
+ I8 Q7 g2 L! R { G. [# [4 K6 g' d* c1 J$ j' i
case '+':
1 p. L) Z X; R; F; B5 C1 d result = x + y;0 q( r1 D4 [. }# @6 | |- S
break;
( h. C. B. y' X! p2 P/ B case '-':
( g4 D: e0 Z6 W8 R/ D' t8 V result = x - y;$ D6 B/ i, N [) e s' G( o9 s* m
break;
: }& K. b' t( W" n6 N0 R" a) A case '*': q5 ^7 R; d. {' U3 }( O: z
result = x * y;
& L( b! t( N' Y7 w break;
# N* u7 ^* ~5 R8 ^. F4 B case '/': 6 x/ `: i8 } M+ ^# |1 B
if (y == 0)4 Z/ V$ T( n5 ^+ U. }
{
2 @( d, E% S0 m5 f printf("Divided by zero!\n");
4 ?1 U* j" `9 a3 O d$ \ return 0;3 S9 M2 T0 |8 H
}
0 X: k: G( b+ W) s. @ else w/ I# D& p: x$ d/ }1 Z
{3 u6 { B& X9 M- {# t8 H' o. K
result = x / y;
0 x+ L" l9 D& r0 O8 a# ?0 t2 r break;7 J% e7 o+ v5 `7 c( I3 r& t
}
$ h6 g; u3 w" W7 ?! N4 B default: 1 C$ K, y. T* S) z9 p. f- ?
printf("Bad Input.\n");
& G# l% p- |5 D+ O4 ^7 H return 0;$ Z( l2 e- d; x; @7 I% t/ A4 |) b4 N
}& B) a* J2 q X
return result;
9 y. h2 y& }( ~} 8 t' x! D& f) n4 m( t
: k. b6 K6 P) T2 p2 r" m$ F
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
0 l) e- T' ?5 F: @* w( w) a& x0 ^{$ D8 t: W. P6 ^- O( d/ F* @/ t
Stack optr,opnd;' i1 J6 g5 n1 a& x
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
! |- k0 I* J+ Z# I char c;% ~- P- n/ P" O& X
char buf[16];4 |4 y6 }. t( r; ~. N. y: s2 Z! {: m4 _
int i=0;
: G# y( q7 d% k$ D4 L$ @) m. _& Y& M / z: S# z2 A! R# E$ e
InitStack(optr); /*用于寄存运算符*/
' P: R& K' X% p1 X3 _# f. x InitStack(opnd); /*用于寄存操作数和计算结果*/
J. r5 x5 i. V& O1 C8 u/ U6 l# g memset(buf,0,sizeof(buf));1 U. ?9 `1 Y' i0 Q1 Y8 S! k
( w9 \- Q. S3 O
printf("Enter your expression:");
% ?4 C" @8 N" f3 f' m $ d* e8 ]/ U9 Q
opr_in.ch='#';
1 ~9 i: q2 {8 y/ m. x) S- ~; I Push(optr,opr_in); /*'#'入栈*/
! G& W/ [7 y+ s4 e1 o# ? GetTop(optr,opr_top);; |7 P C8 |7 n2 e8 {
c=getchar();6 D, d4 d9 n$ }4 [% g
while(c!='='||opr_top.ch!='#')! s# C) F+ A V9 c
{
$ F, k! k `1 Q7 L B* l& p if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/: a8 `0 @# ^5 d6 B: A- U
{
5 f, f, x' |* d- u; {/ M5 | buf=c;; l; k& u. r2 Y7 x6 D2 A
i++;* z) ^4 W5 y& M" _7 G# O
c=getchar();
) C1 I' W# H5 ?; T6 k0 N& G }
8 X! [0 ^) v/ C; V- j else /*是运算符*/
; c* _- J/ a+ b {% z5 r7 p+ `" T! Q$ B' i' G
buf='\0';
, U W, o' W: ` if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
+ @' z, ?; _4 R8 s) H {
& V, M5 U" H6 a- M: G2 S( S( i opn_in.data=(float)atof(buf);
; u* C' m( E( U$ W Push(opnd,opn_in);
# W+ z6 q! g0 T4 c v printf("opnd入栈:[%f]\n",opn_in.data);# E; A n5 g" y; M! ~
i=0;
# t7 {8 C+ m0 t' w, q memset(buf,0,sizeof(buf));
# U4 g4 `4 [$ Z: x; l! I }: B/ y" O$ d7 }5 B% `
opr_in.ch=c;' M7 ^' N5 e' e2 _# d
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/: P# u$ f& R1 o5 d' M* v7 R; g" Q
{
& L* p9 w7 n* j case '<': /*优先级小于栈顶结点,则运算符入栈*/: u8 s- S1 R& j+ Y) x
Push(optr,opr_in);, K" j3 t0 a/ ?9 R% [! m; D. c
printf("optr入栈:[%c]\n",opr_in.ch);& U4 C, z3 \) U K3 {; y
c=getchar();. I/ O; `, R6 e5 R7 f! T Y" k+ d
break;
6 S! U! m# o: ], d9 W/ T0 [ case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
6 L- I) c6 V7 V2 V Pop(optr,e);
* [% u( T. P+ z+ u$ t printf("optr出栈:去掉括号\n");
3 O/ H4 |6 W2 R& I T- ? c=getchar();) R& q/ f/ A u4 A P
break;/ I$ `0 l3 K! _2 h( V' f( N
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
6 F4 X2 A! W/ ]( s" o Pop(optr,opr_t);
4 D% \/ y! Q! M0 s* m printf("optr出栈:[%c]\n",opr_t.ch);
( |1 I, u$ ?- Z0 }* f. Q3 T1 Z if(Pop(opnd,b)<0)
! W* d8 D7 |' g/ I3 \0 Q! U! L {" g0 I! r6 P- o1 f" K5 a& [! x( N( l4 }
printf("Bad Input!\n");7 w" Q: ]2 o7 z& o; {
fflush(stdin);
6 V: b$ ~% x6 o" U& @( q return -1;- Q9 q- ~* a! u( E& v' p
}1 R; g" A! J* K' R! e
printf("opnd出栈:[%f]\n",b.data);" w# u, H; r2 P( p4 t( J: q+ n2 J
if(Pop(opnd,a)<0)
- u/ B+ l7 \. z( ^2 b, r' W/ A9 ? {- d+ y6 |% _( Z; S
printf("Bad Input!\n");
; Q# T1 h: X0 _ Q fflush(stdin);
; q2 b5 @ f8 I) l' Z9 c: m return -1;
! d+ i B4 a- F( U1 o3 f }
3 o1 N. G" p) V( P printf("opnd出栈:[%f]\n",a.data);2 p$ z2 G( E4 Q; _# `/ G+ k/ @
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
9 ?9 i$ Y3 G) t# u Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
0 W& @+ \6 F5 o; A; n printf("结果入栈:[%f]\n",opn_tmp.data);
4 s2 Q- ~8 N; P$ ]# f9 K break;9 ]8 {/ m6 U) [, f. r$ b7 ?
}
! Y, A. [7 `) Z) Y0 C }
d& N' s+ u4 u X- ]' ?3 p GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ + q9 L; F/ _3 h! [! j* @! ~
}
8 y2 J6 }. E Y: B& P GetTop(opnd,opn_tmp);
, x& \3 q# m) L7 v9 [ DestroyStack(optr);
x6 T f: V/ P DestroyStack(opnd);
! x0 l; B: V& Y# O return opn_tmp.data;
' Y" h- M9 a: V% G}- k+ j+ ?( m& \
+ j# W- a( S- p' dchar *killzero(char *res,float result)
2 m3 b8 _0 ?6 i6 K{/ u% w! M) n6 ^0 Z% t; k( }
int i;9 i( E0 I/ c2 x0 o e- C- c
% ]/ z) `0 t& {4 N# U% X$ Q2 p sprintf(res,"%f",result);; W/ m- U4 G$ V7 T9 C. B
i=(int)strlen(res)-1;
: x7 _! R: U* b6 o while(i&&res=='0')
! M5 Q2 W1 o! X( H, }1 N/ j {
/ J; t% V, _. \) ]0 z' J res='\0';
" ?' w% w9 c; v u9 c i--;7 n" h u; s. N) L. O
}
6 O7 P) z0 `/ y4 R; ~) o0 p% z1 g& E if(res=='.')
Z$ i0 b2 I' f9 ~7 |- ^8 P res='\0';1 y& i9 P; F# E5 T- c
return res;
9 P" S+ `7 i- }; C) N- L8 B7 b* s4 w}& P3 f9 f& y v6 e
5 l% @( g7 T7 ~4 C1 A- C1 G& \int main()3 J1 \: u8 ?5 @' ]& F1 i' ^' v
{
& n- J0 P+ f- s( S8 P, @+ V' }- x char ch;. } L y- n% z! Y8 s7 {% K
char res[64];
: S+ Y( C+ F! O1 Y& w: E# N& g float result;
/ e+ L" l& J7 L$ m' z while(1)! V) j& @6 p6 y) o( w2 Y e' R
{" B1 s# E: x# v( I# M( R
result=compute();' }9 y: w) e1 I7 i7 E3 K1 @4 A
printf("\nThe result is:%s\n",killzero(res,result));
! ~$ | [! C7 X0 J printf("Do you want to continue(y/n)?:") ;
- U% g' u# o. @, G! m ch=getch();
- q; M/ z4 F5 C2 h/ m; G t putchar(ch);# D* x# x) `4 _, H$ ?/ L
if(ch=='n'||ch=='N')
6 N! {1 l0 u; \5 [ break;
' W8 ^$ ~* a O+ i else
! Z$ S' [ p/ ?5 [/ k+ g s8 y1 {' Q system("cls");/ w- n: _# @: ]- A
}0 u! b- Y/ m2 O; e: E6 Q
return 0;
4 O6 n! x8 Y5 T5 I$ ?4 K}
4 w* j2 \9 `6 V- `6 p( G- B* E, F [# l
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|