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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.' |; o7 R+ f% p# H
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
2 r' r7 Q: f) h( `/ `: R/**************表达式计算器************/
4 S G/ |6 `2 D! S0 g; h#include <stdio.h>
2 S2 z, B$ t0 z#include <stdlib.h>, g1 p1 u' y1 Y7 {4 q
#include <string.h># o) E2 C5 f8 _0 b0 {
#include <conio.h>
' y3 x. f# N& J0 l#include <malloc.h>/ G" J$ {3 P7 |5 z( H
, r' `+ Z- K- S8 D0 ^1 T) ^#define STACK_SIZE 100( _2 r( o' N4 r' |: L. Z
#define APPEND_SIZE 10$ }: @0 b6 r7 Q, g9 h- U
. m5 f: y+ [! j( x: T
struct SNode{
$ B8 r: l3 A# u( _' D0 I, t3 C1 f# P float data; /*存放操作数或者计算结果*/
& I1 i/ l- W" r char ch; /*存放运算符*// q3 p# Y4 k$ ~: [& u
};3 ^* @' y# W7 i2 y8 Z# R' o4 d
5 c4 z) ^9 [; J0 I" v+ R
struct Stack{
; I+ ?1 v2 k7 l6 R( R' f SNode *top;
9 s. D1 o+ R2 B/ z/ z/ h0 O8 r/ ` SNode *base;7 j0 \2 z1 B- F2 C: }- J$ T' V
int size;, W- X; ]- ]+ `; A% x6 [
};/ n. G/ _( t- \
3 Q! ~: H3 ?$ @; u+ A& ~
/*栈操作函数*/
5 [/ K* D; A0 g! W6 Bint InitStack(Stack &S); /*创建栈*/! [, ~. ?3 x. r7 j. \
int DestroyStack(Stack &S); /*销毁栈*/
! ]3 l( C+ I% y9 f& p% i& ^, Tint ClearStack(Stack &S); /*清空栈*/
/ n+ F) f/ _/ [& w- r! @int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
1 b! A- i5 j0 `& q! Qint Push(Stack &S,SNode e); /*将结点e压入栈*/2 J+ e$ n/ Z* B
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/+ h' z5 K; w! [2 l$ h3 |# }
" q. Q! ~; o% k2 h+ C/*表达式计算器相关函数*/ S' q+ ~ p3 S8 l) E& N
char get_precede(char s,char c); /*判断运算符s和c的优先级*/# ~4 h9 o& L' A* j1 E& `* O! b9 N
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/' ?0 _8 L' x$ M9 A
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
6 J. T/ N# E( U2 A7 Afloat compute(); /*表达式结算器主函数*/' y# O N$ z. Q1 O" T
char *killzero(float result); /*去掉结果后面的0*/
5 T3 |" {3 {. z/ o+ `$ R0 I* D# N! }- Z0 A, t1 ^5 m
int InitStack(Stack &S)
d% R) \( _% E{
! U* f; a6 O* e9 y S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));" X3 \% q3 `' ^( g
if(S.base==NULL)( v( k3 k* ?# N
{" Z$ x7 H$ y& z) J g( j: m
printf("动态分配内存失败!");9 j8 Y3 M% v; d
return -1;
+ `! x; a! }& S) Y9 ]+ E }
$ v0 u# V8 r8 r S.top=S.base;* h/ @+ e0 r) z% W: y/ ~
S.size=STACK_SIZE;) F1 S0 J) \) B+ {% q7 j
return 0;9 [9 j8 y" k( e( ^) @+ O
}6 Q: q' L% I+ |+ \* L3 R
1 [1 _& v# @9 r! f6 J; j6 f+ zint DestroyStack(Stack &S)6 l- \' d$ v/ L# v/ e6 W2 {/ ?
{
" E% h/ T% R- G/ p. h free(S.base);+ z4 E0 [' V8 d; N3 d6 M, ]' r
return 0;- ^, D# E% @5 y1 w5 O, L# T$ k
}
8 D1 I; L; Q2 v3 i/ j' K( U" e; l; h9 h
int ClearStack(Stack &S)% T- T7 O' [9 ]1 Q/ P. _
{
# r+ K$ q" o1 R7 u% U5 W S.top=S.base;
( B8 {$ b7 L q5 Q return 0;
6 @+ D, g& o. {' W/ H' j, u}, s. t+ V- U9 i2 K0 F4 S7 z
0 h. b+ D$ R5 E$ o: P& wint GetTop(Stack S,SNode &e)- k/ x" u5 i6 c0 l: h' C- i8 p
{3 \* ?( v- f4 w! t; |$ |
if(S.top==S.base)) x9 \3 Z4 b1 @1 e$ z* _
{" ], L2 Y* F5 n# d& i
printf("栈以为空!");& d: n' m& ]8 {' i# A
return -1;
: K9 h+ K, F) B9 U4 f4 s0 ^ }
6 _/ S( b. y5 U6 W e=*(S.top-1);/ a' W7 N+ n' B8 x: w
return 0;% Y* G' @) K- S4 f3 V
}3 U5 u: v( y0 x$ L8 f( g9 v; ]4 A
4 O8 V6 k) k3 y4 H
int Push(Stack &S,SNode e)' [5 {* j$ z9 J0 g) I
{
4 \+ r9 Q8 B4 @/ x1 | if(S.top-S.base>=S.size)
7 R; S3 G2 T5 Z3 A( i% f {6 L% n6 G% S5 T9 w
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
2 @, m. I( d! `: z7 i' Z+ f4 a if(S.base==NULL)
I+ g2 M# ~7 d( q8 P3 l {1 m6 W& j4 @# a9 P
printf("动态分配内存失败!");% s3 q8 t. m5 e( X
return -1;+ b4 F$ Q5 g2 V
}8 n+ F; [8 d" Z$ I' i( B5 \) j( H
S.top=S.base+S.size;) `# n2 f5 W& l6 [. z
S.size+=APPEND_SIZE;: n8 ^$ O0 R1 O8 g o0 w! F2 U; z
}0 c9 U( Q# [: e( M. H6 N
*S.top=e;3 g+ F1 A3 h0 i: o: ?6 S2 l
S.top++;
4 U: h9 `/ R! w7 n8 E return 0;( M6 O. B0 ~; f5 P" i
}
; N8 Z2 H2 b5 g7 ~$ H6 l
, q7 H4 n3 \# |$ _* t. ?int Pop(Stack &S,SNode &e)
0 F% Y2 W, L- d) d5 ]{
( x) ^. M. R7 c! e6 H. t if(S.top==S.base)3 v, n+ y" d1 }4 O i7 D/ t0 O
{
' K {0 ]4 \) N) S6 K, j printf("栈为空!");
) _5 x4 b' ] z return -1;
+ w" X& x( o5 N5 L$ B) j" D2 M }
* ^' |; h& y, J e=*(S.top-1);% F6 p: }+ U! M+ h5 a% ]
S.top--;
# T/ F+ {2 C: y0 p return 0; i Z/ b* z. [" q
}
1 z8 R0 n. g( |. E8 }# a/ s& k" X! H. m2 }$ `
char get_precede(char s,char c)& \0 J+ I- `+ C7 f& G
{- m k" E% D) {, |% @" F" T
switch(s)
* t8 d+ p, F3 ?& t2 H! Z. V {
: {4 w. D/ O( R8 _5 f7 ` case '+':
. i0 N; g6 V# }0 f6 `. ` case '-':
# ? o/ i0 S! g: y if(c=='+'||c=='-')7 q- e" U8 p7 h* Y+ L
return '>';
+ H5 ?; g+ t& r) l! d# g else if(c=='*'||c=='/')
7 }1 q7 M! m% j4 Q1 m return '<';& h* |! D8 w+ o0 Q* G! [
else if(c=='(')* U% c, B( i9 e. J3 }, g0 r
return '<';
[! x9 p& j( G/ i; u/ C2 K" l else if(c==')')" a/ ]7 H8 Z# }5 x# O& ~* a
return '>';
6 I& w$ R8 R5 k% n9 g else
3 Q) I/ Z2 W" v- [/ B0 L+ o# S return '>';& P! b8 |' E, _" G6 m5 |
case '*':8 B8 ?: f9 M$ ]3 m) K
case '/':) A7 u& E, F2 x, P- U. u
if(c=='+'||c=='-')
. q+ p4 b+ B) a% u% w0 I6 y return '>';
- L5 r- ?" g B( } else if(c=='*'||c=='/')8 u I' z, ?) [ c2 o0 ]. S1 Y2 h
return '>';
! i$ k# R2 ^5 y else if(c=='(')- S( C5 g1 U& U8 J; Z0 H# k6 M* n
return '<';
7 n; o% e4 y4 B9 Q' {7 m, G% v else if(c==')')
/ e* r9 ]; e- M5 C! @ p return '>';
; S3 c& R: g( ~+ s6 @% y+ o0 b else
! H8 ~: A. ]+ f% k6 Z C) c return '>';
. u) x! I9 s" P7 w7 f0 X case '(':0 S8 b7 e) Q3 V8 k; \# s
if(c=='+'||c=='-')
9 v& w+ d( l' F3 Z return '<';
! r+ U( ^7 Z. z else if(c=='*'||c=='/')
; ?* e* W' c. K' {9 p8 n return '<';
. l: C) a6 E5 {9 U: H else if(c=='(')
u; z: z3 n4 m6 g( P6 T' b return '<';9 J i Z1 o2 h6 K) j3 v, m; m, U
else if(c==')')
0 `, j9 {2 Y% U* o! c5 G: ^ return '=';
- }) n4 }+ }5 U$ [. Z- u( Q" _0 O else
$ z l4 Z- G& I+ f! {% d return 'E';7 |6 H+ v* n: `* g: Q e Z# X. }5 z
case ')':
# D! g# i( r' ]. ?" d. f if(c=='+'||c=='-')* C7 F! H4 G6 Z. E8 m% h
return '>';+ v. c, n' n& F5 c2 o0 R, ~
else if(c=='*'||c=='/')
2 X/ j+ ^+ `2 Q9 T% t! C" U' {* L t$ M return '>';! V) O! P- {) A% A( m( V _
else if(c=='(')( Y3 K* m/ w1 a
return 'E';
1 m+ J1 k; O/ H- c) b else if(c==')')' @9 b' u5 y* {& ~6 W
return '>';
" N4 E; X: p1 u' d& Q5 T! v else9 ~0 R" t: t. @ x
return '>';
: u" Y: S6 C, r# Y. @& P- b5 q2 B case '#':) n# l# p$ P3 x3 X4 r: e
if(c=='+'||c=='-'): d: n! @- n) ^7 S& E% G
return '<';1 } E8 w* O/ _" ^9 e: B V
else if(c=='*'||c=='/')4 G, A6 G2 A8 v' h% Z; m
return '<';
4 g+ S( b& x% \3 r: v else if(c=='(')# _6 _% b+ C2 M1 r4 u$ v
return '<';/ U0 e; F' f& X: M
else if(c==')')
, U/ J( v( Y2 g+ R4 X6 l return 'E';
8 A! G! W! t4 g. O4 ? else% T X Q, R6 `- n& Z$ M/ t( x
return '=';3 y$ t" W( r7 O6 h7 b& M
default:
# X8 N0 ~" ^/ L' ~! E1 `* ~. U break;4 Z+ R- J3 t9 d& f) S R6 A0 h m
}7 T: j7 r$ `# p6 @: j# \% `4 ^1 {
return 0;
% g( x7 C |( A! W8 Q \}
, V) x9 C* B! @6 |5 c( N* p s9 Q8 E6 x' M$ Z7 `/ H" _" d1 V1 \
int isOpr(char c)6 ]6 r6 `( u8 w
{
Y4 m, Q5 p s! R4 j( t' V5 O; C if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')) w2 k9 L; G4 [1 a- L
return 0;
+ g' V8 R/ I; h, m+ @& C0 s else
3 q# h, F0 d, B. b9 ^ return 1;
% V3 i q8 {) w' B' Y}
' t6 @! r6 o% {$ X, f( U; ?% j2 e5 ?2 Z" i" o! E% ^3 R6 T( m2 N
float operate(float x, char opr, float y)
8 h: g- O) A6 @* `- u{
* ~! u: ^* m; d2 F7 G% n; s* R1 A float result;
: s9 F. J* E8 l7 A2 F/ t switch (opr)
- O& E; z! ~: D6 G9 l' ? {# Y" z7 x5 Z2 ]$ X& O8 P
case '+': ! K+ F2 [/ U. L* M3 q1 Q
result = x + y;
" F" |9 z3 y; g: ~$ n8 U break;& m; d: g/ G9 N1 e5 T' A
case '-': - `$ K8 W& X2 a4 j" r
result = x - y;2 a9 x6 S2 u( A6 o8 X
break;+ W( u9 A6 t4 |
case '*': 4 W. i; t0 x5 B- I4 U
result = x * y;0 z* Z, ]$ i3 \* O8 b r# o
break;4 U" c' B9 L# l' n
case '/':
9 z5 g7 _9 \! G" I- r4 ^4 h if (y == 0)/ N( e0 e9 Q6 c& c% E; J
{) u$ ^0 V. O% R1 A- X$ t5 {
printf("Divided by zero!\n");1 |8 d, ]0 J) t1 m9 J
return 0;
( f1 h& B% V* g( W# i! C/ Q( ?" u* w }0 ]# {- p5 s6 [0 N# A9 W7 M+ ^! \
else- @- Z2 ?3 M6 N7 Y1 B6 S
{9 c! s" C& P( p" C& P$ r
result = x / y;4 o' k. n8 ] w7 K3 n4 A$ S
break;
% ]7 F1 x9 E$ e) J }
% x0 G6 o4 X4 Y& n$ h; n& _8 i4 r default: ( s, A/ z8 S, f9 ~' |8 R
printf("Bad Input.\n");
2 B* A r C, @' B" w0 x return 0;
+ Q0 {' L! _1 d* {& j" C }) x# o/ F3 ]6 `0 p# D4 j: T- W
return result;
6 L: B! i2 W+ ^( w# B}
8 \/ @& ~ f$ U, E! M7 B- K" {/ N4 x9 o- W
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
1 H- H- V/ M# p6 | g{ H- b# h a: {# `( o
Stack optr,opnd;
, f( p9 c- l. l struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;9 ]0 K1 T6 f. E" n5 {2 `
char c;
; I/ ^3 k9 n: V& [1 L, B" p1 a% g7 ~& \" l char buf[16];
1 B# n6 D6 h' Q) B/ l) G" B int i=0;
) x! I( C! ^; r5 Z$ O4 O' Y
. i6 e u# O8 N0 o, r InitStack(optr); /*用于寄存运算符*/
F( i4 @" x3 m InitStack(opnd); /*用于寄存操作数和计算结果*/
5 g% Z( R+ u; e* h memset(buf,0,sizeof(buf));
- x: G4 F# D) V0 {$ ]+ m
) R$ h3 v0 u0 F$ e7 f: F printf("Enter your expression:");' D1 |1 W3 A( v" G0 A% G
% \ s# h H' ^' }9 r; z opr_in.ch='#';# @, T6 c r) r- ^. Q4 k4 v
Push(optr,opr_in); /*'#'入栈*/7 C7 A3 e( I; \
GetTop(optr,opr_top);5 K; e- @ N0 n! N% U
c=getchar();1 T6 O( G& ]0 ~: h, s
while(c!='='||opr_top.ch!='#')
b) a/ [, e6 ]1 F, i; a! e {& i( w# c. }, O7 S# n4 t% x' Z
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/5 u- g. S; m2 N8 `4 I2 ~
{) n0 r o9 W- y) K
buf=c;
5 G l$ l! M( |$ E i++;+ b( a4 C% o# h4 m/ `
c=getchar();
+ m0 @! d. K6 j* [ }+ ?& B+ W0 u$ u6 [
else /*是运算符*/
$ _+ Y0 {2 ~* Y/ @& L. j4 T7 W0 Y {+ f' `! g# S3 O0 g E" f# i* U
buf='\0';8 z5 Y+ E+ A: F i# s3 _
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
4 D6 x9 I" x0 j4 J1 w3 ?8 D& | {
) O* c2 I/ }. n2 D opn_in.data=(float)atof(buf);0 A$ ` [0 v1 M# u
Push(opnd,opn_in);
5 ~( O- C) N0 t% L5 w, s* L printf("opnd入栈:[%f]\n",opn_in.data);/ z$ Z+ \# o2 x* o
i=0;8 {6 M( q7 Q1 P, Z
memset(buf,0,sizeof(buf));
2 }' a& \1 I9 k& x! L7 L: X }
* \; a8 @3 I6 S& g9 \4 a$ i3 f x opr_in.ch=c;4 H$ {2 J M3 x7 r( L
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
5 D9 q+ V" w, r3 |! R {* D5 E2 n! k$ S% Y( H. o0 t
case '<': /*优先级小于栈顶结点,则运算符入栈*/$ `$ @2 y h A
Push(optr,opr_in);
& B0 M! n; J! o' j) b printf("optr入栈:[%c]\n",opr_in.ch);
2 P3 C0 G3 X2 R/ p c=getchar();0 u0 d6 M, @& A; P8 N- D+ K
break;
, I5 |* m5 [& h3 @- i case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
3 Q$ G0 T' D6 Z; |4 {3 g3 Z7 P Pop(optr,e);! H. w/ o% o7 Y5 ?2 f
printf("optr出栈:去掉括号\n");' P. ^1 k6 [* T* J' x* G% i" D( w, S# M
c=getchar();- }1 a& x! @" r: l0 d' j) }* U
break;2 W9 B$ c: E- P1 J
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/: N- {; _0 b0 p0 L
Pop(optr,opr_t);7 F" @! i" Z: @( F9 X& L
printf("optr出栈:[%c]\n",opr_t.ch);" a+ L2 u! ^, j" ?
if(Pop(opnd,b)<0)9 n+ F) w2 N* S) V( h: a
{" M0 s0 C6 K/ C7 y
printf("Bad Input!\n");# C! x8 k* ?( U/ f5 ~7 X, b" e
fflush(stdin);& D2 X, `; a' e! I& G# a$ [& E
return -1;
5 k1 ]& y" E. @1 t }( q" U, d+ A/ V* I8 Z
printf("opnd出栈:[%f]\n",b.data);5 {) H. K [) G2 _: b$ s5 U5 q: V
if(Pop(opnd,a)<0)( h5 `. s" n+ E1 `' U( G, v; p
{4 @- [: C" c: D, l0 ~9 l4 ^ B
printf("Bad Input!\n");6 n+ q& I. ?+ O3 J! u
fflush(stdin);, o8 n6 b& |" C. {8 N
return -1;
' {+ U+ v2 k) B. N$ I& ?/ a& R }9 e7 C5 s" {2 `4 u" [5 H
printf("opnd出栈:[%f]\n",a.data); @0 ^! A% Z% H* M" @- h' Z7 `* P6 Q
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
4 P* h- d; u* W+ Q Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
2 k4 x, t6 J" d6 I, L! y% w printf("结果入栈:[%f]\n",opn_tmp.data);
) @: r+ c- w. S8 y$ r) y, X break;
# U/ s8 p( m s* f }! Y$ e% P( |) a/ L% _
}
) P* j" d; t6 |9 W3 k$ @ b GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
/ ~ q6 Z- ?# G* g# [ }! A/ ]5 D4 ^) Y' r
GetTop(opnd,opn_tmp);* g2 ], J- @, Y8 C8 O
DestroyStack(optr);
. R+ }& x2 a9 s) m DestroyStack(opnd);+ a$ l! B: p+ `! O* X
return opn_tmp.data;
; O! j. j+ ?6 h; Z0 R/ E! H7 {}
/ R8 w1 c' U+ b2 y: e, S
: q2 i& g% G6 l% p1 U3 Q& w& x& Fchar *killzero(char *res,float result)
; j* C- z8 j6 g! _{0 ^' Z( a7 E2 {2 m
int i;: }2 \ Y# v/ r: O/ }3 p/ U& Z
# m* C$ Q2 M' S$ f. y sprintf(res,"%f",result);
/ g) X ~% ^$ g4 ?4 t i=(int)strlen(res)-1;. g6 }6 h# [" c4 a; X3 e3 a
while(i&&res=='0')
8 e9 M1 j) |5 K5 N2 p {
' u5 A, g f! u$ f D& D: T res='\0';) j3 ~" i% B3 z6 L8 f" G' }4 N4 U0 m
i--;
8 w. B' q" v4 A2 k+ [ o0 S }- o. A, C7 C& U
if(res=='.')/ g+ V: a6 j# p; T+ K4 u0 Q
res='\0';
) g+ }0 [* W3 r return res;
2 k% a0 J. e% l+ D, d}7 \ |& C3 `+ r- t2 d
$ I/ a7 N; N! Y( {1 Q/ k/ _int main()
' r% H8 A2 ^5 S{1 s j, [) T1 H* a" v/ g
char ch;( y6 Z- X0 O3 e8 m
char res[64];( s$ x: z* ~! _1 C
float result;5 y6 Y$ Z$ \( I5 q. K+ |5 T& {
while(1)
0 W* I" @+ I; L% }: I! Y {
: l3 R6 f; E& q# Z result=compute();+ \( }! z# Q) |- O' v* A/ s5 ]! b1 V
printf("\nThe result is:%s\n",killzero(res,result));
* t( p+ R7 z+ Z2 K4 N$ ? printf("Do you want to continue(y/n)?:") ;
( u5 P8 B7 E/ ^4 t$ w ch=getch();
: s$ P6 i* J0 {( k putchar(ch);
! U. B) \. v5 z y4 g, |, O. B if(ch=='n'||ch=='N')
9 ?0 K# e; U9 v$ K' I break;# w- Z9 I+ D; v6 G' @
else" n# k7 R6 x/ X
system("cls");
/ {' H' R/ k+ x6 _# F! O8 R }. Z. r. H9 Y! D
return 0;( A4 n) K- D7 a. I C
}9 |1 U' P: E- q& i9 i
1 _. M. k1 H( e/ F+ _
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|