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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
% d# i( K* u5 q* i2 I0 Z程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
' d6 B" W' P: B. Q/**************表达式计算器************/
5 z7 O: b! K9 A! H% @6 N#include <stdio.h>
9 G& W3 p" |# A$ y$ b- K5 h. Y N#include <stdlib.h>( o$ R" B3 _. S$ d Z
#include <string.h>
3 Q( g1 {$ L( ^0 t#include <conio.h>( w! @" Y1 _+ ^
#include <malloc.h>
; F8 s5 l5 b# J* W
7 H/ z. F' s% F#define STACK_SIZE 100
" C& F0 }, V% N#define APPEND_SIZE 10
8 ?7 N) i; F2 ]5 l6 v6 f# C+ g! S% \0 s
struct SNode{# P0 a' B6 f, p; |& h
float data; /*存放操作数或者计算结果*/" D J; w8 l0 K+ f% ~
char ch; /*存放运算符*/
* q/ q9 z9 J8 R& W: z& b# i};6 _2 j# u5 a% G% r* J
" @0 E9 Y- \: r8 r2 gstruct Stack{( h0 ^+ e8 c2 B6 d/ y' b0 A
SNode *top;" S% L3 r* F' W4 n
SNode *base;, s0 y8 ]4 P( c) h, c0 a
int size;6 F8 A: w) A6 F' j s* J
};
3 w' c$ P! b, T3 [9 B* ^& S5 d; q1 o0 R4 y. p& b4 O3 z
/*栈操作函数*/
" M4 B; {; _/ G. g- |) U* T7 D! dint InitStack(Stack &S); /*创建栈*/! o8 f W. }( {& q$ I
int DestroyStack(Stack &S); /*销毁栈*/
* w: } V! c7 {+ hint ClearStack(Stack &S); /*清空栈*/
0 k$ K' U1 T8 e6 H. B4 Uint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
+ f4 A- H! K: T' xint Push(Stack &S,SNode e); /*将结点e压入栈*/; b, [; Y+ E% o/ X7 A( \2 R
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/- H8 }, R, P* x$ q
- N; G7 I4 P0 B& N: k. _
/*表达式计算器相关函数*/ X$ z9 u+ e. Z0 D# `* x& m" v
char get_precede(char s,char c); /*判断运算符s和c的优先级*/( @6 d O1 E8 Q& V$ K. h E
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/3 ^, M! ~* a: b7 U9 R k6 O' s
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/9 h6 q, }# q5 p. L( H( P0 I: a3 @
float compute(); /*表达式结算器主函数*/
" q( X1 J/ o# X3 _+ n% }char *killzero(float result); /*去掉结果后面的0*/
& A5 v6 z5 c. ]2 B" b+ w3 C6 m& ]; ~% v9 u& }/ y! z6 s! l
int InitStack(Stack &S)
2 ~4 J# [9 S1 ^) R{* D% \, b) ^+ ^6 T/ ^1 {
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
3 Y8 [; g! z+ z$ T/ r if(S.base==NULL)+ B8 V" J& E# k* `/ s$ Q4 ^ H7 c) R
{+ h3 f% t2 W* }# A
printf("动态分配内存失败!");) `: @* E2 K9 m% S# C/ q- W4 n
return -1;+ C" Q9 [ F2 s9 |1 P" P+ ?
}
6 Q; i. _% r- R4 i/ O8 @' M S.top=S.base;( }2 z( \/ K0 `4 e3 B' E7 r
S.size=STACK_SIZE;3 i; {8 _5 b# V: O. G# t' h
return 0;
; j9 U [6 c0 p7 v}( T" z7 |' {3 y* I- f$ L
$ n/ s# D8 l9 g" N: d7 ?
int DestroyStack(Stack &S)
9 V9 s1 h8 k5 z- U8 j{
6 _& Y$ h7 |9 c0 d3 U free(S.base);3 l; P* x2 X' R% ^# m( U' A8 e
return 0;1 ]1 G+ V! [8 A
}2 K" n$ _: {+ O# A" p" H4 s( ?3 p3 u
# x$ `$ r0 _4 W. U, T) \9 g# I
int ClearStack(Stack &S)
s3 M6 u: [' {( q{
; i2 D# a( r( h. v. ^6 m1 {, S S.top=S.base;; [# l7 O3 o5 r% K* G0 h
return 0;7 z: ?1 P9 k& K& O5 l W6 \: m
}
/ V& P* l0 x, L. @2 G
3 v( i6 C- i U5 q3 E, F% ?; Dint GetTop(Stack S,SNode &e)
% F* g Z# ]9 F2 H0 d) [6 D% O{
_5 Z: s2 r7 C. J/ E& _; i* E if(S.top==S.base)( f, X; u4 k& X$ r+ b+ C" |
{
, @ _# M7 z4 x/ M8 h) l1 |0 ^ printf("栈以为空!");
9 Y8 q: } T9 s7 A/ V return -1;1 ~& p1 R' r6 ? H& u* q- ~
}+ D+ B8 M @2 p h- x" S2 K
e=*(S.top-1);
' a- i$ p; q) L0 n4 z2 A return 0;
+ a! m2 z2 x8 b}3 ~! c; p! T: \, {4 R2 v7 m
$ P* y" ^) ]* z0 rint Push(Stack &S,SNode e)+ r& v( d( ]+ X5 N2 {
{2 Q6 r' w1 C* d- {2 ~( A
if(S.top-S.base>=S.size)3 F; { b$ c$ p. O/ g# b- A
{' P2 a0 L* ~+ w, Z$ G
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));/ e# r: f7 |) g, h ~, z) E' @- [
if(S.base==NULL)* m+ F, m, M1 m: x* U" r
{$ X( Y- f. ?9 J: r- H
printf("动态分配内存失败!");$ ?. A8 _9 j/ k/ p- ]
return -1;
. @ L) D9 g0 m* n5 ^ }3 @3 S) I+ b7 c4 l3 h4 h3 j
S.top=S.base+S.size;
! T% G8 }. r/ r6 z! m/ K S.size+=APPEND_SIZE;2 O% q( T4 D; b
}, d% H7 g+ v; O1 R: D, e4 I( r
*S.top=e;
# _( r$ v3 p3 t3 ~- ^& h5 D7 p S.top++;
y1 H; }+ F; ]' g/ @" a9 W- F& Z. [0 @ return 0;- {# T+ i& d* Z! q: |% P6 V
}% v7 ]: T4 W. v' {7 c- g3 ^' ?
* S% K% |; ^$ P3 G5 C( z0 ]' U9 Z
int Pop(Stack &S,SNode &e)
* P$ K( H% H4 r' c$ y{6 K }, A3 V- P8 _
if(S.top==S.base)9 G5 \1 j# N' I7 z8 B1 R
{
* ^: p9 J5 U( a6 t printf("栈为空!");
+ @ P9 S5 \) W3 l. r' c return -1;
" D4 \' X6 s# C+ I0 f }
4 P0 J6 ^4 z# P0 N) f( y e=*(S.top-1);
# i2 K" L# c: w5 O t! E* i S.top--;
; J4 \2 v8 S$ U) g% v! t+ y# u return 0;
" C: L" t$ b$ |; ]% I}- }6 w3 l* |7 ^0 t h- s# h" D! F
( _8 x4 h1 `( e' }
char get_precede(char s,char c)- ^* Z- `0 w: L
{1 L, e+ }* _- V5 |! M
switch(s)
% W) r- U# F' X P. G* p {
6 H. Z( ~! `9 \( M5 Q6 \ case '+': - N$ |9 X# P& X1 W1 E; B0 [
case '-':1 @4 G. g9 f) S3 Y$ y2 K0 u
if(c=='+'||c=='-')4 T& O& A E1 D2 \, Y/ m' U% l
return '>';
' m( M, u+ `1 |/ \, p else if(c=='*'||c=='/')
" N$ H3 L: P# j5 F% w6 N! ^ return '<';# W3 a; P' ^# c6 \
else if(c=='('), V+ T* W- s; m1 M, ? e
return '<';
$ w9 C% H/ X6 z6 L else if(c==')')& K9 H! Y3 P; V: O5 @# g
return '>';
0 q9 T) @6 C% ]5 e8 ^" g" p else
' l; }4 h0 P9 t" M6 O) b0 } return '>';! R" v9 k7 j1 p% o8 f" K
case '*':
. N' Y$ X3 d6 C/ C& x case '/':/ r$ k _; b7 _& B
if(c=='+'||c=='-')7 F' s' e3 z8 G5 h
return '>';
. A7 a6 y7 x$ B6 R! Q6 O0 V, q else if(c=='*'||c=='/')
6 g+ `( N# y8 W3 _+ \2 x return '>';
V1 C4 E, B, y+ h' s1 B& G! t; v else if(c=='(')
9 v( E, v0 }. C+ A# y l7 R return '<';
/ q6 ?1 p2 B# @# W3 S" j else if(c==')')
, h$ H; H8 P4 W return '>';. y4 k. p4 T0 Y- `& z: b/ w
else
8 C) J7 M) Q- j4 Z return '>';, J! ]# N: ^: S5 X! k5 v
case '(':
$ u6 Q6 z3 T- H# o7 m if(c=='+'||c=='-')2 y2 F$ M' W' f( f, O, w* }& D
return '<';
9 b& ]# p2 N$ _4 ]) I else if(c=='*'||c=='/')1 }+ F+ t! U% H5 s7 ]8 r7 O% A4 K
return '<';9 i. |! `. u& i% S8 q9 V; z
else if(c=='(')) {: p. g w6 r$ C* a6 D* `' j- Y6 c
return '<';6 g2 ?$ q' J7 M8 i/ h" W5 G
else if(c==')')
, |+ V5 {; A- s5 c& L return '=';
) f# s; x H+ c E# l0 s: ^$ N else3 l- \! B3 ]0 P
return 'E';( U8 I' A: E) o
case ')':1 X, w7 x |; B% ?
if(c=='+'||c=='-')
. G R( o9 U; a$ [7 z6 h9 ]( `4 d return '>';
; Q9 j' o% _2 B" z# @% v4 x else if(c=='*'||c=='/')4 b' |3 X) x8 I
return '>';4 V" W. G$ [" t
else if(c=='(')# l9 s; v2 V% m9 W/ q( U
return 'E';" q8 d- m K8 w+ d. b% L' \7 `
else if(c==')')6 Z1 ?, [2 _' E7 j
return '>';. C/ R1 _! p* q5 O
else$ }+ k& g* `+ z' P$ ]: T
return '>';+ u5 a- Y! x5 c( ]+ y( h8 l
case '#':7 E3 G, o+ g. l" A9 s( v: O! S* q& u8 o
if(c=='+'||c=='-')% t$ n2 s0 ~$ O. n
return '<';1 m8 \$ x9 P& k6 s& V9 y
else if(c=='*'||c=='/') t, h1 A$ ~# M; v* E
return '<';
+ M1 t5 r7 Z) f4 j8 g! z else if(c=='(')
0 q+ f" ? W0 _$ f1 `: b0 h+ } return '<';9 F2 } i& `, Y* d8 `# C' Y
else if(c==')'): N* {. H: F. V! n0 O+ N
return 'E';% e. z$ E+ B% g3 Z0 ~
else9 H1 F- _0 P3 r% R9 N6 Q% n$ G6 {" ]
return '=';
1 }# Y: A5 E% O9 ` default:
. d! C0 K2 K. }5 ? break;7 ^9 a) U$ I9 w1 n& X+ O
}
! i: c/ P/ T: G4 N9 g1 m% `! g8 D return 0;
% A) @/ ?$ C5 X: u* L}" ^" K5 Y7 K9 J) Q
2 a* {1 l; P v; f6 ?4 z
int isOpr(char c)% s0 ?' f: U% ]4 e
{
, U1 ^& R3 o8 a) }9 G! q% m& f if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
) b4 J: `9 J) t' M return 0;! S, q( Z( g E, n8 Z1 _. O) Z4 u2 j
else / Z k) ]1 `* P! H: k
return 1;
9 O& W6 R( V' {1 R) z. I7 P4 \ \}" p" b, G' ]! @ V) G7 k. M6 I
. d5 { F+ ]5 \. jfloat operate(float x, char opr, float y)
- X- J5 i' w/ v4 f; E{7 ?/ E$ a ^, _/ K, P& w8 P& f
float result;( J7 u+ A/ ]3 l8 q. h9 }/ E2 c
switch (opr)3 ?7 k2 {! Y* p* p! c- L
{
0 x4 p+ S- W3 u1 }0 ]$ x# f case '+':
$ R( o/ J5 W; A' C: B result = x + y;
0 @+ Y; r$ _- P- Q, {: ]3 \ break;
* S# [9 {: C$ F8 J2 k* ~; E, B- J case '-': $ J, ?% d8 ^! S6 y) `# U1 b% H! ^
result = x - y;
' e: U# P6 ?. g3 ^" d7 e break;1 y/ S2 s/ H0 A Y0 N
case '*':
; Q: m; b' V6 M9 U result = x * y;% t% e* K u: ^6 P5 |2 ]" i x y
break;
1 Z v( }2 a2 N) D) q: Z case '/':
: ^6 ]& }; v- T if (y == 0)
3 y [& Z/ u4 Y# M; d" w {1 J2 R" S8 w# ^0 B
printf("Divided by zero!\n");
1 l" Z" J* M/ i; D& y1 f return 0;# b2 y0 b6 O. B K6 r j/ l6 g
}
4 `/ q. E2 P! D1 k, Z else
) o$ w0 d3 v* `( L+ T, P. \+ F9 o {: p4 n1 S' {6 e% M- r& `" Z
result = x / y;3 a% J4 w7 A! _# S( |0 L$ z
break;' K' q& K# ^" r- u
}9 H, R- ]# f" z( ]2 g$ l5 Q
default: $ H$ d# d! M% v+ K( c6 t# I5 \
printf("Bad Input.\n");
- t4 f( ?& R0 H1 o8 C- v return 0;/ `, p$ b# A+ w1 G3 G
}
* v) F# d7 K1 A+ u9 S# M6 p+ [- x) X; W return result;
/ v2 {% p( r2 I' o( S} + ]2 u( I/ T4 _$ E6 y
0 s0 [* e4 s' b7 R4 Q
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/% R I! X$ z0 q3 f; b3 s
{* N+ V) h4 p+ N
Stack optr,opnd;4 L) H1 Z0 S* J3 N
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;6 W+ R) ~+ h% n5 z( o( G0 _9 I
char c;; K5 ]+ `1 }; }1 J) D- A
char buf[16];. i( V o% ~& h% ~9 d1 M! D% C
int i=0;
# D+ G; T; o1 {- e ! c! L% O$ K" C! C: C" Y
InitStack(optr); /*用于寄存运算符*/
7 S* W! R* G" T InitStack(opnd); /*用于寄存操作数和计算结果*/. x" s& ^4 Y3 }, K9 [9 B# a- y2 c
memset(buf,0,sizeof(buf));
8 ]) V2 r- |# @7 \ ( _& J8 D' C3 K' y& i) T
printf("Enter your expression:");- d' ~, W& B9 }. o
; t9 \" I& l/ j# U7 m! j
opr_in.ch='#';% I$ w6 M5 o3 z
Push(optr,opr_in); /*'#'入栈*/
( _( g- k" ^9 U5 a GetTop(optr,opr_top);
7 y' C; P+ U9 ]' q c=getchar();" E3 I- S7 e/ T$ b5 E
while(c!='='||opr_top.ch!='#')
0 M2 g% ?2 p9 [, j& t( K; ~' s {
6 [1 W5 H& o i if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/( c3 a0 F2 [) F) ]( J) u& n8 h
{
; b! }! a9 J8 `+ w* T) b buf=c;0 Z9 q( G7 p5 K3 }* u
i++;
2 i3 r2 S/ m$ w; ?$ ^ c=getchar();) B. P0 d( L2 f
}$ d1 ?& f) d8 y! L6 \
else /*是运算符*/
" y8 i6 k J% r7 W9 H {
7 U: _- ^) @+ E4 {& P buf='\0'; A" q7 P+ L& A9 X
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/8 ^/ R f5 M- A- R* M
{
6 ?5 J0 b2 R7 E4 V: g) C5 P+ D Y opn_in.data=(float)atof(buf);! D( i$ z( T6 p' }7 p
Push(opnd,opn_in);
2 y: T C6 d- h# c: ^" K1 S printf("opnd入栈:[%f]\n",opn_in.data);; Q. y: Q$ ]: I
i=0;: t+ N5 O! W% y1 |0 K
memset(buf,0,sizeof(buf));
( E7 U P# }7 a+ q }
O( g3 e+ ?9 h2 D" X8 q$ S opr_in.ch=c;
3 `, @6 r8 B2 g- B, w% X+ A4 N1 e switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
; C; O; Z6 l$ u5 I& n {5 i s! v! Q: O" z; }
case '<': /*优先级小于栈顶结点,则运算符入栈*/
- x; B/ f' a3 @( i" c9 S Push(optr,opr_in);+ n4 Z0 b# @% ~9 V) F! `/ G) l J# q
printf("optr入栈:[%c]\n",opr_in.ch);5 M7 l( Z9 p( e
c=getchar();
0 w/ e3 ?. u- B& s+ O( [ break;; d' A' J9 s/ m
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/0 }% T2 I% k5 @1 S5 _
Pop(optr,e);
) O' M5 C- f S& j8 K/ C printf("optr出栈:去掉括号\n");
7 j4 _0 U% X" g* y* | c=getchar();
7 }7 X7 Z+ Z. T! }/ f, h break;# E2 G/ n. V6 g# n3 r
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
4 { Y9 W7 B% E* @" ~ Pop(optr,opr_t);
8 V' C3 r0 L) m' Q! ]. D A printf("optr出栈:[%c]\n",opr_t.ch);
+ e ~/ L5 ^* c; t! N) T if(Pop(opnd,b)<0)
( _2 K. L d% S1 p {
@* C) ~. v4 Y9 G4 T' v6 Y printf("Bad Input!\n");7 d/ K U3 Y. {- e1 f' Q7 U9 A3 e% O
fflush(stdin);
3 v+ a- w- a6 d! L7 x return -1;$ f. S4 q* K' W" l; ^2 e0 d! F
}
6 U, V& [; n2 f2 x2 }1 P9 Y printf("opnd出栈:[%f]\n",b.data);* }0 U& m# u% N8 I
if(Pop(opnd,a)<0)
8 i; Q. V! s- J; n" n3 K {, P+ D+ R9 `( n5 c+ I8 U: c
printf("Bad Input!\n");
7 a6 h# g8 V* T% e2 Y/ s) {7 y fflush(stdin);
# w6 J m% {7 z# P3 \/ T- [3 E* r return -1;" i$ Y' P" f1 o) C1 P5 }
}
9 [/ e" s+ [$ j+ c3 [8 D6 w printf("opnd出栈:[%f]\n",a.data);0 O- F7 A' G- s
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/+ ]) B% o9 h6 Q& `2 J, O! n
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/$ E- ]& N( |2 T* o! e+ L, o
printf("结果入栈:[%f]\n",opn_tmp.data);1 l. i8 h) _+ X: I
break;& C1 v; i. Z$ d* W: U
}
) d" F k0 P4 g3 {" b } e" k0 [3 L) ~+ M) w
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ ; E7 {4 W% ?3 U5 H; @* r
}
+ f- |, C+ o- d) w9 Z$ O GetTop(opnd,opn_tmp);
7 E, [1 O, y/ L! U) K* [: s1 e DestroyStack(optr);& n2 `( B. U1 H* J' A; f
DestroyStack(opnd);. t$ N& M. |4 j5 ]
return opn_tmp.data;4 Z+ U3 I9 h R7 G
}
$ `0 H8 j! n1 n; o6 c
8 y' [2 B' N! u, b! v! O* `/ o$ Gchar *killzero(char *res,float result)+ ^ a3 T! n* b' q- I1 N
{# F w- k+ i% S% ^! Y& a; d
int i;5 i$ Z x/ n4 r& R
( t) _8 X* x6 I# @ sprintf(res,"%f",result);
4 U7 I3 R! F: h C `" D i=(int)strlen(res)-1;
) y4 M2 D+ ~4 P' F/ m" e& N while(i&&res=='0')2 N6 P. n; B- b5 @- z
{) G9 p5 r4 d7 I$ J6 w
res='\0';
3 |/ Q/ S" _; G! t" _9 z- ^ i--;
k1 h' x9 O ? G5 h }( L" F! ~9 v! h8 _2 @1 ]$ @4 y
if(res=='.'); y/ b+ z& Y0 Z$ e2 S7 [
res='\0';' L$ N* }& T ]! T6 Y* [2 {
return res;
$ ]% Z5 G c6 g0 Z9 @}
8 n; d8 t2 R) }6 W4 X- F- q
5 h* s8 g/ [8 v, Sint main()
+ b) M! Z3 _2 j9 T/ v{, S8 }4 q& C9 m1 B G
char ch;
- S# j( [: O2 F; o char res[64];
. ^* |9 v& S ]# B; D float result; D4 }& C, n7 D* Z$ m& ^/ y
while(1)
" q$ l, O. l/ f8 z( u7 n {
3 v' L# E* h8 I1 G& Z5 c6 z& c9 q* { result=compute();
4 B% s7 ^$ a8 j- H( [ printf("\nThe result is:%s\n",killzero(res,result));
- R3 o+ \' H7 W' ~, n' a printf("Do you want to continue(y/n)?:") ;
S; [: ^$ y( O8 F* f3 D9 }) n ch=getch();
Q. Z' c7 T$ R) Y* ~ putchar(ch);+ f; t7 T4 C# a: i# t* z' I
if(ch=='n'||ch=='N')5 q" Q& m0 {+ l: a$ g) k
break;8 ]: `5 z4 l1 A9 I; j
else" \4 W1 F9 I* ]3 M( A
system("cls");# R8 N& Z9 V7 L2 T$ S& B
}& `# i; H5 k* X$ m
return 0;% g: z! C3 d E$ g: Q
}2 H9 H, O$ U$ E' j Q
( K8 X9 l% Y1 Z* K) E+ N% l- d! y- d
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|