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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.- I3 [6 X6 l0 c
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
: d) ~( y( h( M) P" K$ Q/**************表达式计算器************/8 \# a1 D9 G4 ~! v& S
#include <stdio.h>9 V$ C5 `( H3 n. Z) F% s& Y' _
#include <stdlib.h>8 [* g, a2 G9 K Z4 o" z# O. G
#include <string.h>/ L$ g' h; l' ~% Q: {: _# j
#include <conio.h>
d& k# y0 D( t# O* `7 Q#include <malloc.h>
x1 |. ?6 J4 g' y" B+ N! C% Q, q: j3 w ?# N7 j
#define STACK_SIZE 100
" p& ^0 P2 O, p) C#define APPEND_SIZE 10
8 i4 _7 v2 c0 c8 F7 S5 h; j5 Z0 h8 L
0 @% Q) F/ }# S( C3 |struct SNode{
+ q/ I- W. k" T: X, R! X float data; /*存放操作数或者计算结果*/$ ?3 Z3 e8 \9 K+ J5 ^3 d+ y
char ch; /*存放运算符*/! y: g9 m1 B1 A2 ?; V8 ~
};
! p: ~4 o4 H: U& Q- {8 C; r5 V( y# `$ x( S: N; u; m! C
struct Stack{9 S: a; m+ Q* J
SNode *top;
" z- |' e. P8 G9 j SNode *base;
$ B' K- `6 {+ L- R1 G3 N5 T int size;
' ~: ^3 q4 Y8 p2 {: \6 k/ F};* g7 T, b- m1 F4 H
% a6 l0 U% d3 V9 P" E
/*栈操作函数*/9 k. P: u& w: |
int InitStack(Stack &S); /*创建栈*/+ p2 { ]1 ^1 n& M9 c; j8 r2 i
int DestroyStack(Stack &S); /*销毁栈*/* B4 n" ~- M; N/ m. y' G
int ClearStack(Stack &S); /*清空栈*/1 ]2 S1 y) I; A
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
0 H, L% E' r6 f0 X8 Kint Push(Stack &S,SNode e); /*将结点e压入栈*/" X$ t, k8 R7 H/ ]
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
8 A5 v/ h; W: X0 t7 u" t# l6 @
, I# o* h2 \' J; m. Q/*表达式计算器相关函数*/
/ N3 \" g: h. y1 a0 Y4 t6 I/ u5 achar get_precede(char s,char c); /*判断运算符s和c的优先级*/2 R9 |" b/ g! S# b4 e) U
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
% C% [0 }% [5 X! ~) a% qfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
, f8 i, w- w2 w0 J2 Z: y+ y! Xfloat compute(); /*表达式结算器主函数*/
: ?' o- w5 c6 a- U' Z5 h8 Gchar *killzero(float result); /*去掉结果后面的0*/ ( |9 \' y6 P1 _6 K* n$ W" }& N
+ X4 s) ~) J$ q: Y. bint InitStack(Stack &S)
# |7 S: L. |+ x7 H/ c4 @ x{& V' s* y# w/ D/ I9 A
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));/ z, O' ~1 Z9 ~/ ]3 |' W
if(S.base==NULL)" L. b3 L/ A* _( q7 t
{
. a1 i; H" A3 @ S# I. H printf("动态分配内存失败!");$ Q% I) h5 m. Z1 E
return -1;
6 r( n4 ~* V% ]# {( M }) J3 T: o& X8 [
S.top=S.base;
! E o* C+ v8 ~0 c7 B S.size=STACK_SIZE;3 C8 s, p3 o( L$ W
return 0;
9 e1 q9 e# c; u! D}" w0 s$ S5 k' i V% }$ w6 q) w
' X+ }5 J; H) ~0 Y `6 O' ~9 ~# Q
int DestroyStack(Stack &S)
; p( ^* P, z% h$ G" _7 S6 ?* \& G{
# V/ I& f6 r: S free(S.base);
; U8 |, z' _0 e4 m- K/ | return 0;
; k& y4 u& C! K% S0 S* C}8 N6 q+ g( i7 n& R6 ^/ i
1 I3 j7 l$ Y; H, Z# o9 Kint ClearStack(Stack &S)
6 G) Q0 N) T0 t- G* B% ~{9 i: \3 g8 j _0 D+ [; I
S.top=S.base;
! K* R8 U. f2 d( S( ~$ J4 h% D return 0;* X! e! R/ L# d/ h
}2 a' n# o/ @) ], K5 t* q
& l6 s6 @) `7 H l4 k% Gint GetTop(Stack S,SNode &e)
C) H1 n) D% d( H+ r2 M k{1 }8 a) [/ R! }) F# C! [, Y
if(S.top==S.base)# W8 u. h/ M, s0 g0 b4 N, S) N
{9 ^) h; p% C) i, i& d9 {
printf("栈以为空!");
* F' n4 }# S5 e/ M; Q j return -1;
9 K4 G4 k# k; a) B5 D6 L" m }
) f; @( o, d1 I& U g8 j# E e=*(S.top-1);
( O+ `8 [* T% w- I3 s! @ return 0;! J9 a$ T7 A' m& V: z# w t6 q+ s
}" I* I5 B# j. h! @4 w
, D0 [1 C% `" _- d( |6 n
int Push(Stack &S,SNode e)5 T; U6 O. ~0 Z' P
{
- y7 M/ Z% v* B2 n if(S.top-S.base>=S.size)7 z& B( T0 f8 G( ]# z
{4 A0 L _) u* m+ p6 s y3 T. J
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
! d7 r; a- R4 `7 c3 z# L if(S.base==NULL)
6 o1 E6 ^# L, L Y" [& W {! ^+ V0 v1 m3 n V9 u( a- P& e
printf("动态分配内存失败!");
( \ I' Y2 d2 C1 `$ ]! E return -1;
0 Y1 w0 y3 n. u9 u- X1 ~. d }+ c3 g" R, n' L
S.top=S.base+S.size;1 C+ c0 V7 M) s
S.size+=APPEND_SIZE;0 R. B3 J* L- K2 c3 P4 A9 o4 s& W5 ]! P
}
) [0 f9 E- Q, u. m( l! Z9 C *S.top=e;# a+ ]+ P& u3 b8 B
S.top++;: y1 l$ G! H/ y( d, h! q0 z- S$ ?
return 0;: G, Z1 [0 X2 B6 x
}
7 m, Y" ?- E3 S+ W) M8 W. ]' `
* o5 y" x r- D1 e; k/ t1 Kint Pop(Stack &S,SNode &e)/ \7 i$ V1 k/ b6 G
{
3 @* y& w% ?1 J, Q) ^ if(S.top==S.base)
7 d0 J- C+ y) C% ]4 W {
+ X8 @4 w" ^$ n. e, L/ k/ [ printf("栈为空!");1 _" B3 L) M+ I& V; |0 M+ B+ D/ o ~( `
return -1;
$ J7 W+ e/ M3 \ x }
! [5 g% j" O3 y' ]2 H e=*(S.top-1);! W7 y. N- p: q! n( w' q3 W2 J
S.top--;, [, k" O2 k# k6 V
return 0;3 N5 h; E: [ g/ D
}
- z3 a; m9 r" p) @& N% A( Z8 Y" f4 m& G$ s2 p
char get_precede(char s,char c)9 u8 G1 m- g |4 m5 `$ p7 ?
{
6 n! }( U% C! s! o/ w4 w switch(s)
3 ~; @4 f/ Y6 c& @: V {' ?5 w$ Z: ~4 R7 y( S _
case '+': : i4 x5 U. D2 C9 W
case '-':
/ p+ y M/ ]4 s* u% V0 P4 ~ if(c=='+'||c=='-')' Q. S4 V. n: v W0 m
return '>';# `- t* r% @9 t% p: @
else if(c=='*'||c=='/')
: U1 x9 @! G* W2 q+ y" f return '<';
2 P! p' t V3 ~* L else if(c=='(')
4 K5 v$ D# H: d! F& [& }: F! I# d, p return '<'; ~3 D7 ^( c3 i
else if(c==')')
% C% i+ t9 V9 @4 Z4 G d return '>';
% ~- j) ^, j, Q/ ^ else
% D1 {+ k7 ^# z. K; i1 c8 v return '>';; q, |2 R: |& ^
case '*':5 v; t, ?+ I* b5 B' o# E* {6 q
case '/':
{1 K( {# Y2 F if(c=='+'||c=='-')2 G: l* v* H& ^6 \7 T) S! q
return '>';1 p5 W6 ]% j4 S. V) Q3 b6 X
else if(c=='*'||c=='/')8 d/ j2 N) u1 G7 A
return '>';1 q, v: |1 ?" ?$ i
else if(c=='(')+ z9 C' c0 b% x2 f o: [4 r8 C
return '<';* |$ h$ s' T. u# A7 h+ m Z
else if(c==')')1 ^5 o9 c C- k6 T; q- Z
return '>';0 C: s6 `; Y% `+ y4 X! n
else, D8 y4 b. {1 n/ v$ C8 c
return '>';
. ^. n+ j4 f6 E9 |6 m2 T- d case '(': R+ {( R) G4 y; D
if(c=='+'||c=='-')( N6 c7 `) J& {5 D; I9 J
return '<';
8 F+ F5 {2 g$ P8 _9 q9 ?. F else if(c=='*'||c=='/'); z/ ]- d8 w& `1 M
return '<';, D% B1 V) g9 T2 z
else if(c=='(')& }6 [0 B* C, G# n
return '<';
" y) W8 y1 X* F1 U( I8 e else if(c==')')
4 v5 x; \# d' [ return '=';
% U1 v5 h1 {7 u3 S7 n& q5 m else
: a! \( c! L* K$ y8 }8 |: P- n5 } return 'E';
, R7 h+ v5 O1 S4 M case ')':# W/ k8 E# L, m; x& }1 o% ~' I
if(c=='+'||c=='-')7 r6 z! Q" i0 ?7 N" c/ @* N5 `
return '>';
2 U. W; D6 e, H" s' S else if(c=='*'||c=='/')
) L* Y! B0 ^5 @9 @0 k m/ m2 X- ? return '>';
/ A8 J& P" D$ G$ |- F else if(c=='(')
( N; E h. U) A' X$ K5 ~ return 'E';0 h4 ~; j* [' m
else if(c==')')
8 N6 `) J; ?4 i return '>';9 Q9 E$ Q' e1 |
else# q3 v* V5 @; g
return '>';
1 @. c* }6 P. H: I case '#':" M5 W& _3 l3 _ r% j# | J: E
if(c=='+'||c=='-')
?' a& M, S' e Q t! y8 G return '<';) _5 V' M4 a. z! I' S8 x
else if(c=='*'||c=='/')# g, L$ `1 X; v h
return '<';* q+ z2 o" }' _) d
else if(c=='(')4 u S, _2 w' h1 `% H$ {: B& x
return '<';
2 Q' W* j4 i' R+ \ else if(c==')')
( d1 K; b6 ^& h9 ^% ^, Q* Q return 'E';; L) N. m. d; E. Y' J
else- e. C: M6 Y/ H$ Y; A
return '=';
' ^1 O- B: I* X default:0 @9 C, }$ l' Z
break;
4 ^- i* g. E8 K8 ~0 u }7 a h r4 n: W4 w. s% U2 e/ A, h
return 0;
* g3 B9 U9 N+ i, F7 J( z1 ]# D# o3 x}
# ]% Z/ C3 l2 Q$ G7 `! _, s, i, R
S0 O7 n9 p7 R* pint isOpr(char c)6 A! {1 e" ^- [1 w3 A+ }
{; H4 r9 e2 V2 @" k& I* c: P
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
6 b( B/ G. t/ E' S# f s3 A return 0;
. n$ J: X9 n: i- p7 |2 b4 _ else : w0 c d9 s4 A9 ?8 O4 t* }/ y
return 1;
3 j5 p7 v8 ]' ~}
4 C# T8 Q b; c$ s8 ]! e* @- q+ l9 K! w
float operate(float x, char opr, float y)9 b/ |' r/ h( w4 ~( Y% D
{
8 {8 q9 N+ A0 q& i; M float result;6 N( i) U- m- S( N$ }7 [
switch (opr)6 B( u" v( o, x% O; B! A/ {( G
{* X8 Y3 R2 U- O5 y% h& o6 e2 t
case '+':
2 [; N. j6 F0 ^% `% c# S- r7 |& j" H5 g result = x + y;! ~8 F. d, d! O/ j, W7 g
break;
3 P, e& a% ?% T3 B" X: p case '-':
/ }5 L' M( R& L! R- S* g" ] result = x - y;1 z- S( l' L1 n; x+ `
break;
' x+ ?# @4 {. b case '*': / V, y% E' ^: k; ~* B9 v: c. m
result = x * y;
3 ?0 j; [; s; t9 F8 D8 F7 j. b break;1 j, @2 k1 P- b0 l: y4 ?
case '/':
. Q l( c3 ^) Y( n% R if (y == 0)* g% _ P4 g I' R6 ~" U+ l# [0 W% M
{, W0 _6 e+ u& ^
printf("Divided by zero!\n");
3 g* c: p. G# I& b& i return 0;& R- R# U9 }/ U! @: x$ E1 g, T
}
5 P+ Q/ v& @+ z6 s else, ]* Y: j1 \! [% K7 ~* o
{0 U" F0 u8 m! Z. {' t# P2 ~3 h- X
result = x / y;( @- V: n- A1 F7 d* m6 w$ K
break;: [/ S: @) N. d# |8 k) H3 N2 p
}
" r0 v* x _4 @* c6 y. Q: ^ default: . h, f; P% u3 G4 E5 ], m
printf("Bad Input.\n");
$ j: W. |9 L0 q/ S return 0;( ]% M" u* t" V" ]
}
. c6 u r- |" |/ t X- a return result;7 V; L7 y7 P: m/ W. n$ B! _
} * P+ O% O/ c6 B8 r
L- P8 X0 J, M- Rfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/! y, c- z) i- W" |# g8 {) {5 m
{0 g& Z. [4 n7 f) H" Q
Stack optr,opnd;% `# A5 [9 j$ [ b) {. m
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;% g$ R9 G+ x2 z
char c;& M9 }3 i. j2 b
char buf[16];+ ?8 `: M4 A3 |, \* s
int i=0;
4 b0 N0 u+ o% A" v
4 [! M2 |. V4 S InitStack(optr); /*用于寄存运算符*/2 H! `: [; _' b
InitStack(opnd); /*用于寄存操作数和计算结果*/0 E8 b S; f* O o# e
memset(buf,0,sizeof(buf));# l) q/ z+ o1 o/ q! }& k) u) I2 E
, M/ p* A9 @/ R" y5 L
printf("Enter your expression:");
6 C0 d* K3 g! d3 X* V" ?4 ? . q. T, N; n1 J+ a5 Y9 @
opr_in.ch='#';
- K) l; d t: A$ t% P6 | Push(optr,opr_in); /*'#'入栈*/! z A. U" V; w v9 @) _, X
GetTop(optr,opr_top);% k/ I# O; m7 r8 g
c=getchar();
% |4 b- s7 b: E/ B while(c!='='||opr_top.ch!='#')
7 [2 H% }+ y- P {
F9 f" k! i# V! c: Y3 q1 k* \" v if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/6 {- x4 @: h9 n
{
" ^" l" p7 P+ I# R buf=c;6 J& [: n; S! W+ u# k
i++;
2 _+ ?( K" U6 i6 ^* K; b: x c=getchar();; v! R W- K2 _. ]2 \2 Q
}
2 `; c' S* D& T) o: g* m! \ else /*是运算符*/
9 @# I9 R3 G3 U3 L3 G J0 W {
) K9 b2 a: F$ ?4 F( K8 i x& c buf='\0';
% H/ I: K9 ~; d if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
# j! F7 D: D9 _) L {
: f% Z5 P* u+ ]' N$ ?& h% P4 u opn_in.data=(float)atof(buf);
, O+ i" @; a% W. e$ X- p1 j& Q Push(opnd,opn_in);
/ m1 d; {6 L+ p4 M- r printf("opnd入栈:[%f]\n",opn_in.data);
- Y: ?. w# R4 L3 _ i=0;, O6 x I* J* i8 {% |# t
memset(buf,0,sizeof(buf));$ w. }. K7 A7 s) F8 F7 v2 y
}
/ T$ A, Q/ m4 J; U% M6 m# P opr_in.ch=c;
1 V" F7 r4 Y+ [7 T7 r switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
1 m' O% j9 B, z/ n* D/ N6 \' f {
& Q, j6 _# T# y3 a case '<': /*优先级小于栈顶结点,则运算符入栈*/
2 L' D/ l$ Y2 A2 m9 c Push(optr,opr_in);
2 d+ t: s* T- J6 Q7 W, ? printf("optr入栈:[%c]\n",opr_in.ch);6 Y" s3 W: w1 Q9 }; A
c=getchar();% T; P. Y$ \ @( a; b5 m3 G6 r
break;
9 z- {6 {5 d7 H& K+ V case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/, O4 O8 V6 O. y$ ?- k, @
Pop(optr,e);
) V x& W7 w. d0 m- o, W printf("optr出栈:去掉括号\n");. L2 R; C0 ], q; @/ U
c=getchar();
; @* S& ?! J6 F# ^8 V( H' r6 m break;
+ |. [2 X9 _/ j6 w; u% Y2 G, |1 f case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
6 I, f+ j5 ` N |) n$ Y Pop(optr,opr_t);
4 A2 P* Q% M3 `1 X4 L$ z printf("optr出栈:[%c]\n",opr_t.ch);1 d* q* { J0 J; o: a+ c
if(Pop(opnd,b)<0)
1 P, j8 n& Z, `7 J0 i. _ {2 Q5 Z' D- Y+ J c, z \) S
printf("Bad Input!\n");% p5 Y) T- Z( A3 ?
fflush(stdin);
$ m' y, h; W2 S* z6 D8 \8 C0 C return -1;9 B+ [' _7 Y/ ^8 p8 v3 V
}
' V% r# q" i( w; \ printf("opnd出栈:[%f]\n",b.data);
. D1 R# d: p5 s [ if(Pop(opnd,a)<0)
4 V8 D) J3 w( t( r/ C- Y {1 H3 P5 ]+ L6 s0 `: B
printf("Bad Input!\n");$ s; w% O# Q* \& e+ P2 P
fflush(stdin);
& K- x1 _! i" F7 B7 a h4 Q return -1;
, Z, E& w/ h4 [. X. L# T }" w( R2 ?5 X/ }* v0 f) s
printf("opnd出栈:[%f]\n",a.data);
+ x4 J# J6 G, a. w- A opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
6 T6 O. R" |1 ^ Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
$ g: H# @" B! G) M; v5 b" r printf("结果入栈:[%f]\n",opn_tmp.data);
2 u& |5 f3 i! G5 v- g5 ~ break;
_% D1 ^9 ]4 M A# r }. G( C- Q1 w$ T. O) k/ S9 @; m
}
9 A! K1 K- ~. k/ r0 U GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ ; z0 {3 w! B2 \; o
}; M( D0 m+ E9 f( l
GetTop(opnd,opn_tmp);& ^3 q/ d1 |+ C
DestroyStack(optr);# b( `+ P0 P/ T5 ~* S7 O* g7 I( J
DestroyStack(opnd);4 I4 V m5 Q2 q8 Q. `* G' e) T" f% W
return opn_tmp.data;
& z+ r' d. A* Y5 ^! b5 \ M6 p}( v. i3 N5 M( O4 M* E( b- _
0 k i; f$ i8 U! O' }& P" v9 J- `char *killzero(char *res,float result)6 W7 E4 | K' H; p, [; U
{
3 T( {0 d" t7 ~+ U; i" c! e int i;
& O, h7 r4 u \# m7 q7 n% g) Z, [5 W# A
sprintf(res,"%f",result);
( X# e1 p8 r) }; C2 l E, L i=(int)strlen(res)-1;. H6 ?; E9 y0 w
while(i&&res=='0')0 w( q9 w5 T" f- X
{ {& J5 k: q0 U. e2 q
res='\0';. a, u$ ^) V! g) k: z# R
i--;5 v( v3 }: C5 S8 \+ z
}( _ B3 F" Z2 C7 w$ W$ a. ?
if(res=='.')% m8 r" Z+ b; A8 @ z2 I
res='\0';
- l9 R5 T. {. I9 N& O0 n! X N return res;
+ ~; ^, w% R+ [}# P. R, W- `- Q9 g2 t3 k
7 u/ x4 X; @& r, v; G( iint main()
b* e [9 G1 e3 ]; t0 @+ Z6 j{/ l9 r* q4 k* F, z
char ch;
9 E& T9 V2 J8 F. A3 i+ | char res[64];
. }5 U& _$ n m4 g0 a# I/ C6 ] float result;; i! l1 [4 g! v, H
while(1)7 r& }3 x& _7 _6 r `
{
; u) X2 ~" `+ D( l1 i2 }' b result=compute();
2 |$ p- J) g% g6 i9 x$ _+ m printf("\nThe result is:%s\n",killzero(res,result));
3 k6 G! x( k" v. h' D- | printf("Do you want to continue(y/n)?:") ;6 K4 V% r' d: E: r+ J' F9 _
ch=getch();
) W& O, @& j5 a; |4 |: ^# M putchar(ch);
1 J6 S4 F3 y! i6 j- f# `9 x if(ch=='n'||ch=='N')' r K9 @4 q6 b
break;5 t7 J' A% F/ R
else6 H3 S8 E# g) x
system("cls");
, o8 l l3 D7 X" R' O% g }& a3 I6 \( c4 k! f
return 0;
0 Z& v/ S, d( I8 ~+ ^: s A2 V}
% T/ O4 L: T0 c, n% V2 J. a# T9 _, U8 p! \* V* x' S7 p" k( Z
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|