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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的., B: ~' }1 T" R8 h! I F7 G; p k! F7 x
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
, o6 b/ h% y& w/**************表达式计算器************/- l2 s7 Y& ], m; _$ S
#include <stdio.h>
, x6 [$ M% ^# X% b o) P#include <stdlib.h>
$ _ f7 J4 x5 j3 y2 S#include <string.h>
& Y/ a1 i7 i' ^/ o$ q; t' ?" u7 w#include <conio.h>( s6 ]5 C8 E) X; T5 _+ F
#include <malloc.h>
' G! g. R t% K7 h" V# A& g* l! N7 U* S: V
#define STACK_SIZE 100 H! \, X$ O& N% ?6 N
#define APPEND_SIZE 10
F" h |4 s O9 z
0 O' O' P1 w" m8 f" v* |struct SNode{
]) @6 R4 ^2 m- {7 e9 J$ l) ~ float data; /*存放操作数或者计算结果*/
2 }% {# \* R7 P7 @& ] char ch; /*存放运算符*/
- g$ v/ y# ^3 ~# ?};
- C- C' I0 v4 x) ~% }! g3 e) t0 ~% y$ l! m1 `
struct Stack{. ]# h" Z. M+ ?) i
SNode *top;
! K* m5 v, w: i+ _ SNode *base;! S2 @& _& {% h- S, K4 k3 c$ U
int size;
+ R7 J1 C7 c$ o- ]' P" H};% D: [- H2 j. C- m. a
|3 d. ?" R" z" v
/*栈操作函数*/
+ K) T) c' i3 T; p8 _" C2 J7 o* |4 m/ Zint InitStack(Stack &S); /*创建栈*/
: a9 q& r- E! X9 X. C) rint DestroyStack(Stack &S); /*销毁栈*/
2 O, t Y5 ~4 Z9 }5 xint ClearStack(Stack &S); /*清空栈*/
+ ]& ?5 p4 x6 @, r& jint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
( S. `- B1 F* m" z" ~$ \" eint Push(Stack &S,SNode e); /*将结点e压入栈*/: n- N9 T% U. ~+ c
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/" P, S$ W% r; l
8 x& {/ R8 A" P: E# M6 M
/*表达式计算器相关函数*/
+ s1 y U: x. uchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
% `3 l* z" B! Q6 X% u7 L/ ^int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/+ L$ k3 _, ~* b1 c
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
. c7 V0 j6 Z+ d# X! R0 e4 xfloat compute(); /*表达式结算器主函数*/' P) I& K% w: X" U- E. [. p% Z; [8 P! H
char *killzero(float result); /*去掉结果后面的0*/
* K/ M$ f# U& J+ n& {, R; O' d+ U. R; T
int InitStack(Stack &S)
: i5 U+ Z4 \$ y8 A }7 V, l{
! Q$ U, T& U; e* L. J S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));% O1 X5 L1 I, r8 v% s; J
if(S.base==NULL)
, R7 y0 t6 p5 x$ `* A {# y5 [# {1 F3 l9 {( J! C
printf("动态分配内存失败!");
% q7 Z" g( E# @8 g return -1;- `8 p5 n9 k: ~+ ]0 `. t% J
}: J" E9 W+ W9 l( o4 I
S.top=S.base;
% H z' x7 w. `+ E* { S.size=STACK_SIZE;4 h5 \5 ]$ a; O% o
return 0;
% S2 [: [7 S8 _5 @}
$ w) n" t+ o) \6 D8 S9 E
! e( x! J& d5 a& p( \! U: v3 sint DestroyStack(Stack &S)
5 W2 |' `8 ]! u1 ?3 i# }9 s1 B{, Q2 J# V* x% C& q9 `( G
free(S.base);
, Y) H& T' l; Q- g3 ]7 o return 0;9 h" N1 F+ |5 w
}
* ^2 [3 S# J; E4 A5 } t, A+ w' n! a% Z0 F/ b
int ClearStack(Stack &S)
8 Q- U' A/ J* y" v, _+ ~: x3 k{
5 e- D s' e/ f6 h& D3 w: l S.top=S.base;" V9 m1 d; W* r7 d, V$ C
return 0;
9 ^" q7 N* I8 }7 e1 ?6 J( c& `}" M; Q R1 K7 \9 Z6 r3 x! ?( v
4 W3 d4 `8 i6 U% X
int GetTop(Stack S,SNode &e)
5 ^7 Y. `- g6 Q{2 v) L8 i1 i& J$ A; Y& `# p
if(S.top==S.base)/ o/ |# `) D% q
{7 e' s9 ] _) Q3 q1 B
printf("栈以为空!");3 |& d% X( ]/ y% `
return -1;
3 Q+ z2 s1 d" {% t/ f }
* |/ I5 x. h4 }# h e=*(S.top-1);
5 U6 [& R$ j5 T9 T' \ return 0;7 W3 }* N" \; e8 B' _0 B) Q
}# I- b/ b$ B4 q$ Y& h& z1 n
9 U) R* m/ i! J) M4 ]3 G9 Z% ^. T
int Push(Stack &S,SNode e)( ^% \ h4 O+ Z' F
{: A. b' x# r- ?! `: x3 x
if(S.top-S.base>=S.size)+ A- r- \ P9 L7 s
{% T; i$ t* ?, n* q
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
9 R4 `& V0 Y2 h; X' I if(S.base==NULL)
# v7 ?7 q: k8 Y. x {
4 E! T R7 N5 N4 Q8 i; n! C5 h printf("动态分配内存失败!");
! ]- w0 j" {% C) H/ C return -1;
' D d" G6 t. f8 z# Q }
y! H h# v4 ?5 ` S.top=S.base+S.size;
! X$ E2 t/ T9 U/ j S.size+=APPEND_SIZE;2 Y( a: o, S9 ]) ]. _; J* O
}
; F7 d! u9 O/ E$ r1 O2 U' J *S.top=e;
C* t! N' w1 n' l2 v% R! O% e# s S.top++;
& y# W* N& C/ _8 G1 e return 0;
$ k1 Q6 K1 v; ~9 q& N8 I}+ c/ R1 r( I( d2 b
; P8 i4 g* U1 F% o
int Pop(Stack &S,SNode &e)
( l$ M9 t: P" T6 ?" ^* \6 z! _5 o{2 R0 @' @, _( Y& {* u6 m9 L6 ?
if(S.top==S.base) s- B9 m: n O9 `
{$ b6 i$ z8 V- c5 m
printf("栈为空!");
, z/ \$ a! \+ U4 m! s+ d return -1;1 a7 ~/ L* `6 C/ s0 c9 d/ y
}
( K- i0 Z z' c: R8 W4 w, B) y e=*(S.top-1);
/ ^& U4 `+ A4 u, e3 m. c S.top--;* T, t0 W2 f+ e2 d* s }+ r* L
return 0;
# L! G. H. S" u* N; R}
2 C P* j7 e: [( z9 l' t
$ ]# [5 U) X8 F+ pchar get_precede(char s,char c)5 |# t8 I; t7 H' ?% H* j. i5 q
{
/ C, ?) C4 V( h x5 d4 m5 C switch(s)5 i1 u9 b! u+ N, O# k
{( @1 i3 N/ c% p, ~$ g, z0 G3 ]
case '+':
, x4 d& J& I5 a4 T, Q case '-':
- t6 w& f. A0 Y' M if(c=='+'||c=='-')
# b5 B+ b# X% L/ P1 s8 q: X: y return '>';# r$ J4 b5 O& v9 P
else if(c=='*'||c=='/')
! p: g9 N- ^7 h5 W2 ~ return '<';
* _/ H! a$ F' \( J d+ v x else if(c=='(')
" W6 {1 R- U |1 b {. P return '<';
, ]" k8 u( C$ N7 L+ P else if(c==')')9 m5 m3 G, L7 Z. O5 L0 m2 ?
return '>';
0 ~/ C' L/ B$ r9 j3 q! K R6 `* r else
4 z4 h3 b$ A6 N return '>';
. d' x% p9 ^; h+ Q* x case '*':: E. J' q" _* p' o& S
case '/':/ I. q8 D, W& H4 P1 P E* R- |+ f
if(c=='+'||c=='-')' k7 B ?0 p; j4 B, g' F U# n
return '>';
& E3 h# i* a2 r* ^; W8 \, n else if(c=='*'||c=='/')
8 C3 F0 p8 c8 H9 [' E7 b+ b return '>';$ W& T2 D2 [6 ]4 ]6 c. L+ d# n
else if(c=='(')' Q: h& M k! N( P. [# D2 \
return '<';
1 |' M) J! g& q: Q( v3 L else if(c==')')/ o ? X7 j) Z0 C, F
return '>';
2 Q- U, D$ K7 B! ]# f" f& Z else2 u! w; e7 s, `* I, U$ N
return '>';5 N, S! s4 N% i6 t$ C' t
case '(':
5 r) N3 ?1 {+ {4 O3 C7 z2 M if(c=='+'||c=='-')$ P6 S7 l$ |6 z; f. w' z
return '<';/ J) v( f& ?& U# g: L# n
else if(c=='*'||c=='/')
1 |4 ?8 `2 ?% a return '<';
4 k) m+ _8 f7 y8 e else if(c=='(')
& M- d9 t! }7 q$ A, K return '<';* ?, W6 Z9 {3 C9 v0 f. f0 W1 d
else if(c==')')
* {) k6 A. u& j9 S3 t return '=';
& N0 q2 R& h0 f' s8 [ else
/ p3 k* x( F: V2 m7 u* @ return 'E';! |/ @$ K4 D( M- o# d$ u0 c% o
case ')':
5 K M- I; b+ b4 R' a& N if(c=='+'||c=='-'). @' a ]6 _* Z9 D
return '>';
0 Q2 a1 ^% }, ? else if(c=='*'||c=='/')5 ?6 y# E2 Z/ ^: N$ ~6 y# j7 {( A
return '>';
* q8 C7 R- g/ ?( J" e: n else if(c=='(')% z& E E6 s! ~5 Z( T
return 'E';
: I& o$ E+ Y7 S8 p# h8 S: F else if(c==')')3 v) ]& z: g% l
return '>';) d, O/ V& Y( n1 L. W- I0 m1 W
else
$ J, V$ Q9 x1 c* ~) N% ^, @7 n return '>';/ N, i- C& ]1 C
case '#':
2 @& a2 j$ w# @6 y# o if(c=='+'||c=='-')
+ I4 t) z+ P7 `' t return '<';6 Q& P. I# C8 C& J% i: M# N* D
else if(c=='*'||c=='/')# w% `7 p' T0 S
return '<';* _% r8 M' J5 k- L7 r6 W
else if(c=='(') U2 c9 Q& S- i
return '<';
) r0 I, \2 r. k, B# q else if(c==')')) Y( f" E7 w+ e
return 'E';7 h. S) {: H2 N0 F- _& j5 E6 n
else. i. Y/ z/ W4 h3 a+ L4 P
return '=';
) u% F5 Z! H+ j* O default:
4 g4 a+ C2 A/ G$ \7 c break;) R/ k) W( P$ U2 l# V9 }
}
1 z5 N! m4 E J! v5 j5 d' L3 L5 y return 0;
/ Q8 o6 C) H. y q; U3 {! C) m}
! I1 p& j# D* c; e- {! F3 n+ J: A3 ]* i- S m9 n5 G' p
int isOpr(char c); x' n K) R0 H
{5 _% E0 r2 S6 R1 l
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
1 N: }" y* ]; d7 {* _# W8 x& N return 0;
' ]# \* s6 f7 L9 P* D else
9 ]5 j' z- T8 G1 \. F return 1;
3 l) x M. |& K}
% ~7 R8 t% ~" |" H
. @+ ]( H P7 o0 V9 ofloat operate(float x, char opr, float y)
5 J/ Z% J' G) g& t0 `1 _{1 t# O) i+ i. B+ u7 k# T4 e
float result;
# l" H7 u/ D1 i/ H4 u& z9 J$ G2 h switch (opr)6 H% m; k" I. L
{
$ I2 B5 M4 B: ~% M. y( y case '+': 7 x( Z- w; H7 W' |& O+ W
result = x + y;$ _1 I+ H, A3 v) X5 ?( ?0 g
break;* ]% s9 @! h$ Y1 m3 \1 W" }3 m/ P
case '-':
0 T6 Y/ f$ T' H( d2 U8 \ result = x - y;
: S" L& G, u. n) g9 } break;) @4 S5 M. ?) Y% w$ H4 U
case '*': ( H/ @) F+ L* z* \7 L
result = x * y;$ C! c; p4 A+ P8 V. I
break;, j* ^/ V0 f/ G G- B5 O
case '/':
4 F+ X4 [4 [3 T" @1 S if (y == 0)
! v! W& h+ ^/ C {/ s3 Q/ h( n* m7 t
printf("Divided by zero!\n");
1 Q. j, T+ T0 |1 a5 Y, b return 0;% y7 a# t7 w/ g6 {% U w% }
}
! ]7 |5 r( i8 u$ p u5 K) z else
, o$ s1 ?. Z8 W6 o2 n. x. X4 ~9 V {
7 G. D+ i' F- [% s result = x / y;6 @5 r! B& T' `8 l1 ^# t1 b
break;0 y4 l" V, c. d/ u. s7 n
}( ^) }" A& I8 e$ _3 p& y
default: $ E* Q; \% i( {$ y* X
printf("Bad Input.\n");
) B' _$ _% q1 u: X" s return 0;
7 \. M7 b% `+ e2 x }
4 M* m& {. _: \8 l return result;
. b& V! L9 M- n3 s. P6 \; U4 y} ! P4 B6 \7 r& v/ l) {, J
1 L8 {: {& K9 G9 ^8 p: P* c5 e
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/4 p; W% z/ ]8 `! b
{
* T8 @2 E7 A6 b5 D& Q/ Q+ Y Stack optr,opnd;) t i7 f5 K0 N( d0 `+ _9 s K/ {" g
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
7 ]1 z+ u8 I4 R char c;
" F! Y4 |' \/ d4 ] char buf[16];
# H4 Q' V( F/ J, `& f2 T int i=0;
: s! R. N9 {6 g4 W9 T" l
* k2 W: ~. D% ]# N5 E! u5 _2 S InitStack(optr); /*用于寄存运算符*/7 h& h7 l+ e0 V k2 x; [
InitStack(opnd); /*用于寄存操作数和计算结果*/
" b, z2 S- X6 R7 ` memset(buf,0,sizeof(buf));
! S8 _& I) R5 P0 M! Y# v$ ]
- h" Y. a6 D/ k4 g8 u2 f. Q printf("Enter your expression:");' R. v* @: O6 v, n/ n* q+ H r
& S# j! ?$ i J2 B9 ^ opr_in.ch='#';
~7 j+ k" X# U8 ]/ E. L( d4 ^ Push(optr,opr_in); /*'#'入栈*/
" d) c m7 m O- _ GetTop(optr,opr_top);
6 z, k/ n( G3 V; W. C# Z c=getchar();
/ {% Y+ W8 J5 ~# x4 w while(c!='='||opr_top.ch!='#')% N1 q/ r& g" o' o- a- j
{- O& D3 @: g! Y$ E, ]; \% T
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
) D$ V( ]3 `, h4 a {
! I7 g v! B5 O" P buf=c;
! D+ h/ o4 J, y i++;7 P) X: y1 `$ v ]9 o' {
c=getchar();7 M# Y& S: ?2 Y
}
# X; q9 h4 ^% i$ S3 a( W else /*是运算符*/* O% \4 |, s: U$ i* W. q
{
, w* ~3 Q0 N+ d- Q3 Z buf='\0';
. }2 G5 N) J$ Y6 F Q, C- Q if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
# k, i+ S2 o* p, x {5 e6 h2 }3 e f C+ X0 P8 D
opn_in.data=(float)atof(buf);3 W6 W O6 k: u, j1 x% z8 R% N6 F
Push(opnd,opn_in);7 ~& {3 j: x C% T, l& `$ `# J
printf("opnd入栈:[%f]\n",opn_in.data);
) L& ]' {4 Z# E4 H3 z/ d# U i=0; g/ N2 ], U7 z! `! P( y$ H* {
memset(buf,0,sizeof(buf));& J5 Z1 V7 {1 p/ K$ @7 \
}
5 D7 D. w( b: n$ C+ U, t opr_in.ch=c;* c1 i1 u0 |$ h/ H8 a% x2 }& _' w
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/1 i% I5 p- ^# v& m b1 y5 v/ G; x
{! o3 \! n4 m/ _) q( f, w- D; z( [3 }' p6 W
case '<': /*优先级小于栈顶结点,则运算符入栈*/1 t* D6 s: S2 S1 P- h
Push(optr,opr_in);. M1 n. ~6 a5 b
printf("optr入栈:[%c]\n",opr_in.ch);
+ O* ?8 E8 C9 {, [" _ c=getchar();7 C0 S, D) Z- n3 x2 w
break;0 l7 q) e) t- E) p5 U6 j
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
1 D' O) `0 I1 @$ T3 y9 U Pop(optr,e);
# U/ S) _8 ` t. a printf("optr出栈:去掉括号\n");2 ~( R. J7 T" S- v! n7 k# P
c=getchar();
! t2 L- e6 |. ~& { x break;
/ \7 N7 P2 h+ u( c0 N case '>': /*优先级大于栈顶结点,取操作数和运算符计算*// S0 r. h+ f, ~ r+ p( l
Pop(optr,opr_t);
/ l& H) R/ q$ E k1 B; @ printf("optr出栈:[%c]\n",opr_t.ch);: P& @) W+ I# N( x9 G6 a- e' F$ l
if(Pop(opnd,b)<0)
$ F; Y6 F7 B) J+ L+ n {& Z6 u" E; w1 {6 c5 M' b( m
printf("Bad Input!\n");
0 Y/ ], \; {& k# r! [0 D# | fflush(stdin);
4 O( N7 t3 n ]) E5 D/ c5 J! t return -1;( G8 [4 f- p- \( f4 v! @
}+ E, `0 z& v' Y3 M# a
printf("opnd出栈:[%f]\n",b.data);4 S/ A! ?9 J0 M, y# X2 W4 r
if(Pop(opnd,a)<0)% M: I* b& j* i; g4 H$ O. j) I
{& V% R) _, C' ?- W ]4 v1 S7 P- u
printf("Bad Input!\n");
3 X0 K) I+ I6 `; c$ ~- p fflush(stdin);( B3 j: d& A! V
return -1;) [& a5 ^& ^* H# v* D
}9 s Y3 ~* z* f( z' N |" v x
printf("opnd出栈:[%f]\n",a.data);
" j+ C; A: P# b2 S( f ~- I/ m opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/8 K- j# X# \! E
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/. t5 d; x9 L3 u$ Y& g5 s
printf("结果入栈:[%f]\n",opn_tmp.data);- e7 ^) m" |+ o) m0 U
break;
3 _5 |0 n; @2 @& a+ O+ z$ C }
% M2 ]8 s1 S* x* F& O7 n% @ }
% d h5 M# I' @' u" C GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
- ~/ X# U+ R+ x& F s/ o7 }; @ }. Y( F& t. G- P ~
GetTop(opnd,opn_tmp);: K3 S. y K) A2 _4 M; V
DestroyStack(optr);
' X4 P1 p4 K8 e) _ DestroyStack(opnd);( |1 B$ e3 f& R( Y! i1 U
return opn_tmp.data;: z4 V8 w- h8 R( ^
}
4 [4 `1 z i6 j: {2 T* C1 J0 v" m0 j3 T
char *killzero(char *res,float result)$ x2 i4 i/ {# Q# a: [9 j
{
* K& X- n4 O# V. P+ ? int i;
+ r$ S# b* U4 ~6 T- ?% j
7 T9 H. j9 \7 |: y sprintf(res,"%f",result);
7 E! C P5 s3 Z' |" I i=(int)strlen(res)-1;: V) q( L5 [4 \2 ]* G
while(i&&res=='0')
. \+ }$ I1 X* A {' q: D, X9 I) `2 h7 h" w9 \
res='\0';
& N' m' Y Z2 q i--;1 y' i$ z- d& d
}
# T: c) V8 r/ g6 K7 J if(res=='.')! W2 _ N# G2 J" C4 D1 a7 h
res='\0';
' j* Z) p k. u& l8 i; j return res;9 \/ v7 r' D( [! ~" u
}
6 A, H2 e- m) O" g# t" U& F6 E% n6 s5 [, \
int main()
+ `$ c; F- k* w0 [ y7 o& K- c( [{' O* h6 h/ R6 M) L9 E# M
char ch;
( x1 @, w! K9 f8 O6 x5 X; \% G3 B char res[64];
* R' a8 X# G+ e# @ float result;+ s6 C! E2 p% `5 C
while(1)7 f8 v2 T- H: Q0 N
{$ p5 M" Q4 U3 _9 _# L0 _& j
result=compute();4 C+ O, S( W/ W
printf("\nThe result is:%s\n",killzero(res,result));
; C1 `1 y2 U- a+ ]$ D/ i printf("Do you want to continue(y/n)?:") ; y9 H$ G5 z1 `9 G- X
ch=getch();
2 k9 k3 x' Y3 w7 A putchar(ch);/ d8 v9 f2 @, }* f. J" B9 r% W" X
if(ch=='n'||ch=='N'); J. Y/ r* C! P" @4 X
break;' ~! h1 c/ L; N6 y
else
4 p1 I, W7 ~ G9 l$ l6 m system("cls");" N6 g7 F9 Q( b
}/ `/ j8 _" |( Y% u. {8 l
return 0;& }# N' p- r9 X% q# ]! ~8 j, r
}
0 J! l- s, Z' V% R* {* g/ W% m3 t4 l- h. B: q) H& B0 a. J
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|