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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
+ V: z) W! q6 D7 R( y# I+ E. S程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=- j0 a2 `; K1 Y
/**************表达式计算器************/
* N8 ~4 }0 X' ?# D+ U#include <stdio.h>; ]. C1 V& |) w; s7 |
#include <stdlib.h>) \9 P0 J7 b- K
#include <string.h>3 `. m) o- k3 }6 c+ O; N
#include <conio.h>
/ y, O3 X: I# s& X( b6 y7 C J#include <malloc.h>
! M% z% m8 i) q; ?; s
% O$ L: ~1 F+ d) w0 T# P$ U. n#define STACK_SIZE 1008 ?, c2 e& D: P# \3 `, t: y
#define APPEND_SIZE 10
2 O. L- }/ c& m' \' _( Q8 M( `# G; _
4 w$ @4 C7 a9 i& d. |, o Ustruct SNode{5 }0 C1 U8 b5 e
float data; /*存放操作数或者计算结果*/- w4 E9 J" }. I' B: y
char ch; /*存放运算符*/
1 L; i+ c% [2 R};: N8 p! X% k7 f1 Q0 o: ~" h+ g
5 R6 W3 G I& `" [4 N& j, vstruct Stack{
( Z5 q& O5 G8 U; \ SNode *top;
! q' c7 m V- z2 U: ?9 U SNode *base;
( l9 A: { t, `' \. i int size;
9 v* ]2 ?- U ~1 V};# V9 P% v; ]' N4 C
/ i( w @# i) d0 S% |( Y U
/*栈操作函数*/# k" y+ S! n" e2 U7 y' t/ \
int InitStack(Stack &S); /*创建栈*/; P$ L4 W/ d, B
int DestroyStack(Stack &S); /*销毁栈*/
! H4 x; W4 C. E' j6 q* zint ClearStack(Stack &S); /*清空栈*/
4 f$ C! \% p/ V7 r- C% mint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
! n' q2 L8 d7 C Rint Push(Stack &S,SNode e); /*将结点e压入栈*/
; P) I F/ l f* l3 x, ~) ?int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
! g3 O. g1 y& C; y) D* F, P- t* ?* Q, S4 y5 I- j" E* h
/*表达式计算器相关函数*/! I7 `* j9 @* q0 e1 b \
char get_precede(char s,char c); /*判断运算符s和c的优先级*/9 {$ A n4 h4 r$ A% M
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
* h& F0 n: V6 b5 d3 V% jfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
; U( T7 L; m6 W2 Q) D, hfloat compute(); /*表达式结算器主函数*/8 C6 n' E, | z5 l' O, r# ^
char *killzero(float result); /*去掉结果后面的0*/
% C& L4 E, W8 I' `0 N& F9 a ~* q% a6 G
int InitStack(Stack &S)3 u- d! Z8 E3 K9 C. T. ^
{
; G$ v+ t( e: ~- }1 a) F3 l5 A S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
6 D$ u+ J* D, d+ N, P if(S.base==NULL); ^* C- Q/ J5 q5 k& h6 a' u4 d2 R/ Z
{
Y \: I6 J1 N) N* c printf("动态分配内存失败!");% ?0 X; P& ?; G
return -1;
% G L& P: G* a" l, R }/ b' s7 q# k9 i/ z; m& p5 I
S.top=S.base;
2 D' n2 o. D" K" S5 a S.size=STACK_SIZE;
@5 i5 ^! v' `) Y0 f7 t+ H return 0;! p" q8 R% o! @6 Y, ~$ A
}8 N* r; M& @( X5 v5 M
8 U# ~: p# O/ w& k& P4 F0 x) @3 @
int DestroyStack(Stack &S)) C1 ]" C) L' I# _. h3 g. e* P
{% K! h) O# I) |; w2 P; x# ]
free(S.base);! G- ^9 ]" w# E6 _2 p
return 0;# {9 ^* C" y0 n9 x3 i( X
}
: u: e. I$ R9 d A" Y, s
! y7 @4 z+ ~5 mint ClearStack(Stack &S)3 {4 v% p8 ^- k J. d7 k
{) O$ l7 ], o) v8 U9 U
S.top=S.base;
5 S9 U( F. i, C; I6 ~ return 0;6 H# J1 v6 M, p/ W) \- P, B9 }0 k
}
1 |% f- G: B1 P% U. [7 j$ a- U2 y0 Q1 v" ^
int GetTop(Stack S,SNode &e)
4 y% a. C) p* U' K{
) T; g0 H; e5 l: ~ if(S.top==S.base)
4 g$ c5 x8 b) e9 k( n {
2 T) C! `* R3 x2 _- i% | printf("栈以为空!");
, m: n0 O, \; N& Z$ h9 w: m return -1;' J' H) v( y8 j5 F
}' M) m; b5 V% A7 t* c* e: j( G+ T2 e
e=*(S.top-1);
. I6 ^& a! U+ h, x return 0;
1 o& ]/ ]/ r- s& z* D; I# f7 J}9 i b5 O1 m7 `* y/ m" x; W+ z0 z
2 j6 P7 w( o z$ }int Push(Stack &S,SNode e), j! F. K) u: s2 x; O: t. S) F# P7 ^
{
) g4 d% s3 w7 c9 {" j( k8 M6 n if(S.top-S.base>=S.size)
' R# U6 |# M* a" v0 `$ Q {: B) m# v3 G* O8 j; T$ z) H- r
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
+ y3 x% q' o# C if(S.base==NULL)
* @7 ]6 ^2 s1 z9 A4 h6 ` {. m# C+ u# n* X5 k/ \ R2 d
printf("动态分配内存失败!");5 e( [) b% @6 |: j7 `0 a
return -1;/ Z4 g- i' c0 [
}$ A: i7 t( Y' D! ?9 p8 u
S.top=S.base+S.size;
0 s [5 z* J( ~9 M S.size+=APPEND_SIZE;( J* A2 U' ^) W n- m* g( f6 \
}0 J4 U# g; J) ~& E5 }
*S.top=e;0 |2 ]# i; J0 a5 J
S.top++;
1 I0 i/ t) N7 K9 R return 0;: E( X& m( c! R$ t
}5 h; D: q* H9 k. H4 B. c2 W
' ?9 N5 F! r, C6 ]6 m4 Q S4 d
int Pop(Stack &S,SNode &e)* P/ J+ b/ h8 E+ v9 l$ m/ [" u
{
5 h) F$ \1 l! p# z a+ \; B$ N# C if(S.top==S.base)
6 N. l7 T, M4 t {
3 o0 H: T, d. k printf("栈为空!");4 v A! n( Q3 Q' b
return -1;
' R. ^0 v% L a/ M# @ }
0 b9 j0 A6 h9 L5 x3 T2 E7 C e=*(S.top-1);& O* g, X1 J# P3 C; W, h( R
S.top--;
& K- G4 m* j5 Z g& y return 0;
" u5 X* E; y* I) l& U0 i. [2 x) w}
4 v# n# ^6 k6 \: ^+ _ O, D7 u U: D* C, L1 Z) K$ @0 _7 t
char get_precede(char s,char c)
) S F1 t" m8 D, W* }. I0 n/ r H{
4 j( K/ M- r; Q5 P7 ] switch(s)5 K/ Q3 B! Z% F# E* W
{+ o9 M! K9 c; s7 V% K/ Q
case '+': - o* P" g5 C' q& x# e+ F% S/ G& p5 a
case '-':
8 ?& d& x5 z n. l6 ?2 J if(c=='+'||c=='-')
1 v' e. [4 L; U- g1 A) h1 ` return '>';4 P: a0 u" K8 G ~6 H7 e
else if(c=='*'||c=='/')3 N. }6 r. T/ a; x( @( k0 F6 \
return '<'; W3 T* ?4 H1 f+ z. g9 S
else if(c=='(')
, A6 D0 {4 @- g2 E return '<';
5 r; o5 ?( t$ b" c5 z5 G else if(c==')')
" C3 d% T# B9 _& { return '>';
9 _+ Z- G- Z- v( H else * u' v8 d% _' o7 \, z: H
return '>'; C! G( c& m. D8 @: i, ]+ I; E8 V
case '*':
3 T: q" b# w4 O5 s$ J: ] case '/':
% ?- o8 z/ \! w9 m8 f- u6 z if(c=='+'||c=='-'); N4 e9 g. W( W, M2 p: g
return '>'; i; \5 p& b( {
else if(c=='*'||c=='/'); N1 p3 D0 h& m
return '>';
* x8 P8 u3 x R. v$ @+ c% o) i else if(c=='(')
% g# @& ?4 _( q" Z- A return '<';
, m$ H2 Y6 }$ j# Z9 J* J: R; m else if(c==')')
# Y, v' X4 R- g8 w, ?$ a return '>';7 O6 G- _$ ?5 E" v
else0 z8 g0 I. {7 R& w" c8 Q/ e
return '>';9 W4 N4 R5 a4 B+ R$ Q& X: I
case '(':$ n$ w* x7 I0 I2 \/ q/ I
if(c=='+'||c=='-')) m U+ Q; I) ?: g3 f
return '<';
+ Z$ G. [) Z _, l9 u: y9 H else if(c=='*'||c=='/'). T8 @# F6 X$ \ J, l
return '<';
4 y0 l% `# [# u1 F1 J% H6 f else if(c=='(')
9 @6 i" x9 O' Z return '<';3 q) Z, l1 U: x( F2 J: ?. \& F
else if(c==')')
9 }# b4 f+ m' w, y1 V; ? return '=';
3 t: y0 P- C q; U1 \, }# p, N- { else
! K/ B5 x$ E2 W* [" L) l+ T# L, J return 'E';
: R! R% \! {: T5 ~2 P case ')':+ Q1 z5 H( E! N/ X0 }5 [* b
if(c=='+'||c=='-')
$ @" w0 y c* E return '>';1 l& F, c; `. K; i
else if(c=='*'||c=='/')
# ^9 B! t2 l5 { y9 W# | return '>';
; Q1 v U. s r- q( f7 g else if(c=='('). L6 q8 Y* }) B( I1 K) Z% l
return 'E';
1 i' @- ?* b; H. u& \$ x- [ else if(c==')')8 \ N" I+ ]. S/ m
return '>';3 D6 y' a7 v% {( K8 y, g" X
else1 h0 P3 ^+ x- C- w6 f$ Y
return '>';
- X8 q* q4 { g% r# J) F case '#':
5 a- j( [* _+ Y) [- n4 w if(c=='+'||c=='-')/ |5 }) Y& o* p# }) D# c2 g, ^+ z
return '<';
- d9 y. D/ j s3 X* K5 d4 m else if(c=='*'||c=='/')8 s5 s: z% }* u, P& l+ x" [0 ]
return '<';: j8 ? N# \6 n8 D
else if(c=='(')$ U; \7 z7 _: m) k
return '<';
4 ~& D& h/ O7 a; w else if(c==')')
0 F8 G; v1 \ H9 U2 \ return 'E';
" X- E+ b# k2 `0 K else
9 F. T7 M6 W7 @$ y6 X return '=';+ G% v* E* f/ ?% C3 q
default:, s! w7 H' k) d2 D0 X3 A
break;" v i# c% S! p/ ~
}
4 w6 C# I: w( Q, v% w% X! E return 0; 9 Z5 C, r* \: {8 y& @& L
}) s# f0 x! Q5 E! ~) f+ e& U; ~1 |9 j
9 U* A' d, I4 p; B% E# A/ d1 _int isOpr(char c)
! `2 N! h- \2 {& o2 N{& i$ i8 C9 t! h$ C3 W, [ X
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')" [! `1 C% |2 t2 V3 T. b5 ]5 ~
return 0;
& N c/ A6 c. s* d- a( ~' f- W4 y* l else
. @) j' Z6 W. @0 B5 T7 V return 1;
$ G( \ o$ h/ p! M5 L}
5 {* w6 t# y- l5 L0 K: M# I" y* |8 x7 u
float operate(float x, char opr, float y)
& `( v; Y5 w2 F' o4 v/ c$ g/ J: r{
: Y9 p: `3 F. {& P; k( D3 Z" Z7 V; k float result;
% e- W, E& K: { switch (opr)$ A& p! r$ u/ h+ Q0 `
{$ ^* J8 [: p3 W2 }8 {2 n* r) h$ V2 _
case '+':
$ q9 h6 k6 @$ w" L* F result = x + y;/ a7 g) ^; o# R
break;8 u5 Y" P, V6 h- u2 H6 M0 P
case '-': : y# c! e4 X3 {
result = x - y;
! M3 g- G t! y. i1 T break;" o2 Y0 i2 P; k/ r
case '*':
4 h) S: K/ D2 {, t result = x * y;
' f: L+ B1 i w0 ?; {& O4 b, r# Q break;5 s& n2 B' x- ]6 U) V( |
case '/':
& e% Q( i$ h" {9 ]8 {$ ~ if (y == 0)# H0 y/ y+ w1 R; P4 E! }" ^
{
u9 S5 g. ` M6 W printf("Divided by zero!\n");9 {$ H# g& L/ v. v/ Y7 E
return 0;
2 t* l; N* |: q2 t }/ P3 ^. i$ A* \$ g3 J& v$ x t
else( g, _4 U- o3 n h2 b t
{
" {3 F7 z3 P8 r. n& K8 T result = x / y;7 m9 O: z G/ Y3 i, h: l
break;0 V2 L4 x- B k6 G' u7 X
}
! r) i" | Z5 w7 A default:
0 v( Z( v; Q: _% ]+ b printf("Bad Input.\n"); ' p* c8 D2 f0 W* n# J3 X
return 0;" |" k- m! N2 _# I; x0 @# W
}
1 n. x& Q; y" O. W2 u return result;3 i/ V3 l- |$ @( j% ?( V% H" U) d/ y) s
} 8 O4 V w6 C: e$ `& r" l7 u
) l5 U4 ^2 X+ M, }& `1 zfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/3 m+ t8 O% }4 y, p
{& F' L) p. U# ^7 Z
Stack optr,opnd;
! ~- w* P* X0 j, ~* O1 n4 ]+ f# e struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
- y+ M# q4 x! X: c4 e8 p9 n: d char c;9 i+ U4 m. M, C6 ]% v* B* }
char buf[16];6 H8 Y4 I3 X% h% o t6 D
int i=0;
& S2 T2 i+ T# o, K/ ^7 z
$ t- q c# L; z+ P. Y5 N InitStack(optr); /*用于寄存运算符*/. _3 D- J1 l5 b* z4 [8 u
InitStack(opnd); /*用于寄存操作数和计算结果*/# X! l% S8 Q, L# J7 c
memset(buf,0,sizeof(buf)); f7 D: [6 t6 q0 `2 a9 L2 q
* j' ^1 V5 q5 L- _
printf("Enter your expression:");& h0 Q7 d5 d# i( d
$ M0 c# `- M& R4 x
opr_in.ch='#';
2 ~7 s( c" r4 s, ]/ N4 M9 Z3 Z( H Push(optr,opr_in); /*'#'入栈*/
* }/ ]% O! s* ]2 b; @ GetTop(optr,opr_top);3 z2 R1 v; `" C+ a5 g" Q# b5 M/ i& }
c=getchar();
# Y, l, X! b2 J while(c!='='||opr_top.ch!='#')
. m0 W1 z& [+ j B) P D3 w {
& m. q6 \4 W% W4 T& q L3 O if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
% M+ x: l1 B0 p) c {
% E2 s3 [) q3 C* Y buf=c;; m- ~/ s% K: `+ `8 l* g2 U, b/ M: G c
i++;& p; d) @ b% O0 c
c=getchar();
2 q/ {; N+ _6 W! J. C3 Y7 j7 M; [$ c }" f+ E7 S, k2 s9 w7 X) I8 {
else /*是运算符*// Z; g- D, l7 T, B
{2 ]) d5 z8 ]9 |, e, T
buf='\0';
! M' ^5 A, H2 d if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
3 j0 i; o: E. }. o; K9 a {
/ a* `2 O& {8 ^$ l' L# y4 y+ U opn_in.data=(float)atof(buf);
) [9 ?: H$ N2 g+ l, X Push(opnd,opn_in);8 I* `6 L& a7 x; y7 _; }
printf("opnd入栈:[%f]\n",opn_in.data);7 \% \ B) m& @5 R ]$ p
i=0;
; g% \6 G( _& e. m+ M6 d memset(buf,0,sizeof(buf));8 `7 V9 w ?/ k3 B6 M% E
}3 }9 S# _- I2 i1 q a0 U' f
opr_in.ch=c;
& m. |9 _. F( {# V; ]2 q switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
/ }. K9 K* F8 O+ b3 Q {
/ S0 t2 s2 v- {0 |6 [% P# {* E8 Y case '<': /*优先级小于栈顶结点,则运算符入栈*/, {3 p1 i8 E+ P. X: }8 B0 g) ^
Push(optr,opr_in);
" E$ }1 S0 P! e5 b f3 l3 _ printf("optr入栈:[%c]\n",opr_in.ch);' B) [6 J3 o5 d& Q4 N
c=getchar();* q2 U; a. G$ H( I9 k1 U6 z
break; W, G0 K, b _& `* z
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
1 W3 \: m8 b- D# c8 b* K% W5 q4 H Pop(optr,e);. ^5 r0 W3 l, C2 k
printf("optr出栈:去掉括号\n");
7 C& ]) n N" ~" Z c=getchar();: [9 ^& y* d# f j7 u4 m
break;% r: d8 f- ~, Y8 @! z' ?8 v) b
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/% i7 e- x8 R! S. |; ]4 u+ C
Pop(optr,opr_t);
% A' v& ?- F' M2 r5 E- X printf("optr出栈:[%c]\n",opr_t.ch);
2 _2 s7 E% r" j \. ^" F! u5 Q if(Pop(opnd,b)<0)
+ Q$ N0 A# V) q, c* n {# F' r& _: }6 i) r! B$ b" ?; d
printf("Bad Input!\n");: n" F( E0 e) ^7 x! T6 J) p
fflush(stdin);& ~7 O& }4 I- N) W
return -1;+ G3 S1 h! l$ ?; ]9 M
}
1 W1 u) w4 i* ^4 A printf("opnd出栈:[%f]\n",b.data);3 L( Z L& J. U5 t- Q4 z
if(Pop(opnd,a)<0)
1 ` f$ }& c& z; @- z/ G1 k, b/ ]. P {- d. Y8 i% u/ M1 o) q; r& P2 J: V
printf("Bad Input!\n");
: U& x( [6 z3 h0 { fflush(stdin);
( q' o% H1 W# x) F! E return -1;$ ^1 w6 q9 X/ x' K6 G, Q- R
}
, s$ {9 k2 Y: G; x- z; D printf("opnd出栈:[%f]\n",a.data);2 [( l$ f% |( Y$ e- n
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
3 q+ B+ H8 k9 E4 ` Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
+ K9 c# F8 a) e, o0 ~, d# M printf("结果入栈:[%f]\n",opn_tmp.data);
2 D( J* h; [4 T' s) @( Q break;
3 x: L6 K2 O! ?) g0 c3 f, m }
1 z& I. f$ G7 m6 u; Q# E1 n }5 n' l0 X6 b0 G% _
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 1 n* Z; |6 L9 a! M8 @! j: ?
}
/ ~) T! S0 O- q. L6 M GetTop(opnd,opn_tmp);, E5 f: T8 W$ z: f
DestroyStack(optr);
- ~& Z4 {/ y7 h Q+ k$ W; K. P DestroyStack(opnd);$ K7 i: F( o) U/ L# c
return opn_tmp.data;
% `! A* o: j2 D5 a. C. V}( A* v7 S+ t/ |9 S; ?9 \, @" e
; w2 @& i; Y2 R F4 `
char *killzero(char *res,float result)1 |0 @% ~' v3 z1 f- X6 \
{
^; e8 m4 Q+ I; K# ]# ^6 y int i;
% B# M, u5 s% {; U4 s. t
1 X7 K8 `, T- f" X: N sprintf(res,"%f",result);
$ p8 O' H) u' `: T7 `* C) m9 S i=(int)strlen(res)-1;
5 X9 x$ T" r. t. J2 k; n while(i&&res=='0')
; H* s. [" x# ^. V0 C1 O# f {" D/ B+ e! x8 v. g8 i% F
res='\0';% c3 M6 R+ c3 a5 h$ a
i--;
X) A2 V) Q7 {4 v, Y' o- N8 K }
0 {9 H3 b2 k2 k5 n1 w8 O0 N if(res=='.')
0 H: D k( ~3 f! q; D& E res='\0';
0 z% W6 v2 Y/ t return res;
' G: j1 e) t7 f/ n}
; G9 Q1 N" v9 T0 P' j- N; w' L$ J ~( s+ v( j2 K
int main()
$ C8 c7 \0 _. D) I/ z m' Z! P{
/ t0 Y7 i6 Z2 y0 T& G char ch;/ M3 X4 N; J6 D& r0 F' H
char res[64];
5 X* U. ?2 `% F0 x8 v. L. ?2 @ float result;! D& u3 G" R3 e# o) y0 t, p
while(1)
/ i; Z9 t) ]* ` {8 A* \7 l5 u, K9 Z. n% a
result=compute();. }* i9 ]; ^6 V* k
printf("\nThe result is:%s\n",killzero(res,result));
' h. j& ^) D5 o) i printf("Do you want to continue(y/n)?:") ;
) n( q' w2 d, N ch=getch();
) n$ ?3 V) H& F: F5 G putchar(ch);
- b: p' U( d( Q9 G2 L0 w if(ch=='n'||ch=='N')
. N2 R6 U% n. _/ v# d6 M( \( Q1 l break;
2 V$ @6 n' O3 i6 e* x& v" {1 S; x else
|$ G2 e9 T# G* Y- v0 i; T system("cls");) Z- s2 {5 m- c5 c1 k- H
}: h! x0 K( M- J$ B' J0 m2 Y
return 0;4 s* L7 l2 e+ ?
}* ~% ^# {% v& ]
. J% T4 L; L/ _" D# r) C[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|