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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
, e B) w1 r; K0 s# V8 E- |程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=; S% K7 \) O/ G1 y- }
/**************表达式计算器************/& R6 U% G( W- D) g
#include <stdio.h>
; D! K3 T3 D6 m' s7 d1 T#include <stdlib.h>0 ], y5 D3 S S( g' P. z. h
#include <string.h>9 L1 B f5 N9 ^5 K6 }
#include <conio.h>% E4 f" l- J# s, d {0 d" [: u1 S8 B
#include <malloc.h>
5 U! k, I6 \! y( Y8 W u7 ?# @; a4 x2 S* y9 L
#define STACK_SIZE 100$ A4 v# z8 E9 X
#define APPEND_SIZE 107 h7 C3 r$ K( [9 r, S6 N7 d6 M) L
- ~5 `6 r2 @; c/ w
struct SNode{
! T* v1 p4 D( Q# I float data; /*存放操作数或者计算结果*/ G; U# f% k# X$ J2 g6 }- c
char ch; /*存放运算符*/
$ o+ i( Q6 c, m, k2 V# U};
I# d5 h. {: D5 d- d
3 O9 E. B/ f/ p) Cstruct Stack{- ?$ z5 f1 L0 B; w3 J1 Y
SNode *top;0 G- M5 T/ s0 E. |
SNode *base;
' k! P0 Q5 b* }& P$ m! r int size;3 _" Y$ c3 u, U( [! w
};& { v7 o! O% N3 U9 C/ a6 g
: [& T$ O" D7 Y. p/*栈操作函数*/
/ R. ?/ }+ h- E' K Aint InitStack(Stack &S); /*创建栈*/
6 K% D9 a# S/ d- {3 [6 Wint DestroyStack(Stack &S); /*销毁栈*/1 ?5 n# p5 N. x: C% K! f; k+ T6 s
int ClearStack(Stack &S); /*清空栈*/; ^/ t3 x7 M, P, t. r
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/0 P3 d: R8 b0 R! k$ x# T f8 n
int Push(Stack &S,SNode e); /*将结点e压入栈*/ D9 b" @' h4 J! S2 c
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/7 ?3 v( w2 Y2 ? h5 p% T
$ C- q3 P+ u/ h3 `* K1 `
/*表达式计算器相关函数*/$ U( w4 b* i4 s3 D0 D& U
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
5 v" G2 j- d- D7 T- s& wint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/2 ]3 {4 ^5 q5 \4 Q( |
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
7 H2 z/ r- Y- u b" n9 {3 Nfloat compute(); /*表达式结算器主函数*/
+ L& R+ y, r8 H0 X' |char *killzero(float result); /*去掉结果后面的0*/ $ j4 _. B6 H& |$ K- v. z |! }
6 \" f# |7 Y3 k6 s6 O wint InitStack(Stack &S)$ l3 S6 g( F; {- H
{% c5 ~ a5 X2 e
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
" d- Z8 X8 j- e: J4 b if(S.base==NULL)3 G3 U- v6 |# [9 C6 M
{& ?) ~/ B7 |7 A8 Q+ q6 Z
printf("动态分配内存失败!");3 U+ c9 Y0 y5 K! q! ?. e% C
return -1;
' W3 Q9 {7 o* M }" I3 T8 E" ~$ g0 E) ?2 ?$ m
S.top=S.base;& y( _- h' o/ n2 s6 @
S.size=STACK_SIZE;! X/ X, T: G1 _
return 0;4 Q$ Z8 G. L" T! g0 s* Y* G
}) h5 {, r! z$ b9 D3 W
7 i+ c. R; U6 b1 [6 u Fint DestroyStack(Stack &S)
& s# w* J9 q0 y* c. e0 t. r9 }. p{
! B4 X: r; b5 P5 y" y free(S.base);
9 O2 Z H- q6 l) a- a return 0;9 ~$ A, V% l3 w; k
}" a+ p+ @5 t, T$ [
0 O9 D0 `: H% R- U! }int ClearStack(Stack &S)3 B! W; E6 {1 y& Y% `, o: y9 W
{
, a7 e. F6 r8 K; n& S$ G. ~ S.top=S.base;& B9 r( s% W0 z- ?2 ]6 s* ~ a
return 0;
6 Z+ |* k3 O! w& L" ]! f+ H( k: N}% C, E: y. d# |2 k5 N
" B7 f! P& n* d& i/ o: t* o8 Y4 p
int GetTop(Stack S,SNode &e)4 d$ y9 v/ m) @3 X; Q$ Q
{( [, z3 @. |( b) f/ ^4 S1 P9 a
if(S.top==S.base)
$ ]) Q( u& `* x% \ {7 U5 p# G# b/ @$ ?, P, x8 A8 O; M# X
printf("栈以为空!");3 H6 Z. [( K a+ e# P$ {* r( |4 ^
return -1;
3 B& g, h: X" `- d+ W# @* M }
6 i- b. H1 g, ?- f. I/ h e=*(S.top-1);5 n/ N7 W$ ?) s) t
return 0;0 R) P P# j3 E: `) L6 y. x
}& ~7 D2 ^" M4 `9 l0 {3 ?
# N" H0 Q1 ]+ v7 F# A! z5 O
int Push(Stack &S,SNode e): E4 p" z' _# a
{
t" N# I" \ m; R if(S.top-S.base>=S.size)
- b" y4 U6 [7 r9 g) I/ i& N3 { {
* } |+ ~& E% [& ^6 d& B2 e8 b S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));! g8 Z$ z' `6 o- `$ G3 B
if(S.base==NULL), ^- E- A1 j& w% H" M' d9 g
{" d6 X. u/ q- ?5 E4 q; l' \. p1 A
printf("动态分配内存失败!");. A. z' ^( t5 \8 x0 i
return -1;
6 w/ V$ L1 g ?$ J. F2 ^ }, J0 m! \& d9 u+ y8 R# Z
S.top=S.base+S.size;5 X4 V7 L' D7 `
S.size+=APPEND_SIZE;
- S* @- K3 A7 i( c8 v }
5 r3 ^( [: C) j% N" y& B *S.top=e;
" K' x6 t3 X8 a2 P7 {! ~ S.top++;; p- b' ?' K2 U; A2 j/ s7 \
return 0;9 R4 F& t# o) m" z6 M) ?' v
}7 L( K: g% }5 I: e( A
2 Y2 I1 u2 A2 v. ~( x/ r. Eint Pop(Stack &S,SNode &e)4 O$ G$ _/ J# \0 o
{' V; y/ A7 R. g3 y+ Z4 _
if(S.top==S.base)% u, x8 a1 x6 R- @1 I9 {
{+ w, R$ D2 H, E) ~) F6 ^3 p
printf("栈为空!");6 G( S+ e7 H& j
return -1;
2 P% Y- G/ E7 A. I }
$ M% P# ?# x( [$ O e=*(S.top-1);1 m6 S# h2 u8 j6 N _
S.top--;! m$ B, e( w" w. r
return 0;
7 O8 i4 C: p1 C9 m" m- N5 E}$ s( f5 Z1 N5 \: j. _5 `( l
# s: l4 B! v, S2 Bchar get_precede(char s,char c)# I0 T8 f3 c! x0 Z# K
{0 L; p) z2 v* j# k! Q
switch(s)% s& P) L: i5 q
{
7 Q# E6 G* R! M5 R case '+': : |) X$ }- P, G+ ]( Q2 [+ }
case '-':
# M* G8 O. \- ~+ ?+ D, t3 @ if(c=='+'||c=='-') F7 h* ~8 s+ p& q" J- n$ j: p% [, p
return '>';
$ e5 F' c) q. K else if(c=='*'||c=='/')8 z" e6 B0 p, j* f- r+ X1 y
return '<';# t: c: {% C% [
else if(c=='(')( ? L) ~9 R3 o5 ~6 @
return '<';
- m, U( `( N8 A else if(c==')')
! H/ i( l6 f, c return '>';/ L$ _2 h5 F( c' H' y. I% ?$ [
else 1 T9 n& I) d7 z5 `
return '>';
' ~2 x# F$ e, |# y& V$ F: B/ A' C case '*':
5 @4 Q T1 }( w; {( ^ case '/':
0 D- O3 N; {2 x! {0 _ if(c=='+'||c=='-')
( |& ]9 [- X7 }$ l+ ^3 s4 m/ y return '>';, S8 T. |$ B3 G [! E* S0 l* X
else if(c=='*'||c=='/')$ T8 n+ U J) p. M* Y! c3 \7 g
return '>';
& F6 o2 L! _' d- k4 o- M% _9 d else if(c=='(')7 i* Y8 A( \2 p) n
return '<';
W3 h# B# m" r* Z8 t2 L( P else if(c==')')
* _5 D& l( X$ h/ j! C return '>';
$ E) {8 I" r( }! Q+ M) ? else# {4 a1 T8 I. s; o
return '>';0 v) {% ~. K- N& m
case '(':0 ^/ w4 }5 x- g+ `9 S: f
if(c=='+'||c=='-')' Q0 S/ |1 L4 B+ U
return '<';
8 X) h* N0 Q$ J9 p7 n. q else if(c=='*'||c=='/') t$ _; O0 ]! s7 T3 A {4 _
return '<';9 S5 s: r2 x U3 g# G( U
else if(c=='(')8 N; |5 ]* a1 ?" F4 z: W
return '<';
/ n3 o8 |1 U; {$ X4 l else if(c==')')
8 e( t* r9 N+ P( u return '=';
4 @- h. X- b5 D else9 g5 }/ Y8 I* h0 J& @" M
return 'E';! H; i9 `3 j9 b, |( `0 s! ]! j
case ')':
9 e! P4 i$ ]' L$ ~1 o4 C if(c=='+'||c=='-')% p( d8 b# Q$ ?* F- L( H
return '>';" L* I/ S. N2 l6 e, j& Y0 T+ J6 _
else if(c=='*'||c=='/')
1 P) K$ H, p* z6 g! j return '>';* ?, X, O' V0 b* J+ S
else if(c=='(')7 @6 d( {8 q, ^7 z9 N" t
return 'E';# |1 U. v* [7 P$ m* g
else if(c==')')$ ?9 N% {4 G. y& x' X2 Q ^
return '>';! z, C! {0 m& M$ k5 h, f: X. l
else( z5 q4 T) E |$ p8 ~
return '>';2 N& f9 v- v0 g
case '#':
( U0 H1 x7 X3 z1 B if(c=='+'||c=='-')2 s. F& c k5 R. M7 D* r) N
return '<';
# Q# R! a) J; E" U else if(c=='*'||c=='/')& f. M$ a; W0 U. o5 ?
return '<';
9 c S: K+ x' ^2 N% G! H6 Y else if(c=='(')
4 Y2 ?% O6 T( P( Y. ^. u return '<';- `: ?! l; A$ \4 L
else if(c==')')
% m" I$ \% C$ O# Z return 'E';4 [% s% |( T6 w) F
else% b/ M5 m1 |% k1 H2 `, S) R9 O M- h
return '=';; I( ]. D* i& e& I: a) Q8 k
default:
l6 ^6 b4 P% N8 y2 @ break;
# w2 N* W) @6 b- A5 D+ y( s. ^ }% T8 R4 _. b7 I B4 z
return 0; 9 q: }+ r/ v; `1 {
}5 M4 f2 `7 n4 N, \8 I
+ ]; J, x V1 t0 U0 qint isOpr(char c)) M) a- |, z# F/ h+ }+ ]
{7 i- L+ y, }- z& c) d6 D# F( {
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')# H7 Q5 C& D5 l; o
return 0;
5 A3 C5 S& u9 `% \' E: J6 B7 ?6 W else * m' y; H5 s: s# T2 U( q, n
return 1;3 `( Q0 X# T5 q1 I
}
; X$ L# ~8 k A0 G T
2 e" W: J( u# T# w# @- x" ]float operate(float x, char opr, float y)+ F. \- O% K5 ^( T1 H
{
8 O+ {) \% {0 A7 O/ D3 {0 {* y float result;! X# G- N7 E6 }
switch (opr)
7 i$ f# G% u" K2 ` {: b- T. H& G2 O. ]2 N; c# m
case '+':
# s9 ~* L$ U2 A+ F. m; Y4 h9 R3 M result = x + y;
4 Q% a- f9 ^6 A break;
6 w( g- f# \/ C case '-': : D5 H0 Y. N! N# i
result = x - y;
$ ]& f3 s+ j- ?- e T- ? break;
6 y; k9 E9 f) q5 G y6 J7 m case '*': 0 _9 [( j5 k: s1 I& m" p8 q7 r+ Y6 ^
result = x * y;
/ m$ R. m: t' p# e& G break;9 i6 B. F$ d( n" K) N! V$ m4 D0 [! F
case '/': 6 {( H- N& E9 p+ V4 }
if (y == 0)
8 ~% k- a7 q4 S3 c5 T h {
/ O% m; k) d v$ h! n+ }* g printf("Divided by zero!\n");
/ j6 u+ }* S3 i# ?$ E3 P% f: L return 0;2 l" Y: E3 t+ d& V- ]4 r
}6 x' X' d( w8 q. S& z4 Y2 j' I
else
' g0 G/ d" A9 o$ f {* g( \& ?4 i) S$ K* b4 P4 b
result = x / y;
4 Y# D# h! h) k6 ? break;+ K" @1 o' j* ^# [ \
}
$ F2 J( G/ I9 s& C+ g* B* K default: F3 F* |; }3 A$ D" O
printf("Bad Input.\n");
& m& \7 T. X; ~5 n! o7 V5 [ return 0;+ R5 u1 n1 H1 Z0 b+ g+ u+ l
}$ ?% S. d9 z# D) W8 m
return result;
9 w' Y5 |4 I: h* u6 r# ]: `. {5 Y}
( V' |1 Z/ b5 l# d8 ~
2 G9 b' z: B: e) y" q1 Dfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
$ O$ I) e4 {0 H( l: k0 d B2 u+ h{4 ]- I/ C6 a, i
Stack optr,opnd;
+ ?+ _# i1 S% K3 ? struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;& D, z5 N* m) l
char c;
& X. }5 ?" L [; I$ [- r: z char buf[16];
; M3 \ L% J/ D) o% L int i=0;
1 y0 _# u# L3 a9 i3 I* F- `) d 6 s: U. U( P9 u4 L* o$ O
InitStack(optr); /*用于寄存运算符*/
* X4 @8 L0 b( i! d) }8 b InitStack(opnd); /*用于寄存操作数和计算结果*/
. x; O% W* J! p- X- r memset(buf,0,sizeof(buf));
2 v) v8 {, ]) s. {( i ' o* V( k- W* [) D. o/ d7 {0 d1 {# `
printf("Enter your expression:");$ e( b( u) _+ l3 [
! G0 d V$ m% N- \+ k, C* k) {8 T opr_in.ch='#';+ U' m, B% b8 U, y! g6 W
Push(optr,opr_in); /*'#'入栈*/+ W7 |+ h# R" O# `2 D
GetTop(optr,opr_top);
. X* M G7 v" O, r4 r c=getchar();9 I5 H: p+ F2 m1 B/ m( ?6 o
while(c!='='||opr_top.ch!='#'); E- [* T' H- z: t. @0 g6 e
{7 R* u$ v, a: L" d
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/# }. _: M7 _1 T- ]3 s: T5 O- F
{5 [# K, y3 l: x: l" h0 Y' ]
buf=c;; U( e4 N% K" y! }! T& ]6 n5 U
i++;
1 E7 o0 p3 j1 w i c=getchar();
5 v* |& Y4 _: a; }* X }3 ~3 W2 t' v& u7 y9 m$ _
else /*是运算符*/7 {8 E5 X* m V8 a9 z
{' Z# l5 a/ J! V9 Z7 n' q
buf='\0';
% }7 c* Y6 T6 Q0 i* ?$ ~ if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/4 F! c& G- S3 j; e$ d/ |: [6 E
{
# y6 l* T. Z' O opn_in.data=(float)atof(buf);
! E" U r E5 I" I! @/ u Push(opnd,opn_in); S& ^! q9 N" G# q6 T a
printf("opnd入栈:[%f]\n",opn_in.data);. l( y; s- j9 [) N. Q, g% V
i=0;- K$ d6 }# V8 d4 N& P
memset(buf,0,sizeof(buf));
1 U3 S- C3 T3 C" ]1 U5 S, ^, s }7 c! l- A7 R M' s
opr_in.ch=c;! U4 R3 U r! w" ^
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
1 S' k0 T0 n! l {
: F1 j, B2 C {; ]$ I7 D4 c case '<': /*优先级小于栈顶结点,则运算符入栈*/, u# C; n/ Y9 L! {8 e( w
Push(optr,opr_in);
( ]! E+ m; f& G1 j- b- B7 y printf("optr入栈:[%c]\n",opr_in.ch);
% v! v' z6 ]( K: [+ `) c; D c=getchar();
# D4 N: F$ ?8 J3 L: F break;
) y5 F, `/ f& U! q s* D! j case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
0 G0 j- T+ c! ]3 W; P' {1 _ Pop(optr,e);5 y; S0 x$ X5 c. ^
printf("optr出栈:去掉括号\n");
/ F* I# B. d' T, v8 _' O% p8 l c=getchar();
% U6 M( [/ R; j% T- _ break;. S: m4 r7 S$ h0 h" K. z8 T
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/8 S5 ^/ z3 Y3 @2 u0 w; w
Pop(optr,opr_t);. a5 ?5 e3 N3 D
printf("optr出栈:[%c]\n",opr_t.ch);# X+ u3 s }9 s: P/ @! O
if(Pop(opnd,b)<0). k3 e+ F1 H. Z
{
$ O0 D V4 o4 n. D; o3 t' H$ m" _4 V printf("Bad Input!\n");
. L# V ~/ _; P fflush(stdin);( i/ d) S% c% Z4 j' O. {3 L( A/ o+ o, X
return -1;
8 p3 B& M9 \# K- z e3 [ }: O) c+ u0 T, r/ `: z5 `7 c$ u e
printf("opnd出栈:[%f]\n",b.data);5 K5 L n2 t5 \$ S6 g' u; z6 Z3 ]
if(Pop(opnd,a)<0): A9 {0 Q O! v6 T5 n
{) R5 | r7 j# I6 U, ]. g3 c
printf("Bad Input!\n");
; ?% S2 |0 y6 ~& w/ L5 t* K0 M fflush(stdin);- _+ y9 Q' O1 Z ? [
return -1;
& X: I: Z1 L: ?% j0 ~) z }
# R& u; k9 _4 \7 \! x printf("opnd出栈:[%f]\n",a.data);
+ C! S! b v1 i3 S2 D/ t8 v opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
( h+ n- m4 Z9 f' q u' L Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/% L) Q7 C* s$ F4 Z& I1 N
printf("结果入栈:[%f]\n",opn_tmp.data);. ?0 u! n4 L2 y( K/ R
break;/ `2 ^% b+ V+ L
}& Q; b! w: R4 |, T) j
}# j4 Q: o5 {/ G5 f- `5 }7 J
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
3 x; q- H$ p9 Q( _3 h' t8 \ }
) O% v- o0 j7 e9 C5 O4 T6 ^" { P; ?2 t1 s GetTop(opnd,opn_tmp);
) c+ ^. l. E* H0 e! X& C0 [ DestroyStack(optr);
4 V, f) I) B$ Q* I0 g; O DestroyStack(opnd);
5 n. P8 R4 t/ R: w" v! g/ u+ J return opn_tmp.data;
/ o0 ~+ x$ E' ]$ ]8 G- p8 Y}
( ^( G3 h) g7 L8 L! @) z
4 a. W @" E: _3 xchar *killzero(char *res,float result)
# Q1 `: ?7 b8 e5 p5 y- G; H/ m{$ ^! L [) b+ j$ s4 w. K
int i;
; h4 }; ^0 j: Y t+ y# h
' o0 x6 e" B: c sprintf(res,"%f",result);
, L" E. V# v$ r! m) H% p i=(int)strlen(res)-1;
& q) x1 F$ R8 u while(i&&res=='0'). E: j! E7 z/ Z5 f
{
( G1 G/ x2 C _1 K2 a/ t1 M res='\0'; Z) n- x% Z. h6 W8 @# H, f
i--;
& G p; G: V! o) W }
# E* c+ O4 i3 [7 @; r. E if(res=='.'); i6 O5 A- q. o3 B, |9 \* [
res='\0';) T: I& b) t/ _0 o
return res;5 M2 h. Z: T1 G
}- D* ] M7 J2 {$ _3 ^
+ l$ q% b6 M, J
int main()
, j4 Q# ? C3 c' t7 K2 r' s+ R' g{
8 w) A, z W4 A( R0 `3 G' |+ [ char ch;5 u/ c7 g$ b# j# ?( ?& v0 K
char res[64];
J$ E$ H: J, v) g- u0 I float result;
) V6 Q% {/ v+ B while(1)# e g4 o5 C! D- h' k4 J+ Z
{0 A& a ^( d/ S5 I6 K# b
result=compute();# a9 ?+ `3 L5 g* }) K+ a
printf("\nThe result is:%s\n",killzero(res,result));
+ `3 S3 Q/ g) t3 \( S- O printf("Do you want to continue(y/n)?:") ;
v* \# Z7 ?/ I5 s& L7 o ch=getch();5 ^9 k ~( }6 {6 c
putchar(ch);
/ @ h& _ b' Q7 ~( o3 `) W, z if(ch=='n'||ch=='N')
/ G* K" W2 j2 }, A% Q break;
4 U9 b9 [: C( ?: _5 h8 N8 g$ } else% e# N7 ^; n; v' q* k* ]$ z4 u+ w
system("cls");& `- ?' g& [1 x- l4 Z. G8 O) ~
}
* f4 B7 w1 x. Y9 @2 U+ q return 0;
3 T4 N H7 h- t. Q3 @/ _$ p}6 @1 s4 g/ J" q
5 L* j. x- F; Q+ H
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|