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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
3 v! a0 [8 i" G( F) f( `程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
# D$ t* f3 ~ I$ I6 k6 I/**************表达式计算器************/% U5 B) f8 V1 V5 O5 Z L0 c
#include <stdio.h>
" V8 x3 v6 N: n0 D% c#include <stdlib.h>: L8 D3 O7 Y5 G7 u( x& U7 y* l
#include <string.h>
+ u9 Q3 M' w9 w/ ^# |$ k#include <conio.h>
: ~& O. }3 j+ p2 J# C: h#include <malloc.h>
( u# {; P/ T* Y. n; ^/ f
# P1 }# H% B, e+ g) t: s& h; }#define STACK_SIZE 100
( k7 J% Z1 \, ^5 B/ B* n0 Q% \; u#define APPEND_SIZE 10
, G5 q4 c' ?% i4 {* T( t r2 L
% f. F' f7 L6 J5 `4 S. R4 {# @struct SNode{
, J2 G/ W- X4 o& s float data; /*存放操作数或者计算结果*/9 F# Z' a5 E4 C4 l. S- m
char ch; /*存放运算符*/
# A0 p$ e6 @, e. H3 l& u};
' N- \0 }2 D0 A# l# c4 m0 o T$ ~8 n7 J- N: X
struct Stack{' n) G u- I s5 R+ I3 p
SNode *top;' C. P2 v8 D& y% z$ u. \" v, x
SNode *base;
. O% c2 l, t" u& i) H4 R int size;
+ o) e' P/ @8 ]6 L% m4 q( ?};% K) p4 l7 A7 v( W/ n" O( ~
" y, ~4 Q) F' \7 Y3 |4 k9 j
/*栈操作函数*/
3 Y2 Y4 \' m# {/ b T+ z Iint InitStack(Stack &S); /*创建栈*/
6 X P3 K) ?6 Y9 @, Q4 qint DestroyStack(Stack &S); /*销毁栈*/
9 I) [9 Q: T! m* O/ P8 u1 |! O5 Tint ClearStack(Stack &S); /*清空栈*/
# y# t! h5 e6 P$ \0 k8 Bint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/( Y' j% Z" T! L& }6 b) d5 I/ @; I
int Push(Stack &S,SNode e); /*将结点e压入栈*/2 i* C9 F% k. y! J8 J3 Q) p
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
z9 a7 A+ ?% k: j! @3 h6 X5 Y8 I9 l0 q s1 z: ~
/*表达式计算器相关函数*/
! V2 ?8 c6 }$ ^( Z; [char get_precede(char s,char c); /*判断运算符s和c的优先级*/
' \" f' S3 B2 v. o6 \int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/( X" p, h, z7 C' Y& ~: ^$ N
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
& t5 |2 U& s" `4 pfloat compute(); /*表达式结算器主函数*/8 y% L8 m" G: J. Y) f0 j1 T- p k3 }
char *killzero(float result); /*去掉结果后面的0*/
5 B6 [7 S4 g$ d" \# r$ z, _! V$ ?. T3 |6 c# t% i" R- A
int InitStack(Stack &S)
$ Z! ]4 g, m& A- w" @ G; N- q{
- F. g& H; D/ _$ Z+ g6 | S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
3 j! `+ |! q1 a4 x5 u; F6 a' } if(S.base==NULL)
! b( t: k, `9 e/ M' M {
0 @% E2 T2 L: Q8 {: x5 F8 {7 p printf("动态分配内存失败!");
' x6 w3 S8 N6 b9 D# T" x2 M return -1;$ t1 J, J6 b J# Z; n
}
) ~' j: ?* l( \: h, e4 t S.top=S.base;8 Z3 Q6 F5 V0 w. x! \; [: y, z
S.size=STACK_SIZE;
4 ], @1 K% T: O0 m A return 0;! ~; e) R: i y
}: ]3 U2 x3 g& o
- K0 y' m" y1 ]; S+ r: _. r) e# gint DestroyStack(Stack &S)$ H6 x0 \% Z3 m5 Z0 s6 |
{
5 g2 V% s7 i8 L3 s: @ free(S.base);1 d: [' X+ O k u
return 0;
+ }8 o/ {2 _. @5 s" ?}5 H" R B% o; X3 b& i2 T8 q
/ k! K0 m: d9 `7 G* G" K
int ClearStack(Stack &S)5 W8 ?/ S3 }) @- _
{
; i% x" w) G2 l7 m S.top=S.base;; b; |; U1 i3 t: d: z
return 0;5 L- F$ J/ v Z# j( E& N! V. O
}8 ^5 ^4 ^. a0 Y* Y6 R
' }0 v: T. w8 Xint GetTop(Stack S,SNode &e)
, M) H" \7 a. u q2 j, v{
( q' p0 A, {, L2 ]' p& ~( t! n if(S.top==S.base)* K% P; ~6 _' z
{
* r7 C4 d' O2 W6 t- v( k; | printf("栈以为空!");
7 g/ w, D9 ^+ a! K/ N$ | return -1;, x& B3 T; S3 d6 z7 O# A
}, b: y% x) u4 b$ e% k
e=*(S.top-1);* E$ }! S( _; T8 o% B7 v; G" j1 ^
return 0;
: M! w9 f7 ^$ L2 ~6 Y}
! j k" |& Y+ c, I& E( b8 L8 b; y
int Push(Stack &S,SNode e)
) J$ B. }0 E5 o# S6 f# o{$ g& r4 {3 Z( k8 M+ N
if(S.top-S.base>=S.size)- h: n6 U1 H6 _ d
{4 W7 e' |) S; b- _5 B( {
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
& i) l' s/ H/ o* q" k if(S.base==NULL)
6 U( ]8 M0 f) C% s% l3 j& ~0 O$ n {8 i" d6 N. ~, t, _; t8 y7 a; G3 N
printf("动态分配内存失败!");; k: Y$ S2 I9 v5 m! D
return -1;
' [% E7 h5 o: V# L }
! x4 B3 z* U/ v1 u: u% a8 B S.top=S.base+S.size;
. k8 h% F4 D3 h S.size+=APPEND_SIZE; g3 B' R' F+ v% o5 k3 v% C
}
. I. L7 e8 y: \; |( Y/ ^( j+ w *S.top=e;
7 B" o0 P7 L! o5 ^' j J S.top++;
3 v7 o: V3 y' o- l3 b! L+ c7 h return 0;& R# a2 @. L- \2 S
}
9 ]# ]* O- a0 S
$ o9 e+ C+ ]" Eint Pop(Stack &S,SNode &e)
) ~( n3 C4 C4 R+ K) n1 k{
) u+ ^, \ ^# A: x# q3 J if(S.top==S.base)
% u$ e9 F" @4 {% m {
% g" \6 {+ e1 r- H$ w printf("栈为空!");
* ]6 o; o1 w1 A8 M6 b. d return -1;4 u: P( ~6 C' J% i5 }
}
/ R2 l. L$ N; C) n/ A5 t e=*(S.top-1);* D. E. l4 x5 j0 k$ h
S.top--;% M0 ^3 B3 O9 y9 W, \2 C4 S. }# y/ L
return 0;
% U" |& U1 ` ?( C% u0 }}! C0 Q# r; Y4 P+ a5 g2 t+ C# P
4 P& r% H3 }0 I# wchar get_precede(char s,char c)' y# T. R7 Z, m, X1 |8 ]
{' q- r0 B8 R( T: A( G9 j
switch(s)
/ A4 |# @2 e( _) ]+ ~- L$ w {
1 B0 \5 q# p/ R- g1 h& B case '+':
, W. K9 Q1 A% E7 ] case '-':+ O7 s1 k- ?- i# _0 Q/ C
if(c=='+'||c=='-')$ O5 r4 Q" H3 r1 c' r$ o7 W0 t- r
return '>';
[% N! Y- e: G+ X else if(c=='*'||c=='/')
7 ~+ z' [* f; [% C) X- h return '<';# b' |% M7 `( I
else if(c=='(')6 u9 ]- P' Y3 b3 R; T- U2 {8 r4 r
return '<';
& _+ E1 _0 Y& j# F1 t) J else if(c==')')* W2 C' o, r" K9 F7 q
return '>';: T# O9 n% _! |7 k* K3 D3 v
else 6 O* Z1 q! }% E! o9 t; \4 \
return '>';
e& r. ?" M/ ]' n6 c; y case '*':
, V$ V' ], Y7 B4 n case '/':
' G' f" p7 A$ n9 i5 S if(c=='+'||c=='-')
1 O( d) y* o; x7 ^ return '>';/ K5 s+ W. b' L! j
else if(c=='*'||c=='/')
* m) ]# {/ P3 [3 u- j9 M return '>';
2 ~4 H- e* D6 H9 O else if(c=='(')
4 a/ C* U5 { U2 y: ?' B return '<';4 Z- h& V3 P5 O- y: P
else if(c==')')
$ R% R, B |7 t2 F6 c) v4 ? return '>';
# D7 i+ N: H$ r |* `, n+ c6 ] else5 _7 W) g7 s' i* [8 Y+ Z# O
return '>';+ f. t$ f3 @: @6 ]
case '(':8 {; z& A4 O6 U, Y9 @
if(c=='+'||c=='-')2 ^4 X7 f1 o; P1 \1 T. P9 A
return '<';
2 P) m' {: \! y! }8 m" @ else if(c=='*'||c=='/')8 k7 K9 Y" B; P3 c4 D+ W# z
return '<';6 b. s; h' ~' P7 _3 U
else if(c=='(')
1 m8 T1 J! S$ @$ Y6 K8 A4 y return '<';
: _' ^' Q& W9 U3 m* w. X else if(c==')')# \4 W' I" a8 u. K3 h" d% {* [
return '=';
2 R' z3 K8 k) V6 c# n% Z; o8 J3 E else) d/ Z) s7 Z) T
return 'E';
5 _" n3 a( b# e+ g case ')':2 t, e1 g6 b0 | \, C
if(c=='+'||c=='-')
# E1 X5 a8 f) V' b* ?2 P4 E/ l return '>';
, m' w; t3 p2 {$ l& l. G9 I else if(c=='*'||c=='/')
) E! `$ K" ]! i9 J return '>';& M# a) F* C) I0 \
else if(c=='(')* ?+ T- i: U# ~1 [4 h
return 'E';
+ N; A3 n# b, i+ } else if(c==')')" j$ E( }, P2 k+ |3 D
return '>';/ k& }, ~6 v6 v" R1 i( f/ _
else
p. F6 W8 C, g# ~( `# ^ return '>';
7 N# D' S, |' ^& b c case '#':
" m& a4 m( S5 p+ R if(c=='+'||c=='-')* d6 D# ^+ n; O( i7 t' v% U9 ?
return '<';. j8 ?8 L5 G/ N7 j' R! z7 f
else if(c=='*'||c=='/')
6 E2 T A/ O0 c return '<';0 q) \, ~ g/ M- k4 v1 C% g
else if(c=='(')
$ A' X& Y7 u8 L( x' C8 J+ x return '<';
9 i( l; {" k; w else if(c==')')% P; n. e+ _/ \1 h
return 'E';9 Y' D- o6 Q8 Z; Q+ L) ]$ L
else! _* v5 L, d1 I
return '=';
8 r* S# L1 q! P: j. p4 ` default:
S1 ]/ b' [! j7 `. y break;+ t, x7 c2 ~0 r( E% U8 L
}) q% f' |- C+ P! \3 x' |+ g
return 0; 9 R T4 r1 E/ Z3 r( j" G; {
}
4 f3 c. Q( I& H) Y$ I2 C+ H' @3 o6 u5 F" \, J3 g+ d. R
int isOpr(char c)
2 R9 e( P; \* X& {{ z8 b9 y4 ]# U) d* y- @) w
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
1 {4 \$ h* J' Z$ Q* @! c$ G& e return 0;* k5 ]3 i% @2 U4 [6 ]& X
else + x+ C( U) V, X' s9 z
return 1;
+ q" U- [$ p" Q% k6 J w}) h2 A* j* S1 X8 j- Y
1 b, y' e8 k" G: a% I, e
float operate(float x, char opr, float y)4 W2 x% D3 F+ k- H5 r% W9 ^
{
8 B6 C) d x: D& n. R1 ? float result;. [) u2 ?' y# D. S8 |5 I1 l
switch (opr)
6 D4 W0 h3 w8 e {4 ~3 }" v: A$ X% M
case '+':
4 h( _0 i% @ H# b9 Z' d5 [! m result = x + y;
' f" B0 S3 y& y, G! K0 X9 w break;
- p8 a" m/ K3 c8 k* ?8 e case '-': & C8 c" z8 X: r z0 o* ?3 K9 {
result = x - y;: y6 W2 a' q8 ]: g
break;- `2 q, C; K* N- P; w3 o
case '*': 7 e5 x8 Q& B* h5 a: j. _3 Y+ R
result = x * y;" w' V2 G" g2 Q, h7 t9 D% R
break;! C# B8 v$ u4 I% _
case '/':
7 J" n4 H0 c9 g( H- `2 k2 q if (y == 0)
5 d' G4 }0 q: p2 O# p {8 c$ |7 `2 y+ O9 t; ?! X
printf("Divided by zero!\n");
4 Q' h1 K; K$ i return 0;
2 ^5 C4 @& a$ ~, C }
* S- H; h2 l; z+ U else
7 P! K# @' }4 m {% |$ {% ^7 N( p4 V+ p$ |
result = x / y;& e- P& j/ }$ W2 H2 Y
break;3 F9 W j3 T7 C) q) x
}
: s# a8 J+ M5 v: j& ]" E default: $ L& C0 y! T! X9 Q) J3 n R
printf("Bad Input.\n");
; m* h6 x# N% }' L6 U: B7 u8 N return 0;/ G1 q. u7 p1 u& ~! n
}
# B0 N% ?4 w7 N' B: N return result;9 f! M: l# N L; l7 O' R h
} 7 M ~0 O) m) r, P+ L
m- x! b/ g1 v; I& `float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
: E5 S' @3 U& Q{
% K) l2 E) @, T0 J/ T5 a Stack optr,opnd;
+ ]( @0 j+ }9 A! i" g. t5 \ struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
5 t0 M! M0 N9 W4 }! y6 {/ F* r% C char c;* C1 u# t3 `; W: ^! O# ^$ b
char buf[16];
# `; @. G J6 A6 u# e int i=0;
; f8 t# C& v, W; @# D8 n 1 k) |- m! V ~# q, Y% y( K
InitStack(optr); /*用于寄存运算符*/% g1 {& Z9 P7 t1 ?1 f3 [- |2 {1 d7 k
InitStack(opnd); /*用于寄存操作数和计算结果*/
; G; v) Y9 M: G" z. q5 C! b+ A7 u1 X memset(buf,0,sizeof(buf));
3 \5 ^; ]* F! {* L+ ]" ? - ?2 X) c/ i" K8 s8 U
printf("Enter your expression:");) k4 x* Y9 J$ F0 U
$ G+ a @7 m2 U* a o- h7 K8 n
opr_in.ch='#';
& i/ q5 ^# n8 P' D Push(optr,opr_in); /*'#'入栈*/, _4 a" P7 _0 W- H9 a0 M2 y
GetTop(optr,opr_top);
: |2 Q: d' r% }0 s c=getchar();. i/ V+ l3 t" y r4 p9 h
while(c!='='||opr_top.ch!='#')
A$ s/ m/ R8 ~4 O/ j* C5 u+ h4 Y {
2 N/ x5 H+ B5 x( s5 {2 u+ {0 p: M4 V if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
( l/ K! S/ N; W$ _. ` {
# O9 [' T3 X; ]9 t buf=c;
& K5 w( j x$ ?# ~ i++;
* X! D! y! P8 _3 B c=getchar();4 n' p1 @; Z) u( @4 V
}* J8 c! |/ a$ q/ z
else /*是运算符*/
, ^3 K* q N& T/ b+ _" I' B9 a" V {: J: @' B, A& u$ t( d8 ?
buf='\0';
# Z% e i& |' Q( T9 x if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/$ s( U# k3 B1 z2 X# u
{
7 \ x5 t* K+ P# A; X0 x opn_in.data=(float)atof(buf);
! L% l" e2 V* n0 g* a Push(opnd,opn_in);% y$ o1 z; U" s, o: j
printf("opnd入栈:[%f]\n",opn_in.data);
5 w: e: y3 o3 V4 }6 B9 V2 M0 Q% v i=0;) T. ~% j- p2 C3 b" s
memset(buf,0,sizeof(buf));
6 T& g" I. a# Z. \0 Q4 N+ o! @$ m }6 l9 }: g" G8 g! H, T, @/ t
opr_in.ch=c;
1 I7 C+ X i i! l; p! R6 \. U: c switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/: }+ [ C S& L: k
{
3 G. |8 i6 W) v case '<': /*优先级小于栈顶结点,则运算符入栈*// h2 Q& G2 _0 G0 j" ?4 P5 c
Push(optr,opr_in);. w" T+ g! u, g6 H; s+ _/ J
printf("optr入栈:[%c]\n",opr_in.ch);
/ J. |" a5 U1 Z0 N c=getchar();
- ~7 U/ m/ G& O$ f break;! p4 X+ Q1 ~) [) p+ [$ T; {
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/7 m& G2 a, b2 W
Pop(optr,e);
/ f T4 e8 S- i$ q' } printf("optr出栈:去掉括号\n");& d7 p( \ m- [8 z# c
c=getchar();2 q' L4 m0 X/ ^1 H, _1 Y( K Q
break;
5 m; U3 x+ s: W* i+ A9 g! T! r& X case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
; i, q: b# z4 H$ @* g0 D Pop(optr,opr_t);5 w% B- c7 I4 X1 s2 T- l. J2 ]2 J3 |9 H
printf("optr出栈:[%c]\n",opr_t.ch);
# c8 n' ^8 `/ O" q0 S5 X if(Pop(opnd,b)<0)
. ?, p& T4 ^6 ?, S1 g0 L K s {: |! o& f$ E' P
printf("Bad Input!\n");- t- c+ h, C, p9 @
fflush(stdin);
6 Q$ D- [ \" N: ?$ \ return -1;3 C/ v" V8 b8 `) N3 d4 ~6 a+ J
} I q- ^3 ~6 n( a
printf("opnd出栈:[%f]\n",b.data);
8 n# w5 S, N) t3 |$ t if(Pop(opnd,a)<0)1 X5 G/ E& O$ P
{
; d! p3 P+ N) H printf("Bad Input!\n");/ J* m# r, F9 H. A7 J
fflush(stdin);
# I m8 j& j( f5 s# a return -1;$ j9 O$ N' X; k$ z6 E
}% R+ L$ x y6 K# Y
printf("opnd出栈:[%f]\n",a.data);
/ p, ?1 K; P- k% M3 y+ q opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/' n# [ `* T4 O0 D
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
/ \/ _. L# v6 s' e' m( f8 e( C printf("结果入栈:[%f]\n",opn_tmp.data);
T! J2 f% p& Z8 w3 [4 h) q break;7 O7 l2 Y6 Y5 q1 {; y1 t' A
}
: z$ k, R4 I& K- J* D }
( ?6 s+ ]( p3 g8 G+ {3 d9 q5 }: }+ a GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ # W; w2 G9 n; d& E0 s1 T0 D6 m* M
}
* [! d d$ v" j* @, \, F GetTop(opnd,opn_tmp);0 H; A" M8 [! y
DestroyStack(optr);
6 x+ \! w; m3 x' @ DestroyStack(opnd);
% }' G6 H8 h- d/ F return opn_tmp.data;
+ \8 i2 f! `. U& G2 ^( w5 l}; Z2 |1 X# u+ H$ n: ?/ r. ]
) r- W6 Z7 \* E o. c- T- {char *killzero(char *res,float result)7 R* z8 G' ]+ s# y: [; o
{
/ ]& u- G2 Q* ]! H' ]4 f0 m int i;
9 M8 W9 j' V# r$ {6 }
4 I3 ]& y/ \, _- Q/ a sprintf(res,"%f",result);" T4 @ I* @; I; L4 P- T
i=(int)strlen(res)-1;. a% N7 V& Y: Z- \. {7 X1 `- R; L
while(i&&res=='0')* [7 {2 b2 L2 u% s
{: g) q3 `9 Y" t2 [: Y* }0 z u
res='\0';
$ N6 c" R/ A/ ?1 h% \ i--;; `& u, o0 ^! I
}
% J1 s0 m; ]) r* ` if(res=='.')" A3 F$ x+ X1 m) @2 H4 C* A3 r5 l
res='\0';# O, M0 f2 X& n
return res;/ m, K) y, Y4 ]0 y; O) I
}" o6 i" Z4 g8 P3 F
( V4 K7 V( k, Y7 Dint main()
# B* [/ M* T0 u" x% F+ I{) \& D0 |- K; Y
char ch;& p1 k: a+ x9 E9 N8 T% G" a
char res[64];
8 w" J3 [& d! e4 }! A float result;6 }4 I: U, o. p: S$ i+ {
while(1)' [& [: |8 X" @7 x( D: t0 U
{
( Q$ h+ P1 e) F$ _; d3 P" t result=compute();
) ~# k6 r" @* U printf("\nThe result is:%s\n",killzero(res,result));' S' G% R7 q% S& }- [ F
printf("Do you want to continue(y/n)?:") ;2 j! B, r' ?9 L" P: Z
ch=getch();
1 ?# l$ f4 @# q4 l6 g9 ^8 ` putchar(ch);6 f& K: [ L. D, Z+ [+ Y2 h/ I
if(ch=='n'||ch=='N')
: B; P# V* d8 G/ X8 J) k break; a) @$ {: E: ]- l6 ~* e
else; Q- W6 n, ?, x+ q3 U: e2 o5 z
system("cls");
, d* k9 t0 @4 f% ^ }
$ a8 b1 E$ V1 p( f return 0;
# S! b% |1 ~% Y: H! R4 @- e7 Q}* Y* [- f" c$ K7 h/ f
; N( B( p- ^: X3 H: o3 p[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|