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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
2 m$ B. u) b" x( E6 N程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
7 E7 `) j, L& N6 ^7 o! i `% _/**************表达式计算器************/
2 ?9 ]' O; s) A! Q4 l& f! f#include <stdio.h> k& b6 i3 Y) } f( Z
#include <stdlib.h>! G# o5 N! t1 u$ S, ~
#include <string.h>
/ T! ^% w/ o* T U. B: [; [ y/ r#include <conio.h>
' u/ w# h2 E1 p8 y+ w7 ^#include <malloc.h>
2 g/ o" T4 U' r7 e5 ]
$ [0 ^ ^+ g/ r) Y! C( y3 i#define STACK_SIZE 1002 c; H* d( q" p' G/ G1 Q
#define APPEND_SIZE 10
$ [7 p# t% O- o- q- p* j% i* v% B& [' f: a- m
struct SNode{
8 L3 m4 r6 R5 |# C; n float data; /*存放操作数或者计算结果*/
' w1 Y) T, u; y5 f5 [( p( d char ch; /*存放运算符*/6 C+ [- k0 d% T! W
};
: B2 E. T5 K, Y6 |& G3 r; V/ p- `2 p. D# O0 I. S" ?( U
struct Stack{: |: p/ @$ f+ V8 f6 T" P/ R4 e6 k
SNode *top;
1 X! w% h, u, q% b SNode *base;
. a1 u/ k2 ]- [; ^ I! x3 F/ W int size;
2 Q5 Y: b$ ^4 q7 x I( \' @& p};
* t7 i% F" C% b1 I0 O b
8 e/ d$ V& h, B/*栈操作函数*/
/ V9 n; I* w! V* U* R0 y/ r" Nint InitStack(Stack &S); /*创建栈*/
* o( x! t$ R4 p( l. [2 gint DestroyStack(Stack &S); /*销毁栈*/
6 J% T; [$ O& ^9 R; k+ Eint ClearStack(Stack &S); /*清空栈*/+ C! G. { o: `# q8 Q. w6 l F. a
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
9 b# U" P* u% d+ G: Gint Push(Stack &S,SNode e); /*将结点e压入栈*/2 P! i7 q( K) h# q; R( F
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/, u. y- o3 V8 O2 s4 r1 i
8 ~/ ?$ [. Y6 |5 i7 f4 }6 O/*表达式计算器相关函数*/
6 L) w2 L, Z3 z! i* \char get_precede(char s,char c); /*判断运算符s和c的优先级*/
& @" I8 i2 v7 ~/ Lint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/! Z, l. @" P7 R- A( f
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/# q+ @0 {; q* I
float compute(); /*表达式结算器主函数*/
+ x& d- A' T9 Z% t4 t7 V' g2 pchar *killzero(float result); /*去掉结果后面的0*/
4 A" R) p- E5 G* F+ D) ?9 d4 ~
' g: j/ I8 p3 I, j/ P% c5 Rint InitStack(Stack &S)
& U/ L3 x# j2 [/ r) t$ Q{0 R1 t \3 B- u
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));& |- b C' K- m6 l6 @, X0 m
if(S.base==NULL)
; O) ^7 {& v" o {
: i( c4 H9 Z" t1 h2 { o printf("动态分配内存失败!");
9 X+ Z) D* P$ I return -1;6 V. k# [3 |- A
}
0 V0 H& m' D6 M y; A S.top=S.base;
4 z. U9 C2 q* s S.size=STACK_SIZE;2 w" p% z, M2 ~; ^) n( C
return 0;
: g, ]. ?0 l# X: |}0 [7 G0 l: y( W: _2 Y( x! S
% Q# J2 h6 I. w0 B1 vint DestroyStack(Stack &S)0 b7 [! Z/ ?8 c* a
{/ v* X" b! j' V8 S; |; _) H) G
free(S.base);
- G( N+ C4 {7 D& w2 M return 0;& d4 g0 v* R# @5 [
}. Q) _! O( q, N& N
/ F+ b5 ]+ ~0 b; i4 V2 ~+ ~3 X7 v. A
int ClearStack(Stack &S), j, m& d# w, F; B* U9 {
{3 X. i3 \. l M! L, I( I; W
S.top=S.base;
: t! @. C: }2 [ return 0;' v5 \: d# S* J r' e; V5 ?' P+ D* g
}% W$ E# ~6 g# {2 J8 }1 C
. X3 @. T" W5 b/ A K# h' |int GetTop(Stack S,SNode &e)& L% H: ^8 s7 k, N% u+ \; T1 O: ~
{( B% G L7 V! h
if(S.top==S.base)" k* S2 V7 T* K' r4 x
{4 r T" x4 i! k" R. j2 ^* P
printf("栈以为空!"); D' ?+ H8 `' c0 m2 p- n# [2 b
return -1;, g) o- G$ k- m( L. J
}
8 y; `. F; F9 z" ]; a) Z e=*(S.top-1);
$ I, l( Y% M* }0 j return 0;
( G( z8 g8 i: l& @2 Q}) x: c! q9 S' ]
& j3 s2 u2 l. a/ ?0 X) W4 m) l3 x& tint Push(Stack &S,SNode e)
2 J7 P( f& C6 u% p5 R{
7 B0 |: t$ p I8 I, r if(S.top-S.base>=S.size)
' l! v$ n- a+ P) `4 b {
w! t) [, X$ t% C; U4 \ S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));8 V2 p0 z& ^! ^& W! h
if(S.base==NULL)
" ?! J% b) @3 v' Z; u, f {: g3 m/ } i) V; z' _" `2 Q
printf("动态分配内存失败!");
) Q, c* e; _4 f# L" Z* c; s: A return -1;7 C% M4 c, F; }$ F+ T9 [* a
}
' d9 V/ n( G. z3 i1 `8 F S.top=S.base+S.size;
1 _9 l# I) m& ~4 ?0 s0 ` S.size+=APPEND_SIZE;
/ K6 P$ W( @4 f; i% Q }5 x- s3 ?9 z% b; l* g2 o8 @
*S.top=e;
+ B0 ?( n0 ~, H6 U+ r5 Z S.top++;+ x: G$ t: n4 F7 b% K; e. I2 J9 s
return 0;2 f& e0 j, s7 S/ w& X& B' z8 i
}
% A! n4 J2 `7 V: B1 E1 J* J# T& E2 r8 o3 W& v/ L8 u- c3 R0 s
int Pop(Stack &S,SNode &e)7 h: v2 c6 E6 w" S
{
/ I0 q h: D1 V8 O- b% Y+ j if(S.top==S.base)2 j! g1 p5 r/ W: F5 s" j7 G
{
* G- Y& q+ W! r) W: N) r+ Z printf("栈为空!");
& Y/ h/ H" _, p; y& N4 `& D7 f return -1;
" a0 c6 K8 ]* c- L" U( g/ x }
$ X: L& E$ O; A/ N6 y) @1 P5 Y' \ e=*(S.top-1);
+ E2 h, E3 H3 I, L! ^+ c/ @9 J S.top--;9 j$ l* L+ S) D6 K# m
return 0;- L# z( k: h* N9 r; H
}
/ C( F/ c" Q! O' S" c! s
, X( }$ q9 r E0 J" i. w- H. Vchar get_precede(char s,char c)$ a& H ^: U+ r' b4 ]) P# ~% t
{! ~1 t( U) x0 I6 _
switch(s)$ n( I) |! k0 [+ }/ ?
{+ F3 T" ~& Y. ~8 e" z0 l
case '+':
- ?& {+ T' P, q# K case '-':* w; y) ?- f/ R; ^3 Y7 @$ @
if(c=='+'||c=='-')
. z2 @( a# m! l3 d return '>';4 e! u2 @/ I/ Q* c" w
else if(c=='*'||c=='/')' J5 a3 a9 e. S* N% R* T+ N6 h0 c
return '<';
( N# j9 d# j Y. w else if(c=='(')
9 W" E7 z, F9 C return '<';
( j8 j2 v# l( s- a }2 ?; w else if(c==')')' M8 n' g, O( b8 B; d+ Z7 X0 q
return '>';
`% s- {/ o: B: m% i else 6 L# i1 ?1 m* o0 `1 M U0 n) l3 f
return '>';
# ^- |2 O) V' w; l6 T case '*': }" o$ y, Z- u. }1 ]2 @+ S/ C
case '/':$ ?1 }' N S4 w5 ?% y/ m5 ~; C
if(c=='+'||c=='-')
8 [* j0 I0 M- B- }( d% w! j return '>';
2 o+ A+ Q# P7 k/ x* M4 A7 L* q else if(c=='*'||c=='/')4 p9 d* J7 h+ s; z& ]# I& H8 U, H) ~
return '>';. T5 b' v8 G: ^% u
else if(c=='(')
- h8 E# o! \7 p* \9 D+ [2 K, t return '<';
# ^3 ]/ K7 R/ f+ ^( K* M5 Z else if(c==')')( O6 b5 S% q2 c
return '>';
! _% I# j9 U/ v9 F4 [) x. V X else6 R: ^% B/ j$ a& e0 ~
return '>';
: l# j* v2 z4 M/ ^/ F case '(':
/ f. m' Q+ c, O* ]/ ^) C' h+ ] if(c=='+'||c=='-')# I" Y2 O( t# j* |
return '<';5 [) Y7 e* a, P* w8 a
else if(c=='*'||c=='/')
1 {" ^6 ]5 M) q return '<';
& e1 g! j% v& n: c else if(c=='(')+ t4 D$ [' a6 F/ D+ ~& c
return '<';
+ J* q; [2 h7 x5 O) q else if(c==')')/ g: Y" Q- `# Y/ y. j9 G# a9 a
return '=';) v5 S0 [, B6 R4 K
else
$ ^' B3 P+ i" T! ?9 V; T return 'E';
6 ?" v5 j- S( h1 _5 Q1 D- C9 R case ')':0 L* d$ _, X: v. n/ c
if(c=='+'||c=='-')" s" c/ u) W0 M/ F! K
return '>';
6 e6 w6 I8 z6 t9 `; Y else if(c=='*'||c=='/')
4 L3 c/ \, V( G0 Q return '>';+ z( A; G% o# u9 L6 s
else if(c=='(')
( A9 Q) I/ y' p$ i return 'E';1 B1 l% U/ p8 l' [. p o
else if(c==')')
1 p' V& C3 q5 g9 Y# s return '>';
8 _$ r+ H& N. _& I ^% H$ } else
9 N* w% d3 d4 Q7 e: | return '>';5 X$ r, S. u& @6 S
case '#':0 x+ w. W8 a1 p8 D& a7 Z6 |, d2 q
if(c=='+'||c=='-')7 M+ `; {" ?) W5 j( E( o+ S
return '<';
|) q2 d2 ^+ ?3 m3 v9 d# f F else if(c=='*'||c=='/')
* Z; C( N1 t N/ a# ^& V return '<';1 A! N0 z/ S! x# j5 e0 Z3 t0 w+ U
else if(c=='(')$ U, E; ]1 d. D" j; _
return '<';
9 u8 O" Z+ E( ~8 b! R else if(c==')')3 T2 ~2 M7 ~8 p: A
return 'E';" P. e7 `8 ?) y9 s7 N( [
else' ?8 L/ s( F9 g% x3 {$ Y
return '=';
# B$ R. v$ _' }/ M default:
$ h, b" l7 V4 H$ p9 V: z1 M8 @ break;
2 M' c; N: K; F }' K3 W4 a! w( b
return 0; & H0 p3 M0 ~4 q7 R2 }. Z6 c
}
C9 ?/ \- I; O7 T0 i8 n+ a) A
1 k6 P$ B! B7 Z3 P! mint isOpr(char c)0 R d7 m* m& m6 A% T7 G- L
{; o1 u D# F S
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
- u' e& y1 a) [# I4 j2 h return 0;
/ G& I& Z/ V2 E6 E9 H8 b c' j& J else
5 A: d* ~5 e3 e6 A, [9 s" l return 1; d& G; }, M6 D, X; `
}
1 p& f/ ?; `. |& M; y( a! ?. K& k
" I6 D% b/ Q- U5 N$ ^float operate(float x, char opr, float y)
* N1 s3 M; g, B{
5 S8 o- t4 ~3 x float result;$ B& A9 m ~8 h# m
switch (opr)
8 \4 J3 f) O" j* `6 w" G {9 j f& y! T; W0 j% |, D, I
case '+':
: `8 C& O* {+ o, \ result = x + y;5 d6 p& \, ~+ a8 ]
break;
1 q/ F: e" ]4 }2 Q; x G case '-':
1 I- e [6 @$ r$ U! A result = x - y;
1 `: ^) }! l# ` break;
! n6 o+ D1 a. m' W* u case '*':
* q3 V! X* @- j+ C \; G result = x * y;
# K; d/ G& u' e) C# H break;
- ~7 O y; |8 y( U+ ` case '/':
* j" R" h6 m% k7 ^' }& G if (y == 0)* M! Z. Y9 y/ X4 {1 b
{) q; X7 }; ?% L% F* H/ k' Z
printf("Divided by zero!\n");
) c6 ^9 H% B+ ~, o( k9 z' z I return 0;- l% n- x& A* P' r
}
7 `) n4 y; c/ g' D) G0 h else. [$ w% ]' o% N8 q i8 |) Z6 o$ v
{
! _8 |% W1 f7 | result = x / y;
) @% ]2 _# h! [0 C' z break;8 l: V/ D8 j! _2 B/ p+ F9 L
}1 W7 i( T- D( [/ F5 j* W3 ~- U& M
default:
8 y4 g- h% G6 U$ O+ ]5 G( J printf("Bad Input.\n"); 8 x) u2 \3 E" W6 F: l% x" s7 q. @) g8 O
return 0;
5 ?0 ^ i9 ?& x: J$ {* Z }
5 w/ y( j* |4 {8 c return result;
5 f& R: K+ I# C- H8 G} ( o. o: z d' m
8 R5 c$ Q: B8 ]& X8 J# ?float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/% a, t4 Y, s& S% k$ A$ s- I
{( u9 r: T% v( j# [+ y- F3 p+ d
Stack optr,opnd; N) O! Z- T6 p- Z3 D. v% G" S
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
* o; H; N8 T# H3 ` char c;
# v. B f/ I. _0 |! ~2 s8 V char buf[16];
$ M& ^( ~( |6 p% H/ ? int i=0;3 m0 M) ] ]8 Z' a: v
. i% I& v6 H+ ~ InitStack(optr); /*用于寄存运算符*/
: A" c/ \( m q! m |, T& w4 } InitStack(opnd); /*用于寄存操作数和计算结果*/% w8 d" k; S' x2 @/ q) w
memset(buf,0,sizeof(buf));
) a6 Z; ]1 F! q4 ^
! J- Y6 B5 O$ h3 ]6 h printf("Enter your expression:");# \; \( D7 _+ i, N6 J7 W/ ?
0 B [ e/ q3 q opr_in.ch='#';
$ O+ A" f- @3 v& a$ t) n+ ~ Push(optr,opr_in); /*'#'入栈*/. v6 d% Q5 O2 V4 U6 m; s
GetTop(optr,opr_top);
6 w3 x/ U# U) {) b7 k8 ~ c=getchar();) A# O) X% o& |$ a2 P) \
while(c!='='||opr_top.ch!='#'). ]2 B6 U9 J: D2 z! z9 h
{1 T @! @; b+ ]6 L/ M! U; e/ L8 I+ a
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
8 T7 K7 m( h% b. ^ l7 {8 z {) P, _$ e6 s- j
buf=c;7 i& D' w+ p) Y$ q
i++;
4 L# _. X+ v% ~ c=getchar();4 l. q+ O1 E9 R! p) f
}
% \$ c. D% D& t: y else /*是运算符*/& _% ?, g2 A3 ~) t0 C
{
3 e T7 q: L3 O" B( Q. W, o, ]3 u1 b buf='\0';
0 }# T& z$ |. g$ [0 k5 J if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/2 d2 g2 X- x. z* K: }' x
{4 b6 F2 Z3 y( m5 _
opn_in.data=(float)atof(buf);0 d, D+ G) b( Q% y8 i
Push(opnd,opn_in);
- M; ? r x4 L( [, s printf("opnd入栈:[%f]\n",opn_in.data);
( m! H( r. g, G. q, _0 b) x2 J/ @ i=0;1 E; e- @% V5 B1 b2 B$ d
memset(buf,0,sizeof(buf));+ f- [. M$ j4 ?
}. O% x2 P2 @/ e% L9 p
opr_in.ch=c;& c$ ?) D2 s7 |$ O
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
0 S4 o/ v Y( F# K# R/ g' i2 T* F {7 C& ]: o6 I( C! n4 w( r9 a
case '<': /*优先级小于栈顶结点,则运算符入栈*/2 H( O1 i# g4 d7 ^& _
Push(optr,opr_in);
) |! @: r3 K9 X0 i0 _1 q- F printf("optr入栈:[%c]\n",opr_in.ch);
; q# F3 e( a9 r/ A7 `" B c=getchar();
$ J: R) l+ C2 | break;$ l4 E/ O' A- C6 t. Y8 s) ^
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
; X; K D+ e9 F& u: a- L. |0 p1 ` Pop(optr,e);
3 _( i! D: v3 t$ ]! z printf("optr出栈:去掉括号\n");3 y7 B; H0 v# t5 I" [6 \$ f
c=getchar();
* }& h- g1 X* o8 b& ?3 p% A I0 | break;5 ~) F! m( s. W5 G
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
* r: s+ c8 t, M! S% B& d/ \ Pop(optr,opr_t);
O/ R: q4 d8 |5 r" }1 I) C- { { j printf("optr出栈:[%c]\n",opr_t.ch);
1 o7 B; N% N# J5 @5 @; d if(Pop(opnd,b)<0)
: V/ x' T9 g `& v& ~+ a {" G& ]; [( E- S, K* K& _ w
printf("Bad Input!\n");* ~0 Y1 o- m, i7 P4 ~, A9 S! X. [
fflush(stdin);
3 v2 ?4 ]8 {) j% W; q" W return -1;+ ?) f9 G5 f* W9 g5 W
}2 V% B# _3 M( b, i2 O$ O
printf("opnd出栈:[%f]\n",b.data);3 W6 u7 w: W+ E; i
if(Pop(opnd,a)<0). z, R" ^' j2 V
{
, ?4 b+ J8 W0 Z9 ? printf("Bad Input!\n");
, E0 z% |; Z( R1 n7 \- E3 _+ \$ \, G fflush(stdin);8 s* ^7 N2 f0 J; @& Y
return -1;
0 F s" f5 [0 L }5 l5 ~3 F' }2 G% U
printf("opnd出栈:[%f]\n",a.data);2 y: S8 N% E( p4 u' Y) F0 [
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/5 H4 ?2 J9 e6 a, ^$ ~ X1 t% R) n
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/1 C( v3 {* b7 @) H* I; t) O
printf("结果入栈:[%f]\n",opn_tmp.data);) `8 g8 u3 x% Q. X
break;
5 Q- P& b1 T7 o u! o }
7 \' R$ u/ m5 L; ^ }4 S( u$ q; u6 f8 _6 V# B
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
( L4 V! t& j, r! U0 X }
! h' ^1 E" p1 B3 J GetTop(opnd,opn_tmp);) m6 y7 w$ Q5 F" Y% D
DestroyStack(optr);
" a8 R. ?, e7 u% A DestroyStack(opnd);
7 K4 t/ `/ J' E; ~: o return opn_tmp.data;
9 ?* q5 Y4 c- }5 L4 E' O1 t M}
) u2 ]7 y; y6 |6 m% h5 h: E& D' q9 N0 W0 N
char *killzero(char *res,float result)
0 u0 ~& W5 w7 }) I{
' P7 g# N9 Y% \+ J* A5 d" G int i;5 Q; Q! u9 | S: s. k
* }5 i& ` z+ x1 [( r
sprintf(res,"%f",result);
2 ^8 _8 I) g/ G i=(int)strlen(res)-1;- j2 |2 y$ L. h: @- K* f& J
while(i&&res=='0')# P. D. q. |6 g! u9 Z
{
. v) V) B4 K( ^3 u* t8 c& d res='\0';
- M( p$ S, Z5 w i--;
6 K& ~& ~1 l( ]7 O1 f# A }
$ Q& s$ l n6 _( ^' P1 s% }! r6 \ if(res=='.')$ i+ n+ P9 e' E; a* N- a. C" y6 O
res='\0';8 r/ w' \ e B$ v4 n6 F. f1 g
return res;
& P. e+ O" E6 x! n* f3 B}
& G7 E3 j' k/ T! `' x
/ C; Y) ? u: j( `* k, b# [int main()' v* E @; E {# ]" z/ k8 n
{
% b7 J( j n! r+ _$ P7 e8 Z char ch;8 n6 l! X5 Y2 D! A
char res[64];
. S% x3 c+ K) L' x9 T, N float result;. ~7 {; ^* m0 _, a" s E% C
while(1)
/ l' n8 d( `2 A$ p {$ }8 t# r/ m, H2 h( G
result=compute();1 T" T+ R$ Z7 `/ D0 S6 a# d8 k
printf("\nThe result is:%s\n",killzero(res,result));
7 i2 U* r" k% ] printf("Do you want to continue(y/n)?:") ;7 h9 d( d& G+ n/ c, m
ch=getch();
9 o# x! L: F& l3 _' R( z; ^ putchar(ch);# q: ?5 S! X0 x! H9 H. y5 y
if(ch=='n'||ch=='N')
7 r+ H/ J9 N2 ~( t5 t break;
4 x) _7 v6 z' L7 ^+ g) u else. z+ U4 \& L$ d- s7 E/ e
system("cls");: _5 E- Z' f7 h0 V7 r7 S
}6 W3 j: j+ f+ L4 v
return 0;
+ W* E" w+ i) A' S" e+ A) A5 q}
. x' S/ D2 ?* G
8 x ~$ m g# J! \. ~8 E& c8 e[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|