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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
% V& H8 q+ p, {! `- h. a程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=$ K# b- x2 Y, `4 |4 {1 b% {
/**************表达式计算器************/& m- d0 Y5 M3 {% X' \# E& v. N: V
#include <stdio.h>9 v5 d0 g1 m8 _ }6 O' L5 ^; {
#include <stdlib.h>9 p1 S3 k9 n. _6 V
#include <string.h>9 b; t# x2 @5 [9 z# [) B, a* C" k
#include <conio.h>
5 s9 U& f$ S9 E2 r! o2 L% g#include <malloc.h># f+ O Y0 [+ w/ r
* n# P9 [$ k8 y0 Q, X+ O7 q4 c
#define STACK_SIZE 100
! }. m5 q" M* C& j#define APPEND_SIZE 10
2 ]) B3 ]: g2 d3 M6 h
+ j& o5 i l3 y! R6 zstruct SNode{
: R6 m/ x. L" @5 N% p float data; /*存放操作数或者计算结果*/
9 d3 B: |4 b2 u2 B7 b0 | char ch; /*存放运算符*/( S9 Z! _( x$ v$ r. h6 s3 n5 `
};
! _; C- M( r/ u# ?
3 w' \8 K2 f9 _5 D1 B0 \* jstruct Stack{& y1 P" g$ N6 _ ^
SNode *top;0 T1 D2 v/ V5 b% G$ ]
SNode *base;8 Z# ~. e' l% t9 q% S1 ~3 X. ]2 [
int size;
) g: j: v/ Y) a- ]9 q; L};
: u& |' E" b, L2 H- z) D
, ]& z+ x+ I- x7 O( L/*栈操作函数*/
/ `' }7 ~+ D+ t6 Nint InitStack(Stack &S); /*创建栈*/
0 Z5 f, R1 w6 ~3 A/ j7 R6 iint DestroyStack(Stack &S); /*销毁栈*/& ]2 j5 r% v+ l! h; M# n( o
int ClearStack(Stack &S); /*清空栈*/
3 C% T7 \( _) p3 c3 _6 G X2 Wint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/" G% t2 O4 {2 _: l- h6 w8 ~% Y/ U# }
int Push(Stack &S,SNode e); /*将结点e压入栈*/
4 l. t! N9 p% `1 V+ eint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/7 K* b f; o6 [/ Q# K8 o+ t
( z3 T# u" x6 Z7 m# Y, | b" \4 d
/*表达式计算器相关函数*/( n+ o6 T a5 I1 i+ @
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
W4 B4 P1 Q) q! [2 H" m0 T4 zint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/9 v" [) T/ {# F5 u' e
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
; p6 @, R0 k2 x( }& Q8 _0 X4 Xfloat compute(); /*表达式结算器主函数*/1 I/ Y- z4 v- w9 M+ J
char *killzero(float result); /*去掉结果后面的0*/ 2 R: b/ G7 j! f" i8 r: g
2 r" P0 i9 N2 ^4 o! E
int InitStack(Stack &S)8 M7 Q+ \ W2 J/ b. J/ c
{4 P4 q$ {% {+ R8 k8 i" @
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));; J; B l! w$ [! {9 L- D! w& Z' Q
if(S.base==NULL)
( ?! \6 b7 |2 x. U: s; G/ o( b {
& d) L# m! r+ x# D, t4 h$ ? printf("动态分配内存失败!");/ O$ F' m; O. j* G
return -1;
9 ?/ {: \9 z ?4 j5 v/ k }
9 U3 D& g, U0 Z9 _ @, k S.top=S.base;
2 z) C/ }" \1 Q9 m0 n+ m- M S.size=STACK_SIZE;2 o2 \( \5 o; `, e8 O$ a
return 0;' Q$ C+ J1 s! d: g1 p0 R/ _
}
' a1 L- f1 k- _% | S+ T4 a1 J5 X/ T3 R0 r. g# D
int DestroyStack(Stack &S)
# J# d2 Z7 o& n7 C2 R{
Y' y" e+ u. I# N. W free(S.base);
1 Z' ~3 M/ o" w+ h return 0;
& e: U$ T3 P+ E/ W& I% ]9 W}; }* ^( ?2 d7 z7 U! d8 F- i
( o( J6 p5 P' U; V$ r+ tint ClearStack(Stack &S)
9 a3 F% B1 U0 L' T2 Y{' D: z6 b1 f% @
S.top=S.base;
% g# g$ T& X7 N B# @9 |2 { return 0;
7 A2 N+ G3 N5 j- N/ }: X}! B2 z- @5 s0 @1 T! {, }
+ I$ Z3 S, l3 A! B( M2 W4 B4 J, l
int GetTop(Stack S,SNode &e), P ?6 `& C8 u6 W0 i, h
{, @5 k4 Y t3 z& J8 O4 V
if(S.top==S.base)- J4 d( t) R1 ] V# o
{8 l! W, j; k0 a2 G2 G% z! Y T
printf("栈以为空!");9 H0 I7 i# c8 J1 W+ c0 R y
return -1;
9 J- L5 w8 W, Q }0 d3 _" n$ h9 ] j* b7 n+ X
e=*(S.top-1);) K+ j6 ]% [! N0 d& u
return 0;5 K% [1 Y* _+ r9 T
}
( i$ H. p6 V% b f% ~5 u# M# h" ~: o/ D" V) o
int Push(Stack &S,SNode e): |9 _; M, S6 ~, ~; j8 K: D
{- J( {, x! P- c5 G: C# I7 E1 Q
if(S.top-S.base>=S.size)
6 U9 y, m! \2 K3 ^ {. @# L. r7 v8 d
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
; p9 W! V* [( H& t6 [ if(S.base==NULL)$ } a; I0 Z! d* Y
{
! X4 {1 i$ m/ {7 g1 T* Q4 G printf("动态分配内存失败!");9 P; `3 J' y+ ^+ [; ^; M' t/ c7 I
return -1; T( W% J: T# ?3 L' s
}
4 b) A+ p+ E1 \9 V, e- q7 I! F/ ] S.top=S.base+S.size;
1 k; |$ n: p# Z( n7 l6 | S.size+=APPEND_SIZE;
; D$ ^/ r( X6 W7 z }& x( f& v" D, \8 b, `6 f2 ]
*S.top=e;
) L6 H5 b6 m! W+ m- _( K S.top++;
/ t: p1 m5 a9 J return 0;" C! e& [. H+ t, _5 J7 Q( q
}
3 F1 I9 L3 y E8 U
9 j5 W: V7 i8 |) S! R( B: ~! g5 }int Pop(Stack &S,SNode &e)) w, o. w) j* r$ E3 W
{; Q8 c: x( \- Q5 c0 A
if(S.top==S.base)
. o) A/ X1 H8 D, j; F* Q8 M% N {
3 h/ E) ~( {! V C printf("栈为空!");
' g0 S1 e8 q y" F! m- H# ~) f1 J/ d return -1;
" g3 O% s2 X: k h7 ` }
9 Y7 ?: _, \' R6 V0 M/ D e=*(S.top-1);7 t$ l/ b$ w+ u: w5 I
S.top--;; Y* ]8 T! R3 S+ g5 _/ E
return 0; N. P# o6 o5 a
}
: T* g. C+ F+ _; Y% ^1 G' E$ N! w- p8 D
char get_precede(char s,char c)4 u2 @, K$ ?& s" ?( z
{! P* Z3 L- h \; u
switch(s)
% N5 m0 O) Q8 P: { {
# h7 |: `9 n' X) s9 y0 X case '+':
. j9 ^: }) V3 q9 K# S: B case '-':" M1 M- \. ?& x
if(c=='+'||c=='-')
0 ]% c' H5 m/ o6 t return '>';0 e# \" z& S, [4 I3 }
else if(c=='*'||c=='/'). o, b; g4 g2 P1 W7 A) L: b, S" u& @
return '<';: a: X: ]$ P2 n% S( `2 ^
else if(c=='(')$ W" a2 m @7 P- f
return '<';
8 x1 ~+ V5 G5 U/ F8 H; K else if(c==')')' h( Q2 L- {# \ V0 i' ?
return '>';
+ |4 L8 ?* A3 B7 }+ T9 ~ ^: S else 3 P8 J8 y2 I8 j
return '>'; |: M- d! T8 E4 ~
case '*':
! t$ S( ]8 h! g case '/':
3 F' }+ R* v7 O( e8 B+ _ if(c=='+'||c=='-')
" w( ]- \9 ]9 D- i( N/ D3 ^& L return '>';
& N, G, B& q5 \8 ^ else if(c=='*'||c=='/')
" @4 j+ L1 _$ M8 b" q) @ return '>';
7 e" Z. F4 N# D- d, t else if(c=='(') p( R( u e: X3 s4 b
return '<';
( Q- T+ o- V# R' e/ Z& ~ else if(c==')')% B# D* J4 _: p1 o/ Q4 L9 @1 C6 a
return '>';
3 W6 ?4 [0 |9 J# H$ ?+ x else( k$ d" v. H$ T* a. X. V
return '>';
* a5 Q* G, Q$ R! g9 A) G* P case '(':( O2 O$ ^/ t: }; U
if(c=='+'||c=='-')
* v n2 I4 _. F% O return '<';5 s% \. K; F3 F" S8 R# e
else if(c=='*'||c=='/')
$ z4 y+ k7 t" c6 Y" p return '<';
+ x& Q# ]* e) i; U8 S else if(c=='(')5 \; B# b2 J' h+ E9 y/ t
return '<';2 {$ j* K" \* O! u# X" L% d9 |5 n% u
else if(c==')')" Y+ Z- i4 f. X! E$ l
return '=';9 f/ Z" o" |* }6 Z% b& R
else
6 K9 D7 x" F' H) ?: ?8 p l9 E return 'E';- Y3 M4 r) y9 E
case ')':
' J( V+ N! B) h7 k if(c=='+'||c=='-')$ m2 [) G9 I* K
return '>';
" h n6 _; e+ u y else if(c=='*'||c=='/')2 R! N+ b P( M) V
return '>';
; m; {* o& S, l! B else if(c=='(')+ L- \5 Y8 @0 {4 ~/ J/ p) @
return 'E';
+ _9 N6 U* t/ ~4 \, a3 L else if(c==')')
. k7 w; I: n1 S1 C: k return '>';$ R) w# I- g. @' w }
else
% C) `8 [5 _ T }- y return '>';3 L8 g5 X7 I* G- n
case '#':; ^8 ?* K" V' f j- {4 x3 K
if(c=='+'||c=='-') ]: W1 P+ V" R& K3 o
return '<';
7 I8 \0 o3 V! d& {9 @/ _ else if(c=='*'||c=='/')* [' h1 e9 I( J/ {
return '<';# L+ o$ C4 U& s, e0 [# K: ?
else if(c=='(')3 M' q9 e3 {; I8 {4 ?
return '<';) |7 t% E; d, L1 j
else if(c==')')+ T! [2 B) f7 Z
return 'E';9 z+ v4 O6 A6 @9 B! f/ Q" Q0 o
else- E' n" a; f0 w3 G
return '=';- g4 S8 @- e- ]4 j L: Y# T2 ]
default:
4 K6 m- `! f# ^, W& B7 t _' a break;
& S/ B8 L5 {$ `6 W* o& d }; j, Z1 j$ L9 z) ?' ^* x
return 0;
6 y7 d. |$ ^2 `5 Z) b% ~2 {! M}+ w6 t; o7 y) d4 M i, c6 |2 {$ i
) H6 \4 N2 r2 c4 c2 W( Q! v3 `% kint isOpr(char c)/ l$ R5 C2 c3 x- X( l7 U
{2 l1 o6 L' X) m8 c0 i2 r
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')6 [( \! J# H7 w: E5 T, r5 t
return 0;2 p1 w7 A- J3 [, L4 C
else
" b( {# z& O+ x0 h* ~& A return 1;
& b- X9 e/ W/ Q! m3 ~% z0 U6 I}4 b! F5 A0 s" [( m
' B+ M& Q8 ]/ `2 r* {' H/ N: Zfloat operate(float x, char opr, float y)) T- D( I. Q+ e o" t) b. x
{' i; f* C, P X
float result;
) O, s y6 v8 q; @1 x switch (opr)5 k8 F' u5 A! T2 Y$ ]
{
0 D# l$ y: N+ _) [- D case '+':
6 ~. i2 n5 j% ~ result = x + y;
8 ^$ n5 W" Y- C" N- D) A break;
5 `2 p! e* A8 M9 J: a case '-': " p( f9 f \: N- s
result = x - y;( q' a9 `4 L1 w- ~& z( l4 [! K7 z
break;& W" a' v3 a! a" p
case '*': + j8 d `2 X9 U% M+ v. V6 z( l
result = x * y;
1 o/ s" N( ^: |8 U: S2 u' F break;; E- n' _$ t) q% T/ c" c0 |3 w) C
case '/': " z+ Z6 [( P( a& Y) V" a
if (y == 0)9 s* v& k( k: w' F
{
! Z, K" Z, v: o2 }* ` t$ L printf("Divided by zero!\n");
& `" I1 Q+ r2 i* v) W return 0;$ s* O1 J, ~6 J" @4 \/ a3 R! f$ z
}
! e& r4 R4 I& E5 H4 |! X else
* Z% w' L: n1 x7 F2 l% D {! u P: u! r+ d0 v; _
result = x / y;
0 a* _; P7 [) ~! n2 o break;
2 `" c( ^( |/ y8 }1 {$ R4 |7 l7 r }
+ B6 M8 I0 q6 B/ Q/ q, U+ o& U default:
$ U% R% D, t) B2 C/ y printf("Bad Input.\n");
: u. B1 D' w5 G- l9 {& R: i; P+ u u return 0;* v- N' }* [) J7 H; Z: K8 F- W' R
}
% v& q: m4 R3 t3 G$ P6 C" f return result;
& L& A5 P2 F* w2 a} \& w& S& }" M
# X, C8 d! u2 n# g* s: O
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
, W5 S0 h2 B# R3 x{
; p: V1 W- \3 F% c Stack optr,opnd;9 } f+ S$ r; G9 M" y/ k
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
, U$ _1 u% l' } N( h2 t char c;
3 |* V, W. @: F( C- W6 n char buf[16];/ X2 {1 `' z. {* X; v" V, G
int i=0;* _6 V( i8 o2 P; s7 c5 H
! b! E3 N7 L: \; d
InitStack(optr); /*用于寄存运算符*/
2 p( z. ^: C( h+ B4 O InitStack(opnd); /*用于寄存操作数和计算结果*/
; K4 W4 `$ u5 c' Y memset(buf,0,sizeof(buf));
8 ~3 U8 I/ H+ F y6 ~1 `
; S$ I' {7 i% m( S, W printf("Enter your expression:");
0 d# a% H4 [' W- f; `" e 5 M @% C. r4 [, I- a# s
opr_in.ch='#';+ E+ k3 W8 g# s2 q. c$ L
Push(optr,opr_in); /*'#'入栈*/) r# ~: t' X% G$ u8 X
GetTop(optr,opr_top);3 |3 E$ y% j2 n g
c=getchar();
+ H1 d) i0 M7 D1 u* L while(c!='='||opr_top.ch!='#')/ b& P6 ]" f$ d; x8 k
{
# L5 g9 J. ?' h4 D8 h+ @ if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
' E/ T8 u' j4 i- ?+ H6 v% N {% `# Y: h: n* M* ]! v
buf=c;
& c; h6 ^$ T: J* P# @2 T i++;% u/ P( y1 D& x' z# j# E
c=getchar();
- P3 y1 x* y7 Z' x: o }
' |$ o2 v, M1 ] else /*是运算符*/
& ]0 F+ y5 ]3 P/ O, n% X2 Y. ^2 P j { i1 P3 h& V) @2 ^8 \
buf='\0';) p6 q, T: t) h
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/3 U- R+ x- |0 x2 i. X
{
$ s) E8 d* {/ n- l1 J* _ opn_in.data=(float)atof(buf);- `+ R2 [8 ]" z0 Z
Push(opnd,opn_in);4 g& D9 ~5 P, F7 y* f
printf("opnd入栈:[%f]\n",opn_in.data);
. E$ h* |/ n6 D+ V: e$ W( \' H i=0;
Y* w5 R' C. w5 ~ memset(buf,0,sizeof(buf));& @5 |4 {% |8 l l) p7 M; q& i
}
; W. z) O6 [1 p- p p. e) O+ v: T opr_in.ch=c;$ F# _9 ~- q k ? Z1 f" c
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
. ^, Q- q( U4 o! o( g {
! M A% L$ { j1 M% A case '<': /*优先级小于栈顶结点,则运算符入栈*/
" u; ^4 G3 c+ v Push(optr,opr_in);
5 M% n3 a# \& a$ W7 V printf("optr入栈:[%c]\n",opr_in.ch); K- I1 m) e5 A! ]
c=getchar();3 I: u, p# }6 `1 F& ^& B
break;
6 [3 d- f. O& a# | case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
( W g) M4 b3 M' h3 T( f2 \ Pop(optr,e);! f' h$ M: d0 q& H4 n" R
printf("optr出栈:去掉括号\n");' U% x3 t% B. c4 Y( W, u
c=getchar();
# ]( H1 ?$ }$ U3 X* _6 t/ z break;
9 Q5 j! ?0 f, F% \, V" _% u: B' I case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/, A: B, D d1 z2 r9 b4 c& O
Pop(optr,opr_t);3 c) ~1 q+ [5 ?
printf("optr出栈:[%c]\n",opr_t.ch);
: I% R& O% ?( [& f if(Pop(opnd,b)<0)" z$ n( L5 z1 [8 M
{0 W2 D3 o* i; ~ s: k
printf("Bad Input!\n");
: K8 Z, ^/ g- D fflush(stdin);5 F4 A/ E. @& F4 t6 g
return -1;
2 u3 I' _6 B: ~- G! a; Z5 @1 I l }
' }4 L+ z: J1 p/ \ printf("opnd出栈:[%f]\n",b.data);
G4 K& F; T9 j% R, a8 E7 J if(Pop(opnd,a)<0)3 N: Y; g' z; T% q2 S; a. o
{
+ C% b ]) z |' c printf("Bad Input!\n");
0 Q2 y/ R& F+ A* N fflush(stdin);& W+ B( q& I/ r e2 B1 m8 `, I B+ i
return -1;
0 Y. h+ ^7 R( e" M% u6 z }3 h. V7 n5 ~! J b% [. w
printf("opnd出栈:[%f]\n",a.data);
. M8 ]1 w. J1 f! D* T opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
' I2 {9 N& e4 k) D# ?* f Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
; |3 i K% ^( p. s3 |# ^* q2 E% P printf("结果入栈:[%f]\n",opn_tmp.data);* y' i V7 X3 @) P9 f2 H$ \! m
break;6 M7 z; w1 u( H% n2 T6 v6 D: S
}/ T. d% o$ I1 u+ D9 N% B
}
. O: l! S8 u3 W6 m* M& ^ GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
8 {3 \( x A4 O' e: P }
, N" C a9 A0 V) G$ ?6 ~7 e3 ~. B GetTop(opnd,opn_tmp);" [( w. y: |$ Y9 f% b$ ]- k; _
DestroyStack(optr);
5 V$ X$ n/ }* ~7 l; M DestroyStack(opnd);$ j0 P$ K$ k; B
return opn_tmp.data;9 A: n( G- m; y( a2 {# e
}
+ W) e! }1 P3 {8 L* H
1 K* ^0 B/ i3 i% A+ hchar *killzero(char *res,float result)
& }% l) |" x( q Q7 }{5 h9 j. A K. a% g* c
int i;+ o% J1 b' ~$ R, ~) g$ `7 ~4 H; S' i4 s
Y0 l- J3 z; }1 K
sprintf(res,"%f",result);( V# G z4 b' Y9 h. }3 ]
i=(int)strlen(res)-1;
8 M; [: U. p% L0 Q- L while(i&&res=='0')
' W7 l @# A& ?8 B( J* G6 ` {
6 f% r [# b& ~8 \: V res='\0';3 \$ V# `# ?% `9 B3 c
i--;- P; [2 s5 a' M0 c7 b! d) g0 _
}! a$ l7 [# {; ]2 r8 y5 y: s% B
if(res=='.')
7 D% A0 @4 V1 R res='\0';) |# ^1 o M1 D6 s
return res;
, r: I: S- d. O$ O2 g}
" e! \- P& g% t
" o( }" {. O3 F0 }- L/ W4 o2 g: g# vint main()
7 O5 @4 z8 S( e; E0 \{# l# _, K9 p5 {: x
char ch;
% P8 {% W7 V' h3 p$ S# ~0 C, m7 F char res[64];* v! C; ]0 z+ g, ?
float result;
% S6 p; G7 g. k while(1)
% C" G' ^0 g3 I! f3 T0 k# V {1 [: L* O+ r# A: u
result=compute();
3 ] }7 ~# j% W& F* X printf("\nThe result is:%s\n",killzero(res,result)); H% ~/ c1 o$ s5 z+ f& Q
printf("Do you want to continue(y/n)?:") ;
+ |6 h0 X" i3 f' Q0 b ch=getch();
# H( K Y+ p! z1 ]% t putchar(ch);
& C f2 t4 ]3 |& B% Z if(ch=='n'||ch=='N')1 _2 D9 n+ B! M+ j4 _
break;$ s+ h" m- m V- _0 C4 W9 [1 f0 ?
else
- P' q/ u0 X+ b' J( M system("cls"); S' v! h! U5 T
}. Y `) H2 _ y/ ~1 X ]1 \, ?
return 0;
6 J3 Y9 R ^+ T" [' p- c}
2 r, W: D# r: c- r# g) e$ n, W( M2 [& r1 J) z
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|