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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.6 e6 [* A N2 Y u2 x
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
3 W, r- n3 @; Q/**************表达式计算器************/
1 d$ B0 {! [. p) J#include <stdio.h>* S) t/ ^+ z2 a9 c' }
#include <stdlib.h>
8 N9 c' Y- u6 J! M; t {( ]#include <string.h>
3 ~2 e7 j1 p) e& Q( J! S! G#include <conio.h>
# B$ F6 |$ h% S% Y! N#include <malloc.h>
. x' }9 |7 T+ \; s6 R/ ]4 y% D
' w8 l* _( Y# _: l5 h$ s S/ }#define STACK_SIZE 100/ z3 D( P. G: @- d- E) ^0 d
#define APPEND_SIZE 10) W J4 @' r+ p- R0 z
( c, y9 O' I$ j B% `7 Y
struct SNode{
6 c3 O( H: ~( P0 v4 s/ F float data; /*存放操作数或者计算结果*/! ~; r. o x ]' D9 w) n
char ch; /*存放运算符*/
$ A' n& y# {& i6 s7 l% W E};
# E$ F# K: H, L! z
, u! ]) g7 R* T4 V2 ?3 ^struct Stack{# z. K7 w+ F6 Y$ z1 s; u5 o- e- F
SNode *top;
; Q3 C1 g! T, i* ~ SNode *base;
$ ~7 |, c' N& m8 Z) _$ r% k int size;$ A$ Z7 X4 u7 X, Y( z
};
4 a" f+ x7 L3 O$ J9 Q# V( e, h+ M; p
/*栈操作函数*/
' q( x8 F( v$ [6 y" H6 Z- L) cint InitStack(Stack &S); /*创建栈*/
" L( o/ M1 l7 v6 lint DestroyStack(Stack &S); /*销毁栈*/
+ g6 [7 Q. a* u h; p6 L6 ~int ClearStack(Stack &S); /*清空栈*/' J. j" {3 e3 f \# U$ n
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/) h8 \$ A5 a8 \5 \' e
int Push(Stack &S,SNode e); /*将结点e压入栈*/, C8 s% h Z& @
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/' l8 A8 X! V( g6 u/ g$ h
) q" `, m+ m( g0 D! L' B" ]/*表达式计算器相关函数*/7 _$ Y, y8 x3 ?6 T
char get_precede(char s,char c); /*判断运算符s和c的优先级*/4 |3 [9 G4 X) |9 E0 I
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
5 w- N3 Y# L1 e9 P/ Y6 [6 zfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
- Y9 B# n3 T% v J0 Ufloat compute(); /*表达式结算器主函数*/3 S3 w* \* Z4 O4 Y" V
char *killzero(float result); /*去掉结果后面的0*/ ; Q! L# Y; M5 t( I& u
% o+ G% n; D7 E1 R. q" K
int InitStack(Stack &S)2 s6 V3 K! n4 @: j" p7 G( U) f
{
/ b P3 r" G) a3 g2 F S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
, n) b/ P- {$ G0 r2 V if(S.base==NULL)
3 A8 o! }6 s7 y% I {
. f1 D5 f0 }& I/ V! C* t printf("动态分配内存失败!");
r8 w2 L& d: F3 e6 f return -1;; n" d# w) i1 y
}/ ] M" C9 R: Z6 f. C1 S) X
S.top=S.base;( b; T+ [' D' ^: N4 F3 f- m" A5 M
S.size=STACK_SIZE;
1 b. {8 w; m( l# z7 s return 0;
. S7 H4 _# D; I d" n' x: k h% u}* {+ z; i- n+ W
, d# U2 y! a" tint DestroyStack(Stack &S)8 s" F$ k3 i$ Y1 k
{8 j3 Y' o& `" y6 \6 {
free(S.base);
- f) g) Y% L9 X return 0;2 M6 H# G! v: V: O8 l( ?# d; Q+ T
}
. w7 m; X6 L$ A2 A) t4 B7 g6 o; {8 o; @4 g3 F% B
int ClearStack(Stack &S), h* _* e0 \% m7 n
{
7 m Z# _ v* N, D' n' t S.top=S.base;
0 F8 n% L& e/ q$ K3 D+ L, v" @0 B) h return 0;
! C& F* j5 j/ d& u}
3 c2 N* a% x& y+ F! R! J0 D! z1 h
! g2 k7 z; K9 u- ?* e; fint GetTop(Stack S,SNode &e)
5 V1 _+ o' G# O2 s5 }! I8 _{
! U3 Q$ ~. y3 G if(S.top==S.base)4 @8 p- {6 o8 {4 V2 F1 c! x3 H
{
Y5 }6 c$ J6 u% f* h% l4 T printf("栈以为空!");
+ N( p: b4 F7 E+ F6 ` return -1;* D, N4 _ F+ `
}
3 l; q- Z8 L6 i e=*(S.top-1);
5 Z5 K! V, d. ]1 L: y6 x return 0;
( u9 S1 p+ R1 h7 R}
3 c' H6 o3 {( K8 g0 z2 p* k
' q0 n$ h% q* U9 l: R+ P9 r& K' Qint Push(Stack &S,SNode e)
4 Y; B7 v- s# C+ r: ]8 D6 E{
0 k2 h0 v; S& @ T if(S.top-S.base>=S.size)
9 u1 }8 w& _1 y. C j" u {
9 ~5 e9 q) o1 V S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
; n9 @$ \5 C. T8 @ if(S.base==NULL): m5 R; U! m, C; U9 Y# x
{0 n. w: ?* y# N/ f w# B
printf("动态分配内存失败!");
" m6 ]5 E) p+ [8 B: f return -1;/ d0 V! @' Q! t$ \0 [+ \
}
1 @2 K9 l. S0 h. A S.top=S.base+S.size;& z. p- j1 s* P$ G- n
S.size+=APPEND_SIZE;
3 g9 K+ H; Z% C; c0 H }
* D: R/ v: d% _( G9 v *S.top=e;
7 K; b/ E7 f0 i0 W! L S.top++;$ H: N* E) O9 F) I' I, p) U
return 0;$ Y8 O. I/ i) z3 d- A; p+ C
}
% v$ d- I9 X( r$ S4 Q0 j# u K
int Pop(Stack &S,SNode &e)
, C0 _3 R. S! K5 H2 X) S{; z* K# `' u& I+ w0 H q
if(S.top==S.base). n L a& V' A& r
{
! Y ]7 ]0 k- b3 c, b printf("栈为空!");4 P/ S8 l8 x$ l( b/ h
return -1;2 K) S/ p- N) A( ~ _& q3 \0 O
}+ L! @+ d7 O1 n( @
e=*(S.top-1);
* H& _( O0 Z1 \. f4 Z8 T S.top--;
, S9 P4 g1 x7 F% @) y return 0;2 }% |% @+ I1 P) O3 j: l/ B! i
}: Y9 G' `8 q* f d3 [+ r0 N7 \1 `
) X9 p' `& s+ B7 \ K! rchar get_precede(char s,char c)
; Q: b" H1 d/ V3 }( G7 _{
. O4 K. @5 z: y" Q* m8 `0 q- K switch(s)0 S% H" x8 \& u0 R+ ~1 \
{4 S7 U# x( f1 i& Z" [
case '+':
; k6 s& Z; P+ k+ B case '-':! [* N( b5 z$ l* d U/ B' _
if(c=='+'||c=='-')' G. E/ I* r! v; Y
return '>';) @, d. D# K6 j, R
else if(c=='*'||c=='/')' r( L" n6 n0 J6 ^( O( D
return '<';
0 Y# A) k7 w0 x& g" R# m else if(c=='(')
, ~5 H5 g) @& n- K Y return '<';+ H# O, l; z5 F- u
else if(c==')'). S' e4 ~$ m& j
return '>';- [+ Y* v& ]; C) B/ o
else ! s* _' t5 V. t9 Q& s: Q0 P
return '>';
0 p% m4 g( ^9 f1 i7 K case '*':
5 L* l. ?& w; O5 q5 ^7 P* T case '/':
9 \ t; i, d ^ C7 K! x if(c=='+'||c=='-')% O( X: \" F* X% V7 H
return '>';
. w; v& ] C t9 x% u else if(c=='*'||c=='/')
; O& k2 ^7 K3 F9 k6 M4 _ return '>';
& K% n; r3 {% o: @ else if(c=='(')3 I* l+ ~! e9 i- `# v4 j
return '<';. E- q C% m: V% l
else if(c==')')
, e- p) @0 e S9 y* l1 F return '>';
; ?3 u9 a) N. U, u# l5 A else' r e: m6 t) C- y: |% m
return '>';
6 n! p3 B3 e' J( k) U case '(':
3 c* a% k; J1 _, Q. Y if(c=='+'||c=='-')
7 f5 R& d2 P5 v' H! ^0 X. y1 N return '<';" C0 Q# K1 F9 x3 X" G" O _: b
else if(c=='*'||c=='/')$ B% e9 d/ U, W- G7 E1 Y/ [
return '<';
4 l" P+ [) R4 k else if(c=='(')+ M) d+ P$ ~/ I) q6 I) `
return '<';
& {7 Y7 y. g1 h2 ^5 D3 [ else if(c==')')2 {" c8 G. x/ M4 ?( Q4 K
return '=';/ `% [7 K7 n. Y: I" x( j# n4 J
else
4 g6 [) w/ a- J: r4 t+ C return 'E';
1 |7 h6 ~* @5 O# p+ C1 ` case ')':3 N6 v- M9 O/ K. L2 Y
if(c=='+'||c=='-')
8 g" `& b: {2 T return '>';2 H% F' w. H4 `: a* n. L
else if(c=='*'||c=='/')
$ u5 u, F7 d) D# T" {( W1 N1 q- H return '>';
/ e/ D2 j- I9 D! ?0 w( \/ @ else if(c=='('); A$ x1 P' n+ y7 g7 u
return 'E';) I: P+ f) S& r+ _
else if(c==')')
& P3 ]* Y' R% c return '>';
" [ R M$ o& P/ J4 u! [0 c B% o else5 O+ ^( s8 z! z7 k3 [ p
return '>';& i N d7 b j/ y# ]0 Y
case '#':
! h3 ~" A% n! a: K# N9 v if(c=='+'||c=='-')
& _! `( x3 p6 S. L return '<';
( b+ ~% L) Q; T1 h! n. L7 J# E else if(c=='*'||c=='/')8 O% V9 C1 Y% D; `
return '<';' t9 t* n7 V0 Z( G0 x/ T* }" s
else if(c=='(')5 n/ D, ~8 F/ |$ I1 k
return '<';5 D! `2 x4 D2 G- u
else if(c==')')
7 }0 w* @9 T) }! j# i return 'E';
& I" [, e1 u% V else
' X" B! T$ ~: e4 d/ d) J& J return '=';
" F5 _2 R- b5 _! k" U4 c% r& U default:
6 O0 \! ?) K' b% K3 }" { break;
- X, T* L8 i; i `) D9 z }
3 M8 `! s3 e/ R& G( { return 0;
' B. |0 O; n9 ^, X}
! v/ Z3 G1 T$ C% U# A/ j' `8 A9 Y) ^7 d8 s3 I
int isOpr(char c)" k; E2 l9 O0 E' _
{, ~" }' _6 k' j. j/ J/ v0 I. @
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')& b, b$ _: v- Z# n0 W1 T. G
return 0;
$ x6 a& i& Q. u' b( U1 K0 f! B- I4 r" N else
& |. s9 p/ h' h9 d, [* g9 k return 1;/ {. v$ k, J% y6 m" I: G5 ^( n" X4 X
}
: U! O( i- p. u3 D- } S8 k5 L
7 E! g6 i+ c; ~' Hfloat operate(float x, char opr, float y)
& I& b6 ]0 ~0 z/ ~- J4 V; K% R. k{
+ {: n* `7 u* ?( }# U9 d float result;
$ o$ H* R! l6 Y" ~- Z switch (opr)
% p3 I4 E3 K. {' W! { {7 c3 v& ]8 x j5 k% h( Y, p
case '+':
3 u! j" `' ~6 g5 o9 Q6 ]# X result = x + y;! T# D& ]$ @" H' O' A7 T: Z
break;1 Q1 {1 n- D0 R, A
case '-':
4 j8 i1 n" @5 y/ A6 c$ H4 F, g/ f result = x - y;6 a7 ]( T/ J- ?
break;
/ S/ Q# V( M/ ]% i" E- P: N case '*':
& `+ H! V4 q7 D6 k) Q$ ^ result = x * y;
$ F: Z7 |( ]7 l. m5 N+ J b2 E) w' H break;
* h/ C% j* x. w7 N* p case '/':
% z0 x$ ~: }$ U( V if (y == 0)
& Q9 s! D, e6 X4 ~ {. Q8 q# M9 c: w( g6 f8 w* q
printf("Divided by zero!\n");4 r6 _5 F% H: u, k3 A/ D) {. R
return 0;& \0 z, z- s6 Q
}0 z; a& V& _1 @1 U9 x
else. W( |; f. ~: W' k+ H' _( K
{; S7 l \1 V% L' S1 H
result = x / y;$ l! v C" e3 P3 u0 R9 y# U+ N
break;
' X+ {) G+ G5 w9 r# Y) G, Y4 g; S }
- ~: ?0 X; D( r: T' e default:
7 j" `/ L/ u) x& R printf("Bad Input.\n");
" E+ b8 y9 J" l G& | return 0;# q/ \4 I% `) f, @; `8 E
}
& `% s; Q8 j4 v, k return result;; m' q! s$ b) c6 c$ D
}
* q' u: k$ w3 I# P- C: p7 C
6 `+ d8 s- E$ j% c; ^/ r+ S/ l* ufloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/8 ]2 |8 z5 W6 A/ _
{/ o$ D( \( ?* @5 |0 n- V
Stack optr,opnd;
6 T" U# C! z, ?- g) A5 } struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;1 h! L' h6 o+ X+ \+ H; K' y
char c;
% X( v0 _# S2 h- a char buf[16]; h6 H6 O" j' O- @$ }$ f
int i=0;
; h/ c. @6 W( b8 a# F5 W% C ' x' G; ^: K4 Q% c/ o" j2 p
InitStack(optr); /*用于寄存运算符*/; l( w9 q7 e. `! W* @7 d
InitStack(opnd); /*用于寄存操作数和计算结果*/
" T. R) r/ |! y7 m! d2 j5 { memset(buf,0,sizeof(buf));) a5 k8 g/ w ?( }) {$ X+ J
$ ~* Y; a/ w) V( }, L
printf("Enter your expression:");+ t+ n! b! R4 g3 [! _
7 {1 S4 s1 w, ?+ U! ~' X2 P8 Q opr_in.ch='#';8 E% [* ?7 A, K j/ V' Q: a$ U$ ]
Push(optr,opr_in); /*'#'入栈*/
8 d' j4 ]3 i: D3 H5 H" \ GetTop(optr,opr_top);1 v3 o- W, B: l
c=getchar();
0 T' d- X2 ?& N$ z5 [ while(c!='='||opr_top.ch!='#')0 d; P" y! B- f0 |' E" @" B2 A
{9 k7 }' t, c+ b) Q* K5 H
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
1 n- D- U- X, z+ e' q0 w1 @ {
5 m' Q9 |% Z* W- X( G buf=c;
3 V& R, l! a7 I/ y6 v i++;; }8 n# ~- s, S: o i4 r
c=getchar();- _& z5 q! U5 c. S& Y
}0 P+ ?$ U9 T# M* T+ ^1 I
else /*是运算符*/) R0 t7 o6 [$ X2 k7 S# R# L
{
, ~. Q: K" w w buf='\0';8 z: ]: s+ |9 v$ w
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/) r4 I5 l( B( D7 \
{5 L J5 u& T4 ?: e) a6 k) h/ E
opn_in.data=(float)atof(buf);8 M7 j! J) f6 V
Push(opnd,opn_in);
+ v! i% [3 X: y% q printf("opnd入栈:[%f]\n",opn_in.data);4 Y+ W2 J* p" c; S* O8 F) R, `5 G
i=0;
. V1 O) [6 U" B( R: p O5 [: T memset(buf,0,sizeof(buf));# g9 W9 C- H1 C9 C3 N
}) g& ]: J6 ^& n3 \. H4 a! o
opr_in.ch=c;8 H' h0 j3 ^; D9 i+ O
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/. P. G5 V! y9 W0 V* \- s
{! }* L" }+ x2 S: v# a1 f5 h9 H
case '<': /*优先级小于栈顶结点,则运算符入栈*/
7 s9 r( B; t* N Push(optr,opr_in);
* [" f# e' k8 ?5 z1 h' _ printf("optr入栈:[%c]\n",opr_in.ch); q& |$ b4 w' _7 ~" `: u4 C
c=getchar();$ o) c2 F+ I1 I+ f5 X, S* @
break;* z" a. l: ~# o4 `) ]
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
0 V2 Q4 ]% s8 T1 i( T+ B Pop(optr,e);
' c8 p0 Q+ D! d& `5 q- E1 h printf("optr出栈:去掉括号\n");
+ Y$ X5 g3 d: B, | c=getchar();; P2 N4 X# d6 Z3 r# ?
break;
2 s- N8 M& O1 P6 ^( u1 g case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/0 g; L" N6 C- `7 C E5 Q
Pop(optr,opr_t);
( N O5 Q1 S+ t' @3 N. J" K; p/ ` R1 q printf("optr出栈:[%c]\n",opr_t.ch);
) F$ n9 n8 g: h; c8 q! ~ if(Pop(opnd,b)<0)) I% _$ o& K; J9 r R+ K. f
{ m2 s6 s: d1 A: E" d
printf("Bad Input!\n");: \" u1 ?' p0 t& n; a3 K2 m( ?
fflush(stdin);
2 f6 ?4 H+ k# ]$ y, B! P/ w" k return -1;
. l6 k9 a u* T# l }
1 K8 j) D+ [. G printf("opnd出栈:[%f]\n",b.data);
" t2 V5 P" f3 ~7 A. A: ~# e8 l$ L if(Pop(opnd,a)<0)
3 p/ j) g9 B0 }; w+ y( ? {
( o! B5 F1 [/ U2 O7 @ printf("Bad Input!\n");/ J4 H0 {; y4 G1 k+ {
fflush(stdin);6 p: G+ S0 D1 B! X* ]* o
return -1;
0 e3 W+ Y, C! O7 P0 G2 L3 ~ }1 j) Z2 \# h9 f. h' h
printf("opnd出栈:[%f]\n",a.data);. c# F* H0 F: F* a/ X8 G
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
& X- D0 Z( k/ P3 z( W$ H Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/. x S n3 {0 b9 [# K
printf("结果入栈:[%f]\n",opn_tmp.data);- o" S, i1 k) R" a
break;9 ~" U6 g, c1 k; T' L: c# J& w' B
}
9 T" p' q" g/ R: J }
$ E! }4 _: s: G; Q GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
1 y) L1 \6 I0 ? }
/ C+ R% k' \* `- l' g5 b. }: | H GetTop(opnd,opn_tmp);
$ {. [8 i) m, E9 L2 k DestroyStack(optr);
. Q$ W( z- |7 X DestroyStack(opnd);* `+ F: T' x# v( Q0 {" P, k, G# ?5 N' M
return opn_tmp.data;
6 \- K5 ]# T% ]& g1 j0 i2 e" P. l: S- y}
+ F/ c/ C; p( W- {9 G! k" d' a+ N5 n5 [ |# Y- I( f4 c( f# h
char *killzero(char *res,float result)0 v( H8 k# O% _0 d. Y
{
. T( N) k: K. g* M int i;3 S$ w) d0 Y2 X2 ^+ b6 z' W( a, N
( D% s* G# }. \3 ^' j
sprintf(res,"%f",result);) X" u4 S" d3 z1 Z8 t3 r& L
i=(int)strlen(res)-1;
% Q0 ]9 U6 E$ a5 S. z while(i&&res=='0')
6 @0 a% G6 A, O, S8 O$ U {+ j, c) Z- e/ h: R+ O9 h2 W. B7 [
res='\0';
* w% z) }. \# W4 h i--;
k( u0 I' J- ]- p+ k; Z, [0 [ }1 m; [' O7 g. @9 Q( I
if(res=='.')+ s- p: x3 a' n" X; z2 s
res='\0';
/ }+ Q0 u, P5 {8 ^% S" y, b return res; L0 C0 Y( [; O! b. f% N# b# A
}
4 V5 j7 P% _8 j/ r1 q/ j
, C+ u( j& o3 ~" iint main()
) @' Q/ `, i7 H7 w- s{
5 G3 C8 B U3 D# f char ch;
; {" }2 d! ~( @! a; B char res[64];, }1 _+ W% ]: O% Z" w
float result;; A! z: k7 e# b3 E% ]6 @
while(1)6 ?$ {6 `" u8 ~. p
{
4 i+ J) r# ~5 S5 O9 k; Z result=compute();- I) x* [8 S* ]+ i
printf("\nThe result is:%s\n",killzero(res,result));
, P$ H1 F$ f1 Q- `' k printf("Do you want to continue(y/n)?:") ;3 Y3 ]+ S$ j6 @4 n
ch=getch();
* q1 q/ ^3 o& a4 X, p putchar(ch); J9 x6 Q+ \: q$ S) L
if(ch=='n'||ch=='N') l( T3 b6 h6 {: u* X4 f
break;
% f% W4 A) A @ else+ a, [' k, K3 P) Y& W/ F9 n
system("cls");+ n3 B' u# q2 m6 L8 J* p# }
}
8 _' f" y& v c4 n: Z return 0;
+ y( ]* M+ M, }( o/ \9 v y9 `$ G}
M$ O$ C, x9 c4 V2 J, [! d F# ]; x
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|