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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
/ _; \' ^' p) k) X+ I$ R程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
, ^+ w$ |# T. N- B" q, d1 J; r/**************表达式计算器************/; [' N7 d+ R& D* r
#include <stdio.h>" T. [5 S5 q K- S
#include <stdlib.h>, d5 m: g2 C- S$ v. B! I" ^1 z
#include <string.h>
# W8 }( Q0 L% v$ v#include <conio.h>
! m( T5 m M' B) M; {% |+ H#include <malloc.h>
: ~6 l% X/ f, _0 ?3 ^4 O8 b r! y, v: B
#define STACK_SIZE 1007 | E* e$ Y, l$ Z
#define APPEND_SIZE 10
' g$ k& W' C% n5 m2 s7 A# e+ F$ H' Z" Q
struct SNode{
$ X2 m5 U9 n* F: z0 `8 o* E+ w float data; /*存放操作数或者计算结果*/4 `, c& g5 Z& n3 S
char ch; /*存放运算符*/: B3 G1 a+ d$ H
};* e. {9 E. i8 a
8 g. m8 M( Y% [# a2 q2 v, Ustruct Stack{
& ?' Y: k b' E: C1 G: ~. ~ SNode *top;
+ p$ a( I. ?1 l SNode *base;
2 K/ n$ V* p4 `& A& M9 K. S, X# }) D int size;
% E' k& H; s4 |& t7 |+ c+ M& P};
2 z& P V/ t9 ^! U# K+ q4 `, w" R6 p" U) e
/*栈操作函数*/
0 b0 p! ?9 D1 J1 Z' w' R: X# ?( Dint InitStack(Stack &S); /*创建栈*/
$ N: Q1 h; |) }8 jint DestroyStack(Stack &S); /*销毁栈*/
9 y% L) j# Y$ O$ nint ClearStack(Stack &S); /*清空栈*/
! Z- }/ @5 M1 zint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/8 d) N0 u* j, B9 U" H
int Push(Stack &S,SNode e); /*将结点e压入栈*/
/ M8 x( m1 f9 G+ N( Q' zint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/# }8 l5 C& ]6 K Q
: b) E/ a5 I' G* w
/*表达式计算器相关函数*/
! W* K/ `/ q9 M O9 ~char get_precede(char s,char c); /*判断运算符s和c的优先级*/
9 S% T; ]/ D+ w$ n2 @3 Rint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
9 C* |- J3 X3 G- O* O% L% Mfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/, y$ O8 A; `( a) l6 ]
float compute(); /*表达式结算器主函数*/
& `" r7 t0 c" N5 ~# ]% q3 o1 qchar *killzero(float result); /*去掉结果后面的0*/ % c8 w! U; N* v8 p9 A2 X% w
+ S, c" o, n: D$ t# K0 n3 ?int InitStack(Stack &S)! {# j* [. Q4 S$ D. A
{
; i/ L# L9 x y" k4 K- O- K4 u7 o1 r S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));5 B/ g8 p! p0 H! J6 P. H; x# g# l
if(S.base==NULL)
% X0 R# e6 J! c( o8 @ {/ Q4 }( J7 |* Y* L1 T
printf("动态分配内存失败!");
) l/ c6 X C7 H return -1;
! I5 O/ z, W6 }0 q8 M7 ^ }" I# N2 f. r8 s
S.top=S.base;! T* }8 g: {3 `# r$ ?" o, T
S.size=STACK_SIZE;+ ~! X5 W e8 m m+ d0 [7 c
return 0;
: a; m9 c5 _+ z0 }2 d9 \1 F}
' e: Q" O. B- k- `* j* i" f g1 h, C" A
int DestroyStack(Stack &S)
; A8 d( w% f: K4 b4 P W& o. x; [{. |, }! b3 \0 ]
free(S.base);8 v8 W/ X: B h
return 0;
# u7 H/ Y4 ~8 @- w/ s}
( x4 @( o4 `6 [) \3 l: M" y; f: _' D: E2 V
int ClearStack(Stack &S): R) l+ p3 A) @$ N6 q& X
{9 x+ b' F1 @& Q( B& h: W. d' x
S.top=S.base;
9 `7 R& ?& B: o0 l" P* a V return 0;
$ P3 `+ |- A; Z7 N}+ ~- c( H: H% u" k# U
: X5 X9 P. K% ?+ a1 [4 j/ fint GetTop(Stack S,SNode &e)
5 |- T- X7 t1 A# K! h! f, t{1 U" X! \& x' G
if(S.top==S.base)
7 s9 O1 [+ {( A2 X7 W( G6 V {: q+ a7 P- v% \: z$ e( E A
printf("栈以为空!");
3 l5 I) O( f X( u( p& l5 h return -1;/ S' `5 U8 n; o8 h9 B. X$ p
}
) R @1 @* {( y# `% s e=*(S.top-1);
( X. b' Y* d0 O6 W4 B6 ] return 0;. W( y" r5 H3 c
}7 ]2 Z/ ~2 j( T3 q, C
) n4 C/ X" U" l# f* Hint Push(Stack &S,SNode e)
! K& i2 q9 y6 w1 `( [{
# _' }: X3 T* d& A, B) S4 p if(S.top-S.base>=S.size); [' z. D. ~) [% a) J
{' d- E# @) T9 i+ M) B% D2 D0 D
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
5 |' |4 M1 [; L' w ~2 @1 ^ if(S.base==NULL)8 E V- i1 p: y2 Z# K+ W8 o6 O' M7 c
{& [# e' g5 o7 V) U1 i
printf("动态分配内存失败!");
( t$ |* M/ Z, j4 Z" Q, ~( N return -1;& H. B+ k0 ]+ _) u
}
5 R& ~5 @, x4 T- V' {# l S.top=S.base+S.size;
& W) F5 i; Z) Q9 h# f: K S.size+=APPEND_SIZE;
# n4 U$ E3 Z5 b+ f }
4 Z' L6 r: o& }& I0 M7 c' p9 F7 h1 e { *S.top=e;0 j' L8 R( v9 ]: z9 h
S.top++;
) K$ F- S* S/ g& ` return 0;
2 J/ d/ ]6 X! {7 |8 K6 W}
( _: j. [3 D( g* p( w' K5 h( L
* E2 R$ P7 i7 E0 `int Pop(Stack &S,SNode &e)* s, V) R% g! D5 n3 r- ?
{) F# H( u F& L! L9 y) U2 O
if(S.top==S.base)& ]5 y5 ]( ~- Z$ V" Z
{
$ t: f: a6 Z- o+ U. f+ Z/ p3 j printf("栈为空!");4 A7 E* \. W6 D8 ]0 U( d8 y1 f: e
return -1;
4 a; u# w) M" r/ G$ Z, W) c: s! Y8 {0 a }
0 z3 M$ g: O4 }/ N, A0 z e=*(S.top-1);
4 E; n0 H& Z# f) i: I( H- { S.top--;
; |; J- ^7 o3 _" Z5 V$ w9 ] return 0;: H% u1 t% Q/ A9 e
}! i! d' H/ a; r% b8 f) I
1 d0 C3 Y2 |1 A6 J# d8 Z$ tchar get_precede(char s,char c)
4 _" T. E( M8 {7 E0 n1 I4 b: R( N{# b4 H' ]. _* W8 g. V! s, t4 G* M
switch(s)
J% G# ]: ^7 V {. d% `9 P$ _) c5 e
case '+': / Z; s) G2 r& G* M( D' \
case '-':
# {% [$ q U) z8 P& q) I& w- H) M if(c=='+'||c=='-')7 C. @( c( Z u+ e4 [( U
return '>';
+ p5 ^: B$ J/ u6 Z else if(c=='*'||c=='/')
1 N. w" u9 D, L6 L+ i( R9 P return '<';9 F4 z* i4 d6 D
else if(c=='(')
) ]7 I8 C& ?8 A' y% _, z/ H return '<';% l. `7 m! Y8 @0 y5 d8 |8 ?
else if(c==')')9 N6 t5 X' H: X; x
return '>';6 j9 g& w! O/ O( `# N
else & C1 s7 ]# _! P: ?+ D; e9 B6 G
return '>';3 a- o+ l8 b& a6 K; f( P% ?
case '*':" ?& X, p6 l( Q- O/ o0 G$ P
case '/':: ^3 P+ Q! j( M
if(c=='+'||c=='-')# R- I, I2 Y0 _
return '>';% H( q' f9 F. {; C5 U: _
else if(c=='*'||c=='/')' [! u) a/ e0 ^( I: ~6 n
return '>';( F* F! |. p& e* F2 b( O
else if(c=='(')
) R% s5 a9 i5 h a+ P+ y; }) C return '<';
: f8 C1 M- L2 I5 Y9 B; W1 X3 } else if(c==')')
6 Z- W- {% H( m5 p. ? return '>';% j0 H4 T3 O5 D+ B" y
else- ]. U3 t1 o& Z( U1 X, z+ F, |
return '>';- M) H3 A# Y9 M- T- w
case '(':
) N8 O9 A3 D& ~! @/ G' S8 E if(c=='+'||c=='-')
g Q# L. ~* M' w6 o return '<';( y: o+ x& _+ V0 n& z, Z+ b( P+ A
else if(c=='*'||c=='/')
" u8 E! v8 K! S3 L* ? return '<';
) a* O+ b2 k. @9 v" X( Y* p7 F& s else if(c=='(')
# F; j) A1 Z! ? x) S% A( @ return '<';6 x$ y& U4 ? U1 i8 B
else if(c==')'), b) K" r% b" {
return '=';. V, W5 l8 n1 c$ G
else6 U- ~- q9 } F1 w2 U
return 'E';
% j1 m' v/ p8 y7 a* x* w0 v case ')':
& M* F% _; @) [4 [6 G( @6 n if(c=='+'||c=='-')
* Q3 @4 W* \; W# w: u$ Q: |/ U return '>';+ y2 }6 ?: h; Y, z5 n( _: }9 K- v
else if(c=='*'||c=='/')
) A$ I% p$ h" g% e2 l return '>'; A0 h: j6 K" K8 J% O
else if(c=='(')' I9 J: k- g$ `4 V+ y' z; Z$ m
return 'E';
* G; q3 V: i% b' i! b! T' x# S2 Z else if(c==')')
! O1 ^1 ^7 [6 V | J) C return '>';1 j4 o. G1 d$ ^ A8 }) A9 a
else
" Q$ N7 T( Q- ], q return '>';. \& v% e" M! Z3 P6 m- [& _9 F4 {5 a o
case '#':
3 f! Y+ i/ l. T+ I( R5 K, y8 A. L if(c=='+'||c=='-')
. f# s9 t( e! r6 Q2 `) J8 Q2 N return '<';
3 W8 w( }6 ^7 D7 v else if(c=='*'||c=='/')0 v/ x% B, z" x5 p- D
return '<';% i5 |4 `- l' X2 {& S) G, ]
else if(c=='('). }* z$ q- r5 ^0 e- \
return '<';
4 i& H( y! p# x5 w6 U$ Q! u else if(c==')')
U7 \8 @1 M4 G" t return 'E';# Z" L8 ~% D; ]5 c/ ^0 x* D8 f$ p4 q
else& Z- E0 o, c4 K& Z8 _) R
return '=';) O8 f' n" j6 h5 W' z
default:
5 j+ H+ L* V8 D+ a; y, o break;
O! @( d: i' F5 q% x }% \: \( N, ^4 y( |4 I: O
return 0; ! i; h2 I4 V6 B) M2 T! H
}
6 w$ R6 I e) @) v% _7 m5 Z% V6 t- n2 p' U2 Z3 e t' x
int isOpr(char c)& b# f6 `& O! {, i. r) ` T m
{
& f J; Z# `/ z) I7 k- z- H! p if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')" B) [2 n4 M! |* M' u
return 0;9 N$ p7 R/ Q( o7 t! i; Q% I1 |
else
0 M2 q) O8 u. X5 M* ? return 1;8 G% P* ^8 K$ w. `
}
, r& y4 K' F6 q9 J8 a1 N6 j& M) {2 K& t! T1 z
float operate(float x, char opr, float y)
2 ~ i# f# n+ w{! Z$ P* v. \6 Z1 }( S/ l
float result;' ?9 m) K6 |: G W; \( H7 o: K
switch (opr); T( K% Q0 O- i% t* s- {
{
7 M2 w' H: J. Z case '+': 0 J2 X' x: F/ F+ G I
result = x + y;( v& }+ ?' N1 s4 J
break;$ @1 b: T4 I/ v& v+ C9 d
case '-': 7 N% n' [1 d3 s3 M& b
result = x - y;* z+ i$ B5 t7 ?$ M% A' W1 M
break;5 g, L. d# |4 @ `0 @* W4 f. b8 r/ ]2 p
case '*': 0 o" S# x' G, P% ^& N. \3 N! B3 J
result = x * y;' n! X7 M# J* `% w
break;
2 @: r" j% k3 ^ ^7 X* S. j0 ^1 S case '/':
+ W \3 t8 ~+ y& S" k1 M if (y == 0)
2 q$ A: ]8 z P3 F {
6 f7 t) b7 ~0 Q, z3 M printf("Divided by zero!\n");
# m; X' q% f4 \ return 0;
" r' N1 x3 A9 D }( k5 k5 ^; t5 B/ }
else2 ^1 a8 J, X/ M: R5 @* K. a8 w
{8 A1 x: k1 ~- j1 M+ z/ i- t% p
result = x / y;4 x0 w2 e8 U0 Y5 p6 e+ Z
break;( p" Y1 I8 J2 G2 K/ V2 B" d+ ] ~
}3 `9 w1 ^0 @! S) K6 s! ~
default:
) u8 d& K% N# g; _6 d' ^ printf("Bad Input.\n");
9 Q ]; S. b( l3 z# D! y6 d return 0;1 ?# P& w& }0 L( p& U' j
}
/ M+ P+ A3 z& T" u0 l return result; o+ z8 ?" R, O
} # f. B% U4 q6 ?- i
1 y! L: t: W0 }+ E8 ^ _
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/# ]. S- [' {: l6 Z! a
{7 U' t$ H, I6 m- E
Stack optr,opnd;
. ?; w0 J7 {8 l8 X7 `) G struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
, v! s9 i6 D: l8 u, ?2 Z char c;. P0 R$ {+ R& j9 Y6 [( E
char buf[16];7 n6 H4 X+ G8 k
int i=0;
6 A: o; n$ ^! Q 3 W, u! u9 k# W' ^* m
InitStack(optr); /*用于寄存运算符*/& d( A( D& G, Y; H! b
InitStack(opnd); /*用于寄存操作数和计算结果*/
* ?: J1 {% i" z memset(buf,0,sizeof(buf));
1 `, X$ [$ k/ g% l$ k6 Q ( E3 B3 @9 T1 }; Z1 Y8 L! t$ }& B
printf("Enter your expression:");
7 `; C! c- B9 k& @/ y/ | ( S+ D. t! \3 n
opr_in.ch='#';9 a$ @3 J: d- N5 m$ U9 ]
Push(optr,opr_in); /*'#'入栈*/
; I# p; R" R* ^3 D k GetTop(optr,opr_top);
( b) A9 L' q5 L, V c=getchar();
0 o) Q- S% {* }* ]- ` while(c!='='||opr_top.ch!='#')
9 R2 X( S- k5 ~0 e {
- z- |' T V6 m5 l% R. Y- { if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
4 v/ b( I% A. v {3 C3 p/ C7 W, L, @. Z' a/ N
buf=c;, |) i. l: W( X8 N4 X1 ]
i++;/ K/ c% Z& F7 o3 _- e: @0 P
c=getchar();2 i) p5 L! D: U! n7 [% H
}! r: _; V8 k% g+ A4 l! O+ k
else /*是运算符*/
! ?7 B5 c% F$ g( Q# N {
5 \& t+ A( |% q: p6 A" N5 }1 ~ buf='\0';
7 k3 @+ a: ~# k8 E, `% Z if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
- i; p5 d7 y- I3 t& Y- } {$ c0 i, C# Y, q* j
opn_in.data=(float)atof(buf);
- J0 ~4 F9 O& q) M6 O! F( } Push(opnd,opn_in);
; r3 y* }# _, G2 V printf("opnd入栈:[%f]\n",opn_in.data);
1 {: L: v6 a E4 Q0 r0 `6 S5 t i=0;
" I0 A! G& o, S' |9 s+ M memset(buf,0,sizeof(buf));: ?$ u% Q9 v) Z. o0 F+ Q% q) I
}
" I9 x3 n/ w- q/ p; G! f' o9 k2 n opr_in.ch=c;3 g5 y% w; v4 Y3 w% Z6 H
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/* z: W* J$ l& r0 y1 }, v" Q* q
{
& s) P8 Q3 h0 U9 D7 y/ P3 Q) F, ]3 C case '<': /*优先级小于栈顶结点,则运算符入栈*/7 d! e* _7 O1 ^( g/ Z- n
Push(optr,opr_in);
$ V1 T' M) g7 I( N1 t printf("optr入栈:[%c]\n",opr_in.ch);3 b9 m) \* g: |5 b0 }4 `5 v' b
c=getchar();/ v) B: q6 |8 ^" P6 x- a
break;! k+ I# C( {- a6 L4 g
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/5 X3 ?5 |3 z: q/ E% l; n
Pop(optr,e);
/ O% A5 o7 `# H. t; f3 G printf("optr出栈:去掉括号\n");
* X$ j& f: }, O% ?* D c=getchar();
9 u$ s. N3 U. c break;
$ d+ _9 k; t4 U9 ]: u1 x. y9 o6 ~- } case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/1 b2 h O* c ^- t8 S% \9 ^, w, Q
Pop(optr,opr_t);
0 ]% q7 z5 u8 J" d4 Q$ V printf("optr出栈:[%c]\n",opr_t.ch);; u- k' D y; z( b/ Y' o
if(Pop(opnd,b)<0)3 K: ]) C7 G1 F
{8 @4 O; l6 A/ ~& j
printf("Bad Input!\n");
_1 P% ^/ D- B( m6 i& ^ fflush(stdin);
0 O. Y& L/ j( w# q' x: u return -1;" @& ^4 C9 w& J5 u2 c3 {
}' v$ t; k, E1 e- Z
printf("opnd出栈:[%f]\n",b.data);
" s6 O6 C: n4 i# p: C8 [ if(Pop(opnd,a)<0)
P7 X2 n* N6 p {8 c2 g% j+ w% A% m5 z
printf("Bad Input!\n");0 Q7 Z' u' P1 N- D T9 D
fflush(stdin);
* x6 a$ Z8 _$ r; A& ? return -1;
/ w6 ^ h+ |- v }" j( N8 A, _5 f: ~
printf("opnd出栈:[%f]\n",a.data);- m3 W. m* b9 ^/ t- A& i3 ^4 r
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
) g9 u. d2 v% v5 g7 W* A; a% ^ Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
( q/ U2 Y7 j! ^# Y: p. u printf("结果入栈:[%f]\n",opn_tmp.data);6 a1 p- @+ Y: _. o6 V
break;" B+ j& I' }- Q3 N( y; A! @7 g
}* O( v4 |# N% H
}
3 U$ X- E# A2 I M, N: W3 o GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
. a% O9 D& I7 w) {! G% N }
% A$ z7 W# o" l2 J3 f9 @2 H GetTop(opnd,opn_tmp);
) l0 |* N, N- P( }% z- J6 o DestroyStack(optr);* i2 D3 {! [# K+ [
DestroyStack(opnd);
* e* n" n+ O6 M' H: `. s return opn_tmp.data;
8 l/ g0 m: {7 n$ K}: j: w O& L9 t6 K7 u, n
1 a* y% z A6 c( I7 y" _& e# Dchar *killzero(char *res,float result)
4 H) i1 Y3 m, y$ Y l5 o0 N{1 ~# W2 Z, e4 K( z* A4 n* y/ r7 ~
int i;
3 T0 P$ z! R: C
6 }5 a5 {& }7 i* C# a- H sprintf(res,"%f",result);
9 E% o+ x9 f2 m% H3 C i=(int)strlen(res)-1;( ^: w+ X7 \0 o: W
while(i&&res=='0')
$ i: e( V0 O! e {+ F! X) M5 E; ^! c% c! U# ?8 A: T5 e# t
res='\0';5 H" [5 J* M9 N0 ` |8 Z
i--;' C: O, N$ |$ ~1 y7 w
}# `7 s$ B8 ]- @, g
if(res=='.'); `& y+ Z. F/ [
res='\0';
6 p* W- O3 u; D4 z return res;1 w3 }. L* E4 O- C& W5 C( @
}
) [4 ~5 l% H( @+ s" @9 \" q. x+ D. G4 }! U* P
int main()
9 K- q3 J* C! b/ a: x8 a, V& w{
: [; W9 ]0 {0 j; Z char ch;& {6 `: ]0 c* h N
char res[64];7 M' I h& L# a8 V4 Q) H* c7 W
float result;0 H4 f/ h0 B: M8 L/ E# P
while(1)
; `( u% M0 g3 Z& A: t _1 N {! f; [ F/ L% i' {% E1 z
result=compute();9 G0 r; i: S) ?- o
printf("\nThe result is:%s\n",killzero(res,result));
$ T! X. L( Z& |: l% q- Q1 ^ printf("Do you want to continue(y/n)?:") ;! ^; s& H, \8 A/ W3 ?/ T
ch=getch();1 ^4 t7 E" l! p. l# Q+ s
putchar(ch);6 T' m( w7 H! t8 {
if(ch=='n'||ch=='N')
& v- l. H i! F' k# ^5 @ break;) P/ R1 J0 K! r
else3 v9 L/ \0 N9 B/ K% l5 l
system("cls");
d( h( W! }9 C1 i }9 r8 |% U6 V: ]5 O& @& N
return 0;
9 o) `" C" Z( C4 l}
& A9 z" s3 ^3 r# G. s: A* M7 y/ i' U6 z
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|