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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
" w3 A# O3 g( d+ l% g- f9 O s程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
8 L- c, U; k( w/**************表达式计算器************/
; L A: m* V. @, w* l#include <stdio.h>
. V1 g; {1 k5 w) ], ?/ ]2 l#include <stdlib.h>2 ]; E3 w' n* y. E# `( U
#include <string.h>5 d$ u) M1 F# [
#include <conio.h>
( A, m4 u8 U$ `+ p; g#include <malloc.h>
* k/ C2 A% D c& J! Y
" T" g, Z4 a2 z+ r( I1 b" n$ g#define STACK_SIZE 100% a; o6 q7 e/ Y# T7 @; \% }7 H* G
#define APPEND_SIZE 10
$ w" P/ e. }# o5 G( d1 c2 b, L
struct SNode{
+ a0 e7 b) d( m7 {9 p+ P9 P float data; /*存放操作数或者计算结果*/
& L2 z+ G7 b0 ^. s4 F! R char ch; /*存放运算符*/, `5 f' ^) u2 J2 ?1 a( v
};
$ k5 f+ o7 ~! x% [. t8 Q7 a
; D: ?7 E2 h9 n1 f! p: G5 Lstruct Stack{* c. S% B0 Q2 r) `0 f
SNode *top;
j' n& f4 y/ c SNode *base;
# g. [( H7 U/ e, \5 j* h! M int size;
" F" M, e" h* N/ `8 H2 g};
: P6 A6 {& t9 K* X2 w" l* }" k
/*栈操作函数*/( |- Z) h Q% h7 r
int InitStack(Stack &S); /*创建栈*/
9 B3 j( d4 g, U! aint DestroyStack(Stack &S); /*销毁栈*/2 l4 }+ N' H8 T" b0 e+ x. h; ?
int ClearStack(Stack &S); /*清空栈*/
4 F i% ~; ` m( Vint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/+ Y0 ]$ K4 `! C S- r3 e
int Push(Stack &S,SNode e); /*将结点e压入栈*/
1 B* A/ a8 Y" b: r+ Q* ]2 o' qint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/3 K' o6 o* M3 Y. Q1 C! t
2 R* a' F3 Z7 ^3 D( ?& K( c7 ]5 x( A
/*表达式计算器相关函数*// {. {0 z7 i3 w: R- i+ a
char get_precede(char s,char c); /*判断运算符s和c的优先级*/3 t" @/ P- ?" t
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/: q$ `1 C0 y, C$ U' n7 j- H
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
; ]7 S+ h* _# v0 ?1 qfloat compute(); /*表达式结算器主函数*/$ P: Q9 P; v' P. O1 N
char *killzero(float result); /*去掉结果后面的0*/ " p2 h9 {) v0 p
: N. K w- K2 W/ V9 o3 v# T1 Hint InitStack(Stack &S)
) f3 I) Q! P- N, E& _{% Q8 x4 k( g- V& h& t8 E
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));: q% T+ H- s0 B$ g
if(S.base==NULL)
5 f4 b. v/ R% J2 P2 O/ k {$ ]7 d" o+ A+ V2 F3 i7 j- c! U+ y
printf("动态分配内存失败!");
% b6 G; C0 p; ]4 C7 q return -1;2 T ~4 G5 Q; ?3 }% U& a$ X8 U
}
# w( a4 N9 a6 O4 T$ F7 p! I. a8 T S.top=S.base;8 J8 b1 W" @: Q# t7 {$ B
S.size=STACK_SIZE;1 q" O! I% @. L3 ?2 _
return 0;: z+ D5 d# H' ^( H
}
# G2 r. |* B$ @- y$ r" e, w' v) [* K
int DestroyStack(Stack &S)* M9 M6 l. D5 ]( g1 n$ {7 X% h
{& k' i( a, H5 d+ X; t
free(S.base);
4 N7 z, ?( i: u) P return 0;5 d. u3 |8 m4 i- l9 O* i
}4 Q) _; o8 ?) F0 L& t1 b
. D6 [8 P4 g& m% cint ClearStack(Stack &S) s% q6 z& p; T" w3 ~! f* ~
{' W1 |, c- h* L- f/ M2 G
S.top=S.base;5 K* V+ d8 h: Q% z2 N
return 0;. m) _( w6 w# V. T1 b8 y+ e4 Y
}
& W" e" _* {- r+ H3 H
; u4 d. v* X) C4 r- N0 F0 T& oint GetTop(Stack S,SNode &e): S+ X/ m2 N; `8 L
{$ P0 I+ p+ L) H+ [! x: q6 _4 X1 D
if(S.top==S.base)' Z/ ?& n# V H" h/ S d
{
! x. ~& m- g2 V1 j6 L' Q printf("栈以为空!");
$ I& _! F- c$ p" e+ ] return -1;3 v( Z4 S2 ]5 r' @8 d$ f" K
}! _ a8 b( g! q4 i r8 h
e=*(S.top-1);2 z. G* G( F+ `
return 0;
' \4 b, m/ t; F p/ ]% G" R}
' W" z4 ?" ]( y$ g% }4 V6 \6 f' C
int Push(Stack &S,SNode e)
O+ R$ z1 ~; C3 g9 x5 P{+ O: {; P$ Y ^# _/ g. @" }
if(S.top-S.base>=S.size)$ j _8 L9 K' K' h4 L
{, L. s& R0 c- a4 h3 U& i" }
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));1 M* `3 }8 a! L( V( U1 H
if(S.base==NULL)- Z; {5 L& R& A3 F
{8 r8 O3 o5 V# M: j
printf("动态分配内存失败!");. X2 X9 [' X3 h5 h
return -1;6 b( X0 \7 m7 s% E( Q
}
2 A, y5 _, c( G# l S.top=S.base+S.size; \* r. E0 Z9 H1 j5 N
S.size+=APPEND_SIZE;
9 O1 H2 j7 e& U! p D7 K( g; ?) B }
* I$ Q7 m' l3 ~* W3 J' p6 a *S.top=e; p% ?. o9 R* ~# t
S.top++;0 c6 T1 l; g$ m2 T; D4 T' T% r U
return 0;
{* I' x2 I% T; h A}8 H E4 `3 G) U( k2 l: B
! z5 X( i( Y7 M/ uint Pop(Stack &S,SNode &e)
. |/ a( ?! _! g- i{0 c, g/ i% m7 k% o. k7 z9 F% i' Y
if(S.top==S.base)4 n1 o2 h) ^( V- t) R; Y3 |
{
8 } L* \' `+ y; Y4 g" `; h2 C printf("栈为空!");
1 t8 }9 n/ y6 j" g return -1; R5 ^2 |* H, j. l3 m. ~$ K/ h" @
}
. ~ V4 |% A( V4 X; w e=*(S.top-1);
5 w6 ~9 X% g- r# G0 Z S.top--;0 D. y$ ~5 E% n8 _; d& s3 B
return 0;
& R2 o. P7 m- n( M: D6 s+ ?}
. r. E& j& b2 w6 w
' [: `( [( V! Vchar get_precede(char s,char c)
: n/ C3 P) {+ _' \{( t& @- r7 ~( Z7 w5 Q
switch(s) |( n4 H$ y; l$ g2 u. r
{
! x6 ]+ S% E6 ~ k1 P/ U: L case '+': # _8 l& L1 F7 [4 k7 {' A6 Z
case '-':
/ ^" g+ o( @. J if(c=='+'||c=='-')
7 w( l, O. N1 q8 F) R1 ^1 y return '>';' g/ p. e1 r9 l0 ~) I M
else if(c=='*'||c=='/')
5 `" c3 e; h( B3 v0 R1 M return '<';
* D( T: @. m8 k- f! V/ w: _ else if(c=='(')/ {, N3 ^+ a U6 y# I1 V) q/ F* f
return '<';
! U% m% Y; ?, T/ d1 t" O# B2 S" } else if(c==')')
2 D4 h. h; o/ h3 ^' |! ]$ z return '>';
" T' P' m1 [" n) a$ x0 t7 x else . Q$ ? y E0 z2 m
return '>';
( H, J# g3 n: S* B9 D case '*':% u% x0 R" N% X4 ^
case '/':
& |1 }" z l& u: _5 T- Y5 c* a if(c=='+'||c=='-')8 g- o0 }5 h$ S" D1 W7 b4 o
return '>';/ v u- @5 T. q& Q1 P
else if(c=='*'||c=='/')+ C0 W" f- u! p1 l
return '>';0 H t& O1 I' V- e# q _; B4 C
else if(c=='(')# D) ]5 H, l+ x- Z2 W0 y {& v2 a
return '<';
) C2 d2 E8 `6 E& s( ~/ D+ U2 v4 e else if(c==')')) L# j- o5 C& X b
return '>';7 T, Q; B9 J* L* @/ X/ W4 X: T
else
) h) B; W$ k7 n* l8 N& ]. p' D return '>';
: s! m* i0 l+ O) F case '(':
4 Z0 _, d( U8 q: @' L/ w4 f M if(c=='+'||c=='-')
S' {7 H. `; c' r% ~# y& w2 N return '<';
% C. }) y! q5 }) T else if(c=='*'||c=='/'). N4 ] @; N3 p6 f( b Q, u! z5 L
return '<';. |+ W% G2 e( Z0 \! {
else if(c=='(')
" K9 b0 i6 Z0 p/ ]3 [ return '<';
9 F6 B1 b# N G; F else if(c==')')
. P' _ `3 c8 G' z; ]; A; l0 ` return '=';, `$ U! W! [, }; o$ |4 y
else- j7 K* t3 H$ @, s5 a3 W
return 'E'; W& I2 X; g; O$ {
case ')':: P, G) n2 d: A6 s/ w! j5 q7 x1 z) ^
if(c=='+'||c=='-')$ v/ z1 Z% R- D; O, T+ j7 b, }+ v8 B
return '>';
$ W2 f& D, P/ Y: h else if(c=='*'||c=='/')
9 D1 f& X6 P p. ~6 g7 K) e' m return '>';8 m: P* a+ S( F7 G
else if(c=='(')9 d0 Z! L2 Y, y2 |2 \1 h @; Y
return 'E';9 _9 o0 O2 j' s
else if(c==')')$ c/ E, V8 j. O; y, ]0 Z
return '>';
% O* E$ v5 s! n4 ]3 ] else, W$ J7 T# o8 |* F7 e; K
return '>';
& e, J* e# _: ]! P. _7 K3 p case '#':
1 l( [& R6 R8 q' {7 R& B5 C" { e if(c=='+'||c=='-')4 M1 `. k) O8 d
return '<';
3 Z& ]. L# p6 [- ^: p else if(c=='*'||c=='/')7 D( s, M' g6 ^! J1 T8 p
return '<';
5 o' {0 I5 j* e# J5 S else if(c=='(')5 v" a! s( Q8 t" j. w# v [# ?
return '<';1 v% c- ?5 K: K" C
else if(c==')')2 h3 c- B, j! G$ F; \( U" p. _
return 'E';. q8 c% W) q2 a$ T" @* H
else' _% i- @3 x" ]# S
return '=';. q# W/ F4 v8 Z& h: k
default:+ w3 p4 l9 {' ? B& n! f4 O; C5 P
break;5 a: z/ E* s9 {. t, g
}; }% @ M' g; S* I3 x0 v9 {. x- E+ D
return 0; 9 C, a5 P' |) I! a# B
}* N5 I9 m8 s5 [+ O
, e3 \* O. \& G! o3 m& o
int isOpr(char c)' i8 F! [$ v. ~5 ^0 H
{: z' j1 g9 b4 Z: @5 P
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')2 L5 E! l2 j2 B
return 0;
) L( y% S! S. Y; A4 _+ l else
2 j7 j& T0 m2 q return 1;
" [8 k) h5 W0 |3 {. w' L}
0 u1 [4 Y$ A, E/ r! a! m2 I# M0 ^' C6 N
float operate(float x, char opr, float y)
! s% h9 p7 R1 g. c( ?{, x* j0 V# L7 r( n
float result;
9 ]& ]/ k M, ~. w$ u5 g switch (opr)( o: f; \8 H' _
{
- S! ~3 R3 c; g [ case '+':
. ]. C) a8 L+ U( c4 X result = x + y;
7 i [ d% Y" c3 x9 Z. i break;( R U1 r/ o! m% C7 t) ?5 n
case '-':
/ |( i* I2 k2 r3 U& Y result = x - y;
! C; I6 c; m6 t. Z, H( |) }6 f break;* W+ \8 Q4 W5 n
case '*': ! q" k* W. ?# p$ N4 U
result = x * y;
; p1 p; u5 W( M- j f break; u* o: k- \* I
case '/':
# w7 L% V2 Y- Z; x7 y5 U if (y == 0)& U) k3 n! O: n' x* k) q
{
j0 X7 p8 D; {4 t printf("Divided by zero!\n");
! K5 m, z1 P8 u T/ ?5 h return 0;0 m/ K" @3 g5 Z( Q$ f) V
}; I! H' |' f5 y+ }+ W
else7 h$ ~/ e: V, @0 Q' | I
{/ J W, E: l/ Q$ F. C0 Q$ n
result = x / y;
# [3 n; `2 ^; {1 E0 [- S break;3 q; T+ H7 P% ^- {# s% l* N
}
& c! M F: g; `' J8 n default:
' T" F) x5 h9 C1 v printf("Bad Input.\n");
5 _ l" E$ M$ p! p& ? return 0;7 ^, y! }8 V* |# ^2 ]9 G8 K
}+ c+ X2 W/ P( Q! z' y) M
return result;5 ?! j% P3 ]; d9 l6 w0 H
}
" K4 t2 X% \0 J% \5 G
) o+ {% \# h8 y; V7 zfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/) [% K3 j; f: [
{( a; Q* L7 @% C' L# a; k- U& b7 g
Stack optr,opnd;0 n( |+ D1 x* O) e2 X) J3 |# ~
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
# l1 q ]" D0 E) Z, i char c;8 x0 J0 d% ?+ ?! R% E/ D7 K' g
char buf[16];
, q" t$ e2 X8 M int i=0;
' t ~2 w/ C8 J, S+ ^ n & Z S4 i, N/ Y8 Q1 T! V) F
InitStack(optr); /*用于寄存运算符*/
3 L4 n6 d* U0 W v7 J ?5 E InitStack(opnd); /*用于寄存操作数和计算结果*/
& Q9 V# N4 t8 {+ n/ E2 Y memset(buf,0,sizeof(buf));. W# E& S9 o5 O3 @, ^3 w. ]
. X- Y( ^# g' k U% g+ j6 {
printf("Enter your expression:");7 v. C- R7 s: E, Z- M
2 V* O8 U( ]0 |/ V. ^) o% K% R6 B
opr_in.ch='#';/ x7 V$ |! ?) `2 m! ^$ K e
Push(optr,opr_in); /*'#'入栈*/
: U6 G+ ~& D' n# K! O GetTop(optr,opr_top);
7 G! }# K2 }8 f g c=getchar();' a4 u: y9 F( k! Y7 N
while(c!='='||opr_top.ch!='#')& P5 M5 f3 V; _! _5 f" ]
{
) i5 ~: ?( K ~ d' V* U! `1 G- p if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
$ l" y& n0 y- n) x, `! A { H- V! N# U' {. Z, G
buf=c;
; S1 T; q4 a1 ?% U i++;
]6 z* k e) Z4 Z, P c=getchar();% X4 _8 V# v" B" Q
}
' J" r( g1 C7 d& f else /*是运算符*/1 s. d L; f+ J( m3 u" [2 c2 v
{4 R2 z9 `% W" \6 v' Y5 }1 t2 D
buf='\0';
: t4 E& ~ V0 ]% s if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
3 z/ Q+ o9 W0 [* U6 B! ]9 _ {
* E4 t! W7 Y) V( ]' b S ] opn_in.data=(float)atof(buf);! v% _+ [" z; r4 b! k
Push(opnd,opn_in);
6 f6 s; B) R" {9 `9 E6 |7 Z printf("opnd入栈:[%f]\n",opn_in.data);6 ~ t$ q5 ? i- J& Z; y3 O1 \
i=0;8 U- H% ~1 C; o4 c( }! `; r
memset(buf,0,sizeof(buf));0 T% y) _; _8 _9 g: G
}2 v5 q' e$ y* R) _! N( r9 m
opr_in.ch=c;
& V/ ]% h. W. T8 v9 A- H& P switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/" I. M0 `. K* M6 t2 f: f; H
{3 a! B. S4 }9 y! w9 \, V" A
case '<': /*优先级小于栈顶结点,则运算符入栈*/$ B1 P1 Z. A$ a. O% n9 d0 X; h1 M
Push(optr,opr_in);. X: \+ ~* t9 e8 j2 z* a9 ^# t
printf("optr入栈:[%c]\n",opr_in.ch);
. ` S4 s" }5 v" i5 Q- F% t c=getchar();$ Q) e; U M' @% R
break;3 V) X8 \! k- x, A$ D% c
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
# Q' F; {5 F' M Pop(optr,e);- n1 O; w, A+ \6 Y) m3 u0 m2 M4 J
printf("optr出栈:去掉括号\n");
6 c# H4 Q% S5 U c=getchar();
0 `% R3 K. P% t% k break;
/ }9 h1 y. j2 u0 P2 q, E' c case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
8 ]) H# k2 N1 O' |( g Pop(optr,opr_t);
" @% b2 L, F- t/ V printf("optr出栈:[%c]\n",opr_t.ch);
( M' ~8 T# B8 }" {4 C B if(Pop(opnd,b)<0)' v* y0 C# q/ r* Y8 X9 v
{0 R$ T6 m0 X$ o& ^' ^% e2 f
printf("Bad Input!\n");' R, Z6 J2 Q5 d* V4 a
fflush(stdin);5 |4 d5 M& b- P6 Q% I
return -1;1 J) F: z. {( I# f3 `
}
! `, @: ^) Z; e) C printf("opnd出栈:[%f]\n",b.data);
1 R( `5 c& P0 ^ if(Pop(opnd,a)<0)
. M0 V o% l2 r* n' I/ A! ~ {
/ H7 D$ p; e( \7 r' r C printf("Bad Input!\n");& p) Y% K/ Z, N
fflush(stdin);
- ?( ^* U- s0 ~5 z return -1;
. o( u4 b' z0 Q( t' I# H& J* m }
0 w1 N g6 u/ Y; l; z printf("opnd出栈:[%f]\n",a.data);- s6 B$ e& @! c# C @/ J
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
: t9 u; q6 b2 `, ~, _8 s* c Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/* Y5 C$ p x+ M
printf("结果入栈:[%f]\n",opn_tmp.data);
2 N: i, {6 ^/ H- I+ }. O break;% C: Y) K' h2 N7 h
}
" |5 l I& O8 r }7 p0 _( Y6 N2 ]" k+ x
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
7 x( R9 Y2 H5 L7 v } V/ C( e' |% j, K* A5 c
GetTop(opnd,opn_tmp);
* m7 I" O* }: S/ e$ N DestroyStack(optr);( ^- f5 v3 ]( T( [# [) {$ }
DestroyStack(opnd);
3 ?) O+ d0 ^6 F- _$ L Z1 M% O return opn_tmp.data;- N) |* F/ s- v7 a6 n/ D1 M( s4 N
}
) D9 O3 a9 q: u8 K7 o4 Y' }7 k" _; o4 Z, X4 ?$ C
char *killzero(char *res,float result)
+ ]" p3 o8 _+ h{
8 P/ q9 r+ z/ V6 k9 a- l int i;
7 @' ^1 q: w/ [; F
* S6 J1 a; ?! W' ~* g7 M2 T sprintf(res,"%f",result);
- C9 X- L. I7 ? i=(int)strlen(res)-1;
! [7 k8 P8 E: l$ ^5 T& c while(i&&res=='0')6 l8 q1 s: a. f" ]' Y. B
{! B+ E6 \4 S0 e# D" G9 C
res='\0'; f. B5 W4 D8 K6 f- n
i--;# J0 J* ~5 b1 a: L2 Q0 v
}
2 x) E. f8 i# n2 E% H% L7 y9 t3 y if(res=='.')$ T! b5 B! F7 G5 V, p
res='\0'; Z+ R; o/ v5 Q
return res;! J1 f# p1 q( F% D7 C6 v0 ]! C
} @& ^) M( A0 o+ ]6 ~
% W6 u2 ?3 J0 P7 s* Yint main()1 M( h5 n: C( k+ ?# p7 r+ E
{
* C; G$ A. o; ^2 M' C) \7 F char ch;
9 Y! A$ H) O/ c1 H" c# m char res[64];% M6 J4 x% k c/ U# [
float result;4 m& L4 L, s! K4 k; l$ I* I
while(1)
* g+ k! ?. D4 n {& \8 ^0 f% G( a3 H& ^
result=compute();1 Y2 j" S. \3 s2 M3 F* k0 l- Z
printf("\nThe result is:%s\n",killzero(res,result));
. P' e9 f, K- f2 @ printf("Do you want to continue(y/n)?:") ;, G8 }. b* Y% a
ch=getch();
/ ^/ o/ Z/ _" T. R; d putchar(ch);
. ^5 k1 @( d# L Z R if(ch=='n'||ch=='N')
4 } h' i4 ` C$ n. b+ @, a break;( B) Q6 B1 L, _) i$ X; }
else8 d- _. z2 q/ h" R+ T1 `
system("cls");
8 h' m& t' I l7 S }: u1 L1 t7 O+ E8 m+ j5 x
return 0;5 o& y& I, d ~. M8 E6 A% Z5 G; Q
}/ p- n3 _/ }* I
6 Y5 Z, Y6 a: C& F
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|