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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
5 M" C2 _ W) e, T; ]& _程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
5 j) Q' h3 S* x$ U9 [/**************表达式计算器************/$ J5 q. A( U2 l# [; l+ }
#include <stdio.h>9 w) G1 R' i% S0 ?
#include <stdlib.h>
( X. _6 A: o, I6 u! X& _#include <string.h>; Q' H3 t9 D9 M4 O9 S- Y
#include <conio.h>
: Y" _) {: n4 h0 T0 d#include <malloc.h>
* \, a Z4 _. A3 G# h1 d* W* Q" y/ d
#define STACK_SIZE 100" J' G6 \1 \3 g1 i
#define APPEND_SIZE 10
' y" i/ N! K: a6 t5 m
* D2 y! X k+ l, `struct SNode{" O6 m* ^9 k' O: l0 m
float data; /*存放操作数或者计算结果*/8 M; U3 J) @' t- @9 `# z4 ]
char ch; /*存放运算符*/
! \2 W9 {, @! o/ }$ U* B6 _};
, d+ R& e% E) H; m5 t, D/ B
: s% A( G! _7 D, F% g% s/ G6 b8 k9 X( \struct Stack{5 I3 ]1 u! l4 A/ f! Y
SNode *top;
! K2 A5 o" a1 V5 ~! r s' w SNode *base;
# a- i% h& X- w% f: v! [ int size;% f6 ^" j3 j8 _! W8 R1 ?0 ^
};, P4 d' B- i8 U7 G% E
# j# N' C# k4 Z8 L/*栈操作函数*/ z; B2 c! {7 \
int InitStack(Stack &S); /*创建栈*/4 {7 }6 T3 X; ^6 D0 Q2 c! d/ Z; v
int DestroyStack(Stack &S); /*销毁栈*/- b8 z5 e5 ~4 o
int ClearStack(Stack &S); /*清空栈*/
( w {2 E6 V: {9 R2 I# ]& D- fint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
* Z' A1 Z( U* n5 {" L3 n$ dint Push(Stack &S,SNode e); /*将结点e压入栈*/
2 ^$ A" j# m+ q$ iint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/+ G! d5 c0 {- E1 G. p
2 j+ F5 [6 M+ K. z: o$ i0 d/*表达式计算器相关函数*/$ H; S Q8 g* k$ X
char get_precede(char s,char c); /*判断运算符s和c的优先级*/( ]! R$ b0 j2 s/ P2 s# Y
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
' D# O1 X: X8 k6 i: P) Pfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/: L$ ?! L1 ~8 ^6 q
float compute(); /*表达式结算器主函数*/2 J) p: [) k% m9 H! B& L
char *killzero(float result); /*去掉结果后面的0*/ ) [- Z) d9 F8 v3 v- ^
! D$ K4 D3 V5 n
int InitStack(Stack &S)
/ j; _. E8 Y) {{
* ?3 m6 t. S. U: {% A S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));' l ?7 Y3 D0 ?6 x
if(S.base==NULL)/ }9 M" F0 Y8 x8 `: P
{
9 ?2 m7 a7 x; v5 w7 t( i7 } printf("动态分配内存失败!");
! Z! Z% L* u9 j/ \5 [+ x return -1;+ W* k1 S% v# T2 @" W- F
}
1 ]! t$ F+ c% d+ K0 S S.top=S.base;
$ i9 [# _" {0 m' R& C S.size=STACK_SIZE;3 M% L% e' `+ ?/ Y0 V+ b' b2 s4 x
return 0;
* S0 F- M0 }: C9 z$ L}
* A- \/ L) d# s4 G' B) G) \% x9 m
int DestroyStack(Stack &S)
% _: e$ H; V2 B) F2 k8 }3 h% x{
. J, r; K& ^3 J% C# B) Q free(S.base);8 U; @3 Y. T% `! E. z6 [
return 0;6 V0 r4 U, l5 \
}6 ?! K- ^4 `# e0 Q' i6 K
$ m+ ^7 ^2 c% _* `int ClearStack(Stack &S). ~. P1 v7 l( s; W: w C; U, e+ ?
{; d X& m+ k& H8 l! R: b! d% v
S.top=S.base;
F% ]- ~/ O" l2 L. v& I return 0;6 D! s- L c+ ~) K; w: q4 Z
}
# K# ?2 F: ` c7 k& E- q# |# {
, l! N- J7 r/ p% W1 Z I- rint GetTop(Stack S,SNode &e)( q* s5 m, ?: r" l
{
8 m9 R$ U R1 S* [* m! }" o. k if(S.top==S.base): H2 l3 T* n3 D) {
{
7 c0 K$ U) S7 ~* T, l; Y3 W printf("栈以为空!");
# M. X# J1 r4 N3 k. l return -1;. e5 ^( b1 ^+ k
}
/ C1 k6 y* ~4 U5 `* O# p7 z) f e=*(S.top-1);) n# P0 n; a- `9 {+ |+ k8 j; z, L' @
return 0;
4 M7 {4 Y' q( r8 q. I}
. D/ R6 H- l) j& \5 Q# N6 [7 X/ S3 R. {7 {7 G* \: ^( R* T
int Push(Stack &S,SNode e)
' o; ~% [& b9 W/ d; u! L{
5 E' b2 {* K3 n2 m) j if(S.top-S.base>=S.size)! C7 W- c; H/ N8 ?6 d, C1 X) i
{
+ q% ^4 n, r0 d6 | S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));/ I3 ^4 c$ @/ m3 t" k+ I5 J- n; m
if(S.base==NULL)
o+ |- q/ j* S5 U1 V3 x {% f9 F4 |. ? V$ i* I v+ a( Y
printf("动态分配内存失败!");# l# o- f# L' E" i3 g
return -1;: I# g* A. _3 i9 r' b0 I
}% L9 }/ z/ F p
S.top=S.base+S.size;2 m% t1 O" {1 ^* ^: v" J
S.size+=APPEND_SIZE;8 f5 K( L7 V* w6 {0 G* H' D
}
0 K- g, G8 |) C *S.top=e;! O4 h; I' \5 c9 n+ n- i
S.top++;
7 T2 s1 K, x* t& T! @7 i- W F return 0;9 [/ b8 a- q% f, V2 H; D; b
}' c3 w' q# a* v2 H
# R$ @4 l+ D$ X6 a4 Tint Pop(Stack &S,SNode &e)& o7 j9 c( K0 c! w$ x" o
{
- {! m# S# Z2 P/ f$ @5 p if(S.top==S.base)- g4 y" h+ Z) ~ `+ }
{
; `2 i% k+ L5 ^ printf("栈为空!");0 Z6 S( Q1 a, e5 r9 m8 v* |5 ?4 `( z
return -1;) Y0 L" D. S+ F5 M
}. O" m; O4 ^1 }8 O
e=*(S.top-1);
+ d7 e( K6 R9 F- r" Z S.top--;( i' ?. j( j% [1 ]: R1 d
return 0;
3 t3 N: F, M. }# O}% k) ~- G I1 W8 i
~! Y) T' E6 J4 ~char get_precede(char s,char c), ]2 U, @0 K) B$ b4 V2 q
{
# x9 M. Y( d+ y9 R j0 Y w switch(s)" N, F; R7 ~# j% Z
{
& ~0 [& R9 {5 z) w' v" q case '+': - ?; y) g" l8 t$ n
case '-':8 @( J" v: W: Z8 H
if(c=='+'||c=='-')
! z: _: ~ H* g3 s! ~! a# ^ return '>';. ?" K/ C+ f$ x" E0 g
else if(c=='*'||c=='/')
8 V3 M% ]. ?! _$ H4 J return '<';- n# V! m) S- y& D \
else if(c=='(')
+ r; x9 M8 o: `7 O8 U, B7 K! U$ A! S return '<';
6 |6 W; ]% F C, ~: w' Q else if(c==')')) D8 \) K2 W S3 Q
return '>';
$ L& g( ~0 F$ v0 m1 G/ P else
+ J0 V" |) D" Y$ W1 e$ F' G return '>';1 B8 `9 V, F5 M1 Z/ Q
case '*':
4 z+ B C! z5 ?2 W6 z case '/':
b2 w: h$ H) t3 w" Q if(c=='+'||c=='-')3 G. O. m3 b. J
return '>';
T- @, S% ]3 g9 i( ? else if(c=='*'||c=='/')
5 F, u- x1 K1 i7 @; X6 f: P return '>';
7 E+ f; {7 j. t* n- H else if(c=='(')1 r: q6 H2 f1 ?# g, o2 V
return '<';- z+ T8 i$ R/ ^
else if(c==')')
$ [# U3 C! _( ?6 x8 c/ @ return '>';
- O% O2 F0 p+ q+ ~4 v; V" t else+ x9 ?) D1 i: }8 \- d% U. U. K$ ]
return '>';/ B) g- A- ]3 h- Z1 p
case '(':
0 g$ h3 Y( D( \; E# Y" Z if(c=='+'||c=='-')% K1 U* Q1 r# J( ~% D' e/ R S/ O' x
return '<';% r9 t4 L* F: Z. C
else if(c=='*'||c=='/')
3 C; M6 s2 ?1 r7 F return '<';6 j/ N7 ] q! I1 L# F( R
else if(c=='(')' X7 A. t9 j; q( S: j. E3 W& o
return '<';
% Y- M* O0 z$ w2 ^7 ?+ \& {' R else if(c==')')
) R) O& l7 g7 H8 _6 z: E return '=';
% g" c$ B" Z; {; b& M else
3 `. S' v2 v. b( ?0 C return 'E';8 j0 J# ~* k: \
case ')':
( K; u: v+ E# O. p9 c: ~ if(c=='+'||c=='-')
* w/ _0 O' u1 ~& Z* ?6 ~3 [: w return '>';
$ z- L9 ]- z- H/ B p3 B% J else if(c=='*'||c=='/')
, E. _, v& B# G; b: r return '>';8 s! }8 \4 b; D; R" E# m7 o
else if(c=='(')9 g! O1 t7 A$ [ y7 e
return 'E';
# M O5 R: T' [ else if(c==')')6 Q& g7 a" R& T7 l7 l8 {( j: ]
return '>';7 R+ I/ {2 A* }% b. W/ K
else
4 O# _& `- P0 A$ V5 @ return '>';" q( D% P0 `7 ~; n
case '#':
/ G X; u; T" Y. {2 h9 b- C. B if(c=='+'||c=='-')
8 _# w5 |$ q2 j- w2 g V7 P return '<'; D: x6 d3 B& K# w
else if(c=='*'||c=='/')$ H0 m2 _9 w6 w5 ?- K& C8 k
return '<';7 g2 W8 H# L- f2 y U1 Z/ u* T
else if(c=='(')( Q6 i: b8 B' Z! N1 }
return '<';- q5 M# n5 q: Q+ M; N
else if(c==')')
! ^- J1 ?+ ]; d return 'E';
8 G# |8 c( `" X8 P) U* N else
& I0 s% n/ P4 Q' Q" Z$ O# v% F return '=';
8 ]0 {7 P5 D/ c( C# F2 P$ u2 D default:
; u A' g7 h, r: P3 u break;
8 \, o, _: s6 Q( }3 d }
' w- P8 N$ t4 u return 0;
1 t; n; _. y, R6 @5 R* ^}
- R! U5 ?% {1 A: G/ r2 ]/ ?: Y5 P/ w S2 k' I+ Q, _. g# I, z J
int isOpr(char c)# A9 H# r6 g. `% b) N0 _# T/ E
{
@9 H% v1 \% L9 U) x if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
4 \8 m5 l ?" U4 w( r return 0;
3 U, B/ `1 P+ I# u# f% Z/ w2 J1 p9 \ else 8 F4 U/ p9 I4 B/ J$ }$ T
return 1;
; z# w/ h7 D, d0 l}
% f7 S5 R) P0 B: F
2 ]" a* E- G% u5 U# N+ kfloat operate(float x, char opr, float y)
, d( F6 S# M; F% J{3 D8 x" K" U5 X" n* A
float result;4 A' {3 R9 b. l- B1 f
switch (opr)
6 j/ {" E/ D7 ~ {
8 p i2 j" ?( V3 I4 N2 e" p case '+':
+ X0 R$ k# w# G# h @( h& Z1 g result = x + y;, _" k6 B5 s/ m$ y
break;
, _ R$ ?+ K( p6 I case '-':
5 C! W2 g$ ~7 l6 B+ _. v" C result = x - y;9 a( @# b! f5 p" t
break;
8 a' [+ q: @- `% a9 R4 i case '*':
6 h1 p* ?# P- O6 T! ^5 v result = x * y;
/ ?* z8 B9 ^- k# F8 s/ g* Y$ p break;- j3 M) \2 ]1 }/ @
case '/': $ @" A. _( q1 e' |/ `7 S6 ?
if (y == 0)+ g- k$ m, H" }& j6 _, y3 Y* B+ H
{
) F% E! X: u9 j+ p$ E# _" o% j printf("Divided by zero!\n");# A* v6 V2 s: x8 r: e$ O
return 0;9 x. K) [7 `+ D% O7 \" `) L4 |( I6 V' D
}
# `+ l) ?% h3 U8 n7 q7 }3 l* z- u else
N* u4 z5 y/ d: @- p {
/ w4 W7 c) ]! I$ [" q8 t result = x / y;
% V0 k6 e9 W; a2 @4 L. k/ g' v b% L* I break;- W9 N, b6 b* z; e; v
}
6 c6 v( |5 r, f! C r% Y5 ~$ @1 I default:
( E. G1 j: r! F1 N+ e$ Q9 o printf("Bad Input.\n"); ' v! X* b2 y2 A c9 H
return 0;
. C" M6 \$ h2 V5 } }8 N" S3 f7 [ b- D8 y8 N. j. n
return result;" z9 D2 `$ J$ Y+ Q6 _& \
} . D1 g( g, e5 s- [2 j2 X& i
5 f7 E3 g5 ^2 Q2 t- o A2 L( `
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/) `) L" p; n& u8 i2 {# c
{
; Q; j: c" Y& n2 s/ R* {& M. p J% f# m Stack optr,opnd;
8 W+ A# ?1 |7 Q+ s struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;/ `/ l( ^* H& L+ i
char c;; Q3 Q0 D% A2 {8 f, F
char buf[16];. f, y( _2 @- ~2 A0 W& |
int i=0;, X" I P7 m+ Y- T) p7 W0 b
* W1 {; T( d8 _. n
InitStack(optr); /*用于寄存运算符*/( T& w/ @( R% }2 @
InitStack(opnd); /*用于寄存操作数和计算结果*/9 m, w' h( w3 \, g
memset(buf,0,sizeof(buf));% O1 E( R7 K/ u$ P+ K+ D
4 N4 \5 y' M" d L, E printf("Enter your expression:");
5 U* F) P( U' ~2 T1 o+ D 0 U9 G+ y$ U' |/ L6 J
opr_in.ch='#';! q: T& o% a6 q$ Z
Push(optr,opr_in); /*'#'入栈*// e/ b; g) W6 d
GetTop(optr,opr_top);
: L6 k( {8 s! @ c=getchar();
) @! T) m: J" j$ N1 ]- n8 h6 ] while(c!='='||opr_top.ch!='#')
2 V v+ s2 w6 c% S; `4 { {
4 `3 {) [; b3 h* J0 N if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/* t$ a/ k R9 }5 @6 g, q& K
{! o& c1 o8 I2 n8 ?* F- U$ p
buf=c;" B5 t: P" Z8 K' s. ^. \
i++;. S1 V3 J# i. F% m0 m" n6 a# q+ a9 Z
c=getchar();' U! K! f* Y. e$ b7 z% m
}/ y- z5 a* s4 U
else /*是运算符*/+ [! h; u6 e. F, s& B3 q
{
, \' u) S, S3 O6 T5 ?: F8 o: d8 y buf='\0';
' J1 O" N! |- R3 B! ^. N if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
- f4 b, E. ^4 R7 ^ g1 {7 n {
$ H" {' Q2 w3 p3 V1 X opn_in.data=(float)atof(buf);
+ b7 d+ u- M' Z, A/ g8 a% v Push(opnd,opn_in);
6 N1 z1 ?2 f8 i6 p5 Q printf("opnd入栈:[%f]\n",opn_in.data);: r* ]! k6 E- |# z3 k
i=0;5 V. {( z0 P1 \. y/ c
memset(buf,0,sizeof(buf));; g2 B6 y4 m% a) C; s7 c( ` {* x
}! y! N6 ?! k& L6 K0 H
opr_in.ch=c;
. K' T% z- y/ h: [. r" B switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/9 X: ]. W. f$ T6 T
{0 J# l. X( ]6 ^5 n$ `6 }
case '<': /*优先级小于栈顶结点,则运算符入栈*/% |9 h6 F4 o7 |1 X: ^, L
Push(optr,opr_in);
6 t+ D/ ^ u) E% k$ N printf("optr入栈:[%c]\n",opr_in.ch);
6 Y( y9 r5 O. h+ n; V4 F c=getchar();% U+ f/ P! \$ U- B& e' |4 Q
break;
$ p4 F) A& l, S) l! Z- j/ e+ h ~ case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/- Q8 l' Q0 c% G5 x* L
Pop(optr,e);
- q' T/ W1 \9 n$ c printf("optr出栈:去掉括号\n");
3 @5 R* n9 ^+ e, J7 M( @6 E$ P) Q c=getchar();" F- i: H Q- W/ n5 |8 K% |1 N2 l3 Z
break;
9 ]! |3 b1 B& k7 [1 @6 [' Q' H case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/4 d: B$ m9 ^0 j# U
Pop(optr,opr_t);0 H& G* [/ X, w
printf("optr出栈:[%c]\n",opr_t.ch);: b8 I6 O- p+ `9 w1 H S) H
if(Pop(opnd,b)<0)* d: C l, a# |6 h" g' s
{
0 w$ M) |1 v* }; d9 g1 T. p" ~2 H printf("Bad Input!\n");
$ c; ?) d7 m& P( c8 D fflush(stdin);% y- x ]5 M- }- ?: M7 l
return -1;6 m" o* V: J; \/ s# @8 k; X
}
: v# N; z# s7 s# Y printf("opnd出栈:[%f]\n",b.data);$ ^: L' B, x$ a) c1 W7 J' L
if(Pop(opnd,a)<0)
J5 ], D f+ d1 c/ L {
$ N) {$ W# \7 ]0 Q printf("Bad Input!\n");: M7 r" \, j$ x" K
fflush(stdin);
# W" ~! \7 R y+ U& j: j& a" w7 n return -1;
/ g7 t4 Q& x/ v7 w: e2 s$ Y }8 U2 ]( [. j3 p0 U
printf("opnd出栈:[%f]\n",a.data);/ f- ^5 @8 D/ e
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/7 K' A7 E. Z, `* v
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/1 ]1 [% J7 u1 u) R
printf("结果入栈:[%f]\n",opn_tmp.data);, B. q6 h' `0 \, n* s
break;; L( [ e/ ?9 C* ]' X4 q
}
: @6 h6 }, o3 S; Z) s7 K }
( a$ N; m2 a J7 j Z) @2 V GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 0 [# D( @2 m. Q( _' l1 }5 c, J( c1 c
}1 [0 X- B" O! g( c0 p' j, g
GetTop(opnd,opn_tmp);% K" K) O$ r- y$ M; c+ L- u
DestroyStack(optr);, Q& t+ D& U4 P4 j% I) t( v
DestroyStack(opnd);
. J) I# \9 ^& z% e return opn_tmp.data;
% w: B: H7 o+ ~7 I# @" j6 L}3 e8 m- @& T1 U+ S6 J8 e
/ E# W* k: X H
char *killzero(char *res,float result)7 {/ K) N% s+ r# ^
{/ U- D0 O8 J. I& A' p
int i;
/ g4 H4 y' W+ w" M+ g P6 b( A8 M$ J! ~+ L5 E
sprintf(res,"%f",result);
4 x1 d- h* {0 j* O8 N i=(int)strlen(res)-1;
5 y% ]. Q( t- [0 g8 u while(i&&res=='0')" L: j% s& Z/ Z( W# u* A
{. |: \ [1 Q/ ~' Q3 T3 X+ Q
res='\0';# W0 A* K* T2 G9 m! f
i--;
}; m+ @6 w" S# Q/ s }
4 E! x$ O5 {) Q6 {( a2 z+ X2 j4 s% l if(res=='.')- t/ ?' S, B' h6 Y- J" s% l# S
res='\0';. O$ A4 e, i: T* f* P5 v
return res;' K6 p5 R; E2 A. Y1 l: Q/ R2 Y( H
}. O1 F# Y1 l/ }
# I3 D: @) b" S& M$ K
int main()4 L1 U2 U$ B) k9 q
{
: [% C5 u4 f. h1 P- F \ char ch;8 ^: Z- g3 t3 n; b0 q3 m
char res[64];
( n. s2 I! u' } float result;0 @- g a; F$ P8 K6 Y0 L" o) }8 f0 V
while(1)
- U/ f; R2 h+ [6 B {
( H3 R1 p0 K$ M q- H# k result=compute();: k) {: T# _: J6 `) }9 R+ b
printf("\nThe result is:%s\n",killzero(res,result));" L( J `4 k# ]) ?: A2 b0 a
printf("Do you want to continue(y/n)?:") ;
# H- V! `* `2 @# \" d1 i ch=getch();8 k: f$ d- d, a) J, f! Z
putchar(ch);
( z; b2 Q# G' i) q2 ] if(ch=='n'||ch=='N')/ \" x) P7 S6 i. k& `: d
break;$ q# X! c5 P; j" U3 o: n
else# v% T0 M; T+ H6 Y
system("cls");, n' |, Y0 R/ U: r7 L8 Q. U) O
} k5 j! a8 \3 g+ n9 C6 A
return 0;
6 X4 L( y+ P! U& t}
2 \4 t0 O- d6 x- n J O1 o6 T2 t2 K0 `
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|