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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.! T5 y0 w/ s3 e1 M5 ]
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=7 W2 j5 E# V* c5 G$ d/ k
/**************表达式计算器************/
6 D4 }9 |, d' }" V4 O& t" f6 f+ w( i#include <stdio.h>0 O- d! }. f$ l- i, }) ]
#include <stdlib.h>6 o) h# C* |1 R, d9 o$ e j. ?
#include <string.h>0 J+ ?# A$ u; e1 u2 x a- j v3 s# z6 i
#include <conio.h>; f& B8 G* E, P
#include <malloc.h>6 l+ M2 L7 l6 w5 }
7 V+ [7 y+ M8 a8 U
#define STACK_SIZE 100+ O6 T+ M; `% b
#define APPEND_SIZE 10& \: l5 Z) f- s4 z3 M4 ]
/ W2 B- e# G9 ?* Q6 b4 t4 L
struct SNode{4 B8 b; _# v$ ?) d! a& y! s6 l
float data; /*存放操作数或者计算结果*/, w- k \. J, t! V/ h5 D
char ch; /*存放运算符*/
" r$ k, y' p" z6 b; z' S};" z( z/ x! T( H+ n
# m$ y9 O& U8 W8 z' f- _struct Stack{
! {2 |% A6 ^8 d, @ SNode *top;* D8 |' Z3 \; m. `9 F% Z
SNode *base;5 h( }! p. m1 h1 X- ?, O* o3 M
int size;
9 T. h4 Z" j; m- f4 }) Q};) r# W1 V: C7 P! g9 `) i6 w+ D2 U
+ O" E$ }* k# y' m. _
/*栈操作函数*/ T4 n7 Z- n/ }' n- B% b
int InitStack(Stack &S); /*创建栈*/
% j) V5 J* I" r2 Q0 L; K! ?int DestroyStack(Stack &S); /*销毁栈*/
3 ~+ W8 h9 L ?. o4 q: [5 fint ClearStack(Stack &S); /*清空栈*/2 e* F) Y5 u1 Z6 l! a
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
/ t9 N0 ^' w L, Y1 p h9 `int Push(Stack &S,SNode e); /*将结点e压入栈*/9 g' Y @2 z3 K( ?3 U
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/% L) a3 m+ i' O
5 r7 N8 _( }6 S% R5 Q5 T7 P
/*表达式计算器相关函数*/2 o6 L9 B: A9 ?0 S; b D! X; b+ ]/ t
char get_precede(char s,char c); /*判断运算符s和c的优先级*/" A& M( d+ e6 E, M
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
% c. ?/ M1 q( }8 N/ Afloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/0 m+ j& C! T$ I- R2 S }
float compute(); /*表达式结算器主函数*/
: P& P& m& H: rchar *killzero(float result); /*去掉结果后面的0*/
- O. i5 L: `1 i- U
$ H7 p4 q- J( f% q+ h8 E8 t: A( Aint InitStack(Stack &S)% l" F1 S; t) e
{
5 t. g/ s7 s- S# p$ X6 R4 E S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));0 O5 u: s' h/ N: w
if(S.base==NULL)0 `$ h7 x2 E9 q
{+ |$ l# x$ }+ ~6 J$ Q
printf("动态分配内存失败!");' _# H( U7 a1 v1 j# E$ n8 y
return -1;
" ~4 ?; \$ {8 j& q* ? }1 x+ r! x! q2 `, _
S.top=S.base;
& d& r: Z( F* y7 i0 ? \ S.size=STACK_SIZE;" n# E% X# S2 z, a
return 0;* {1 z& f6 W, D. U
}
* b+ y( U/ [) G) x- P' M9 X' _
/ ~4 S+ O n1 Kint DestroyStack(Stack &S)
6 [% Q. G6 B0 h5 ^3 n{! g" ~3 M( n4 O) r
free(S.base);
X5 _" @) e; c" x( ]+ F) y return 0;% V. P' c: ]% m
}
! k1 d0 C: b% z. m, @; n! I2 t; P; X, S
int ClearStack(Stack &S)
1 c/ Q$ a( ]2 v7 w# Q% H{1 Q7 N9 W2 {) D W) V
S.top=S.base;
0 V) {$ ^3 u9 _4 l- L return 0;9 J+ z* Q+ d* S
}
0 F$ ^- b/ K, p) W5 ]$ m. N8 |; L
int GetTop(Stack S,SNode &e)2 C0 q0 g& ^( m' J! ^( U8 t
{' Q! h! ?" {; v% Y4 M6 c
if(S.top==S.base)3 u* e( C7 q. a7 J, B+ z6 [+ G
{- ?/ E" B) Y: I) L9 s) s* P
printf("栈以为空!");6 w) q% Y, K/ A
return -1;9 Q- a- N* b- P* Q7 t, O. s+ M
}
* u7 Z1 H2 E3 W1 } c) F: Y e=*(S.top-1);$ ]7 A. t" A. G' y; o
return 0;2 J, F) x0 I+ _' b) z ?( [+ k
}# z! Z7 `/ ^( E) ^* H! S! \6 a
( P$ S7 Z1 b" a3 |; F9 {
int Push(Stack &S,SNode e)# ^8 S( f& t4 G* v0 i$ e
{
8 H' ~+ o& B' i+ l3 O( e0 R: c" J if(S.top-S.base>=S.size)
?. k8 @, `! S# M/ d {% W- N# `% o+ s- x: _- D$ c2 G
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
4 h2 z1 [. n9 T# A \ if(S.base==NULL)3 z5 Z" k' }2 ?! @8 q+ C
{
0 I9 X; E$ T$ u3 E: | printf("动态分配内存失败!");
7 i* \2 O) b+ J* w* F8 N8 A3 i+ V return -1;* h6 D* D& ~% [5 D$ Y% K; `
}
) N/ Y6 \$ J! g9 `% |! R, n S.top=S.base+S.size;
2 x1 U9 M3 B, H! U S.size+=APPEND_SIZE;
* G2 t. {+ e W0 r' v }
4 a$ r& p& G- f2 v: j& p *S.top=e;
- c% J0 A1 e; N S.top++;
c6 m' u: R+ d. S return 0;
) N1 E6 q% C: H; g, y}( z: }6 |6 L! t7 Q* C- b
5 ?7 V( I; Y [& t$ v
int Pop(Stack &S,SNode &e)
5 s" x. D7 B7 ?- e# s{
% B. g1 J+ y& N if(S.top==S.base)
2 u2 f( [* k; z0 j/ q) [, O {% Q6 M& U$ B6 h+ Q! _1 w2 _
printf("栈为空!");. q3 C+ x% Q/ k P4 G0 q
return -1;2 J) _ \6 k# b6 g
}( ], {- n8 u3 v! S3 B% L
e=*(S.top-1);* O: R$ l- g6 k A8 t
S.top--;. C# D$ L% ]( J9 P0 m
return 0;1 `0 q# J& A" q
}: J8 @/ \" o3 U: o' O& s; w$ l; k M
* M/ S* A$ T0 |7 S, r# ]char get_precede(char s,char c)
* }1 m B. B( x( [4 S{/ ]& ^, g+ u. N; r! K
switch(s)# K! s" V: K. m4 m6 O& ?8 p
{
6 e4 [$ I* K# N3 w6 b) U3 c case '+': 3 ]$ n9 W7 U3 ^, ^; N" k! Y6 D
case '-':
^; j; U' u' g4 C2 ] if(c=='+'||c=='-')0 O, q( a1 N) P) R" D, D' D5 a
return '>';
! Y; r+ {+ D2 s& r else if(c=='*'||c=='/')/ y- `# B- Z- b3 ^
return '<';5 L5 |# A9 N: p8 x. V1 Y8 u
else if(c=='(')
7 y9 b. i) v/ D/ l. p: a return '<';
z& M4 [: d3 Z- k- ]7 F# x) W, Q9 z else if(c==')')# c6 Y9 y# ^! B8 h
return '>';
/ F9 @! @5 p+ s) x; m3 _ else
+ y& J1 V" t9 l% k0 S return '>';
+ U) }" {. D% y case '*':4 t' r ~0 C- F d' y& ]4 K& I
case '/':
: D0 c; ~- B1 L" K9 ^: C* v4 u ~ if(c=='+'||c=='-')
1 s7 e" g% G8 f! U return '>';
- j+ \0 ^+ d( X; d( n5 ^4 ]; n else if(c=='*'||c=='/')* `8 c; M- R3 p" `/ p
return '>';- A' ?3 q: g+ r7 ?+ a
else if(c=='(')9 o# a- h/ M* w$ \6 I' U
return '<';' I* r( c# e1 o! R5 \; R; E
else if(c==')')9 M1 }+ d- h* j9 _
return '>';
$ e+ P8 M+ l& s; A4 [8 Z% W else
D6 z+ X& K" z" y' W$ b! h return '>';
4 J) h- V! ]/ i3 h case '(':
9 g/ P1 J6 t. G I# o' W' V4 ? if(c=='+'||c=='-') i- o. ^' J% P* E
return '<';
% i4 j/ u5 f4 D/ } else if(c=='*'||c=='/')
( n* [& m9 [, a- S1 q! s' x% @: y) d, G return '<';6 `: p* M1 d* U9 G
else if(c=='(')2 S$ O1 \5 r* Y1 I5 A* j8 @
return '<';
" K0 y; P: d. }& T& O else if(c==')')0 J1 M8 V4 [2 W# L. K, M0 E
return '=';
3 B4 w) K0 D6 B' T+ y" G else6 ]2 z9 S9 @1 j- s
return 'E';/ [ p( q# G+ r
case ')':" o4 ?* w" k# x* r" r
if(c=='+'||c=='-')
% P3 D* d8 R. o return '>';# I6 i: B. d0 i& o
else if(c=='*'||c=='/')2 s1 ?2 S+ u, z; d
return '>';/ z7 W W5 ]3 @0 r- W5 B
else if(c=='(')$ C: ?2 d! U% ]' S1 k
return 'E';1 v% t# R/ R ^* z% [, j) r$ Z
else if(c==')')* b$ U& w! x9 Y2 D* d1 W7 B* V, t! c
return '>';! {$ a' z8 h5 W! m6 Q9 t$ B K
else
6 `8 s4 i6 ]& i. f, s return '>';
% Z& i/ l$ I. E# ~' j3 ]7 M, p case '#':
; P8 t6 G% s) g) W: f* _& Y* o if(c=='+'||c=='-')
1 \1 f9 d# `& L" Z- j7 t1 N return '<';% |$ _& q: f- F% S# T3 w, c
else if(c=='*'||c=='/')* S* x1 Y( H( e8 N o) `
return '<';
) q7 W. W; ]( o else if(c=='(')
h; O; s+ T0 n return '<';4 _! O/ {0 j; H% G
else if(c==')')& W0 U" y" Y. u2 h0 j
return 'E';
- w. E- @. i; ?" T8 W else: d" T( v9 y; g! _! f# t2 ]3 a' l2 I
return '=';
/ ?7 L' A0 i% R! c default:
/ G3 A5 k d3 x9 l1 x: Y- t- F9 c break;- n: Q0 x$ T# }1 g0 M# `1 U
}
) {2 j. {6 F# q& H0 P/ x return 0; ) A+ {) }& ^" B. w
}
7 ^8 J1 c/ d- }
4 U5 G& t. V. \4 ]* w$ }' kint isOpr(char c)
4 u6 O4 `1 J/ W# j{
, e% y" J l+ c6 m! m% e1 @ if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')# U/ g' C; Z& } _
return 0;
4 P& C- M0 U& j4 \$ P! x else
+ ~: @9 Z. W, S6 E5 H& }8 ] h return 1;
' ~) o5 n- i) g+ S! m3 d}
. E7 @3 d2 C, Q9 \. W
~1 c$ \0 d3 Qfloat operate(float x, char opr, float y)$ U- w. K4 |4 W( e
{! j i2 u5 x; M+ Y3 ]. r- Z
float result;: M) B1 m9 a2 P" m! @0 B
switch (opr)
. S0 c! C0 b2 o: `9 [6 ^ {
C' P+ ^2 h, a2 f0 ^ case '+': 5 z7 j* b8 f. p) N1 b- W3 i4 a. o
result = x + y;
; f9 F* y# ]8 m5 ~ break;4 I: [( {4 p! s. ^" G S& X# Y
case '-':
6 ^7 h; {( j; A6 b result = x - y;
# s( g9 }0 [* f' ^* Q break;6 S0 B9 w$ s4 j( d2 T& A
case '*': g5 P; p# \* n( W$ z) Q5 W# `& T1 C
result = x * y;
( }( M, q# [- p break;6 d: u0 ~. v1 w2 v3 K' u
case '/': - D" E1 |& C) U ^6 q" J5 a
if (y == 0)
8 }/ s% f/ J6 o. o, M# p1 ` {0 M1 U4 T6 f- F$ g
printf("Divided by zero!\n");+ c4 c) G- X+ a
return 0;
3 R3 d: x& w! j1 V, J6 F }
+ \* v, a- T0 u+ y else
9 B7 B9 u9 ?0 u0 P! F {
& a6 Z, Y/ A/ u result = x / y;1 g2 h+ z! {) p( f$ z5 t- ]# y
break;2 y! h3 Q4 B6 l& K
}; B5 U( Y# q2 J3 i# m4 g$ s; p- a
default: 3 ^: U8 Q. M$ `
printf("Bad Input.\n"); % s+ K: [: P S9 |; T4 {
return 0;2 N5 {% _7 ~5 C/ A9 j0 B
}) F( r4 } C( I# f9 M7 E- E; W$ J
return result;6 p& L; P" x9 o6 _6 o7 ?
}
# j; u3 ]$ R+ x' O% s, \) {; I
, `: c; L* S9 w# Lfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/8 ~6 Z- D& H; l V6 @
{6 P1 M1 N- \, j$ |* ^5 @- k* \
Stack optr,opnd;6 U9 P' t7 \' K0 O/ P" A4 Q
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
# l3 [3 d: D8 f* J) K2 I! x char c;
U: h( K* P% ? char buf[16];0 H" t" @% D( C6 }
int i=0;
* D: U5 x r; T
- c, c9 [/ a+ q2 G* x$ J InitStack(optr); /*用于寄存运算符*/
# r/ |/ Q8 C3 s: H0 a2 d% F- [ InitStack(opnd); /*用于寄存操作数和计算结果*/
6 H. q6 e, n: A6 v& u1 e memset(buf,0,sizeof(buf));, A( f2 w7 P! b4 c' `5 P
+ i0 Y/ k* h/ }( |
printf("Enter your expression:");! a$ C1 N! ~7 g7 b! I
- ?! a( \7 T' H( P opr_in.ch='#';# z* _( t3 i0 L5 @, I
Push(optr,opr_in); /*'#'入栈*/" l% }8 Y" I- E8 D
GetTop(optr,opr_top);
: D3 s6 k) j& V; M c=getchar();
- K+ y8 Z8 f. S n8 t/ F while(c!='='||opr_top.ch!='#')" X% x0 K' `! z% ~! C2 H( |
{% N) T/ h; U; m E1 g$ e
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/5 h7 ^) Z' G1 w4 ~2 S
{! R( a# H4 y8 z% Y+ o! k5 \; a
buf=c;8 p; T ~2 s* S x
i++;
2 r0 e8 h* O# W3 J9 L9 l c=getchar();
' A+ o D5 d, W* C }) [, Z: {8 q2 n
else /*是运算符*/* ?0 V9 T$ ]$ e: @6 l
{: Y7 I' _& e C) v' O, s& \( Z
buf='\0';3 c: P+ M7 S/ r: G! ^$ X# K, T
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/% I9 Z4 Z# o' g. e" \# s
{/ i3 h) K+ K* G) i8 {
opn_in.data=(float)atof(buf);
. ~4 z* J* u' c" c" U Push(opnd,opn_in);. e! \6 R# @" e4 \ K
printf("opnd入栈:[%f]\n",opn_in.data);% L( b7 O- U1 w( [" U8 ?
i=0;
$ v4 U! ]8 Y" j memset(buf,0,sizeof(buf));3 u3 c; U4 F! h6 v r9 s, o
}% ` d7 a6 z8 Q% S# c: r
opr_in.ch=c;1 _) O! v' C- W$ p2 H2 K& n
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
# ?5 I. u6 [3 D& A' t" ^% p {
9 e8 G3 ]5 V. U2 K: L# h3 c4 G$ f case '<': /*优先级小于栈顶结点,则运算符入栈*/2 [2 T0 g1 l7 x- v
Push(optr,opr_in);) S0 [7 a( X$ @; @
printf("optr入栈:[%c]\n",opr_in.ch);1 i% ] Z. O5 {& E) p
c=getchar();
1 ]/ }9 F% |7 ?' }0 t0 c1 o break;
0 ^$ `! E% i: K6 J- \ case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/+ s4 U D" A# K" H
Pop(optr,e);1 o- X5 V4 v8 z" Y' q4 N* T' l+ L
printf("optr出栈:去掉括号\n");) l+ X0 ~# `0 l" _/ F N- i
c=getchar();
5 I* B3 N& L0 d( u0 s break;# B( x, x% ~$ m- D% O( U' w5 v1 q& D% O
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
" i% i3 H1 G7 Y Pop(optr,opr_t);9 U7 t [+ M. a( p+ q$ }
printf("optr出栈:[%c]\n",opr_t.ch);9 r, b( g [9 ?( C7 q
if(Pop(opnd,b)<0)
7 ?4 L" B( W" K. @% t0 m8 f$ X6 I {
' [+ A7 }: U8 m- A2 m# a$ S" _ printf("Bad Input!\n");; t: s2 T4 z3 _5 j+ O
fflush(stdin);
5 t k/ ^" G) x; M4 e( B return -1;7 O- ]9 e( H. g) h7 s, ^' O
}, E4 x9 Z$ k G! k v! z
printf("opnd出栈:[%f]\n",b.data);
' j. H- A6 o/ h! i* ` if(Pop(opnd,a)<0)
) {& l9 t7 S$ i- b {
4 o$ `1 d0 W9 C h& L* R/ U printf("Bad Input!\n");
* \7 x; M2 T' Y fflush(stdin);
% J5 F! \% I8 j return -1;
/ {& Y+ ]. y2 Y2 f }% l' K' L' B0 J+ {! {
printf("opnd出栈:[%f]\n",a.data);
9 F7 F1 D- f* f9 H, Y0 \4 f h opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/( l- R" C; c2 B2 }, F
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*// {) p1 C6 Y/ Y0 }' I" J7 {
printf("结果入栈:[%f]\n",opn_tmp.data);( p" E! q8 f c" W% z* i
break;
}% V; t+ ^9 U/ v: E/ O& N) W/ v }
0 Q! B% _% G' t" C }
1 j" I/ L1 q+ _( G" y6 E GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ ) A# n/ T0 u* w# E2 k
}" q: ^& f+ ^. J: s# H; N8 a
GetTop(opnd,opn_tmp);7 _* G) L% m+ e: M0 e, M
DestroyStack(optr);9 {9 b2 k/ P, f* l# E1 J
DestroyStack(opnd);
' s) g$ o* t5 I, \: ]- q8 v' }% a return opn_tmp.data;
) @& j, O A# g}& g) J3 \& m8 p0 v. X8 {8 I
7 b) l8 s! H2 D8 D6 K) N' Y; o) Ochar *killzero(char *res,float result)8 Y; Y! I, n' c' l- \5 m' Z
{! `1 v# R7 e! s2 v
int i;
! P& Q$ W; q+ M( V; s" [0 S" _/ y. N) b$ L
sprintf(res,"%f",result);
5 \5 t9 L2 f8 C$ n0 n: Q i=(int)strlen(res)-1;
# a5 e) k+ ^! }0 j3 o/ {' ?+ R. j while(i&&res=='0')
. s6 |! [6 D1 p7 t2 ~: z {: _% t# f! X6 b, I6 J) P% H
res='\0';/ l3 R) ]' b* h( Q2 y" B6 J3 P
i--;
- w! s% z& C: _& C }) \! d' E: N7 y
if(res=='.')
7 E( J! }) e2 g2 d5 Z/ p res='\0';4 C' x( R/ Z S" \3 }8 G
return res; r# x2 Q9 }$ e) M2 q3 }) `2 L
}
' {! O E% {$ _( ~+ G% X" {& ~, X* f+ x$ D) e+ l+ n
int main()
8 U0 q! f# @+ F{/ {7 d/ p3 w/ n1 {) U5 [
char ch;
+ Y3 ~" O4 Y8 n char res[64];
! e9 o! k2 T* v9 ^ float result;3 x7 `4 g& A2 w# g- C3 R. r9 x
while(1)6 K9 v$ G+ \" ?, A
{" A, _2 E; o- T Z" E% x
result=compute();
2 B$ S5 B% Y/ ~+ H) K7 p: x/ v5 l printf("\nThe result is:%s\n",killzero(res,result));
- r9 D' w3 h( w3 o" P printf("Do you want to continue(y/n)?:") ;
' Y& m- X* C, m0 `/ k; q ch=getch();
9 r, }% p3 B: A putchar(ch);( L S% P5 v7 b9 n3 ?
if(ch=='n'||ch=='N')# L2 p0 V6 J2 ]
break;
* d; J% T8 L3 g9 b else- T- Y4 U1 ?8 ~4 u
system("cls");
# O1 d! \' i3 y }
5 y+ @: f! M3 A' V return 0;
! U8 [ o7 N y- k+ g( D) d2 E$ z0 F}
. |1 g x5 w }7 ~+ E( f% ^4 o$ y2 \1 v- s6 ]( m
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|