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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
' J+ G3 N4 L% v8 ?! _程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
+ \- s, `0 s- D# ^/**************表达式计算器************/
" c8 \ l# f( V' h9 j4 Q" o#include <stdio.h>
7 e# d! X( e) T#include <stdlib.h>) B: \3 n5 U3 j& P
#include <string.h>) W% }4 d+ N8 D. @) i8 Z0 a$ Q
#include <conio.h>
6 l' O3 H: _: ?8 ]7 L#include <malloc.h>
% s4 V. ~# z& E% f6 B- ?
# e2 N/ i. L z. p+ b; B; ~#define STACK_SIZE 1009 n7 n' [9 [. r: R
#define APPEND_SIZE 10
" _( \( N1 u& w5 w( _8 {: f$ ]3 i. k) ~( Z. e6 R$ i8 Q
struct SNode{
+ ]$ `+ A, M2 S- R: g% E) N# m2 t float data; /*存放操作数或者计算结果*/
9 y' I$ s( j: ~3 t, T8 A/ t! { char ch; /*存放运算符*/
( O. n) y4 v+ {: R" s0 R( Y8 I- i+ z) \: ]};! \/ L4 k% [+ [% V
2 I F+ \* A+ ]5 Xstruct Stack{
: v3 P( \, _! }9 H% e8 m: r# ~ SNode *top;4 Y6 u+ Y" d8 L: F( [& ?. a
SNode *base;1 O) C' N1 I( k
int size;' v* H" S$ ^& R
};+ ~: c7 n9 X. U/ p3 d- o5 d" d9 }0 w
7 O: F; n3 P/ @- t% A# I) j
/*栈操作函数*/& Z7 P$ b1 R, U
int InitStack(Stack &S); /*创建栈*/0 ~, {3 \9 j: [1 n* h" h1 L
int DestroyStack(Stack &S); /*销毁栈*/
( A% F/ S- ~# ~) g8 ~; I* wint ClearStack(Stack &S); /*清空栈*/
5 Y9 |) l3 _& Y+ r" c; Hint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
9 {3 E) j% R7 U9 P$ C2 ]) a* r1 `int Push(Stack &S,SNode e); /*将结点e压入栈*/
5 }* Z" ^- Q. T/ aint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
$ E. J/ E% z/ }& u J, E7 I1 z. D, @# ^! Q8 q8 t
/*表达式计算器相关函数*/# ~; l( O4 U, M) a
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
! N) F; N$ J: h& B3 \/ Cint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/0 @6 u8 m8 d; j+ }2 o0 d) k
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
% F: W5 `% d% _- d1 i' F, sfloat compute(); /*表达式结算器主函数*/8 b4 [( V. E$ T* F3 {- e
char *killzero(float result); /*去掉结果后面的0*/ $ k7 G+ r2 H1 L% M. Q
6 ~* S- a. d* t" [6 F2 Vint InitStack(Stack &S)2 ~: n2 E! B# D# y, f
{# c: A' a' u. y7 X3 n4 z: g
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));" u0 c! K: i, _) X# I' t
if(S.base==NULL)# Z( s4 `6 R; `; q
{
5 |( k0 r. v" @! G) P4 d; g printf("动态分配内存失败!");* \ K8 ~" S! q7 ~$ `, }
return -1;
' e \% h2 K% f4 |. ?) m0 T }3 G4 X3 B8 o& I( y$ C* x, t3 s& c
S.top=S.base;
1 p5 L2 N4 _1 Z# M. X S.size=STACK_SIZE;
, ]; R8 K( ~# `0 ?0 L. k3 e return 0;
+ p4 P3 J* m: I- {: D. T0 m" C}# a( m5 t- M: [5 R# j
% I9 d9 T) R3 e5 |& l8 i _int DestroyStack(Stack &S)$ u" p' Q$ Y# u! C- O4 e$ Z
{
) y f/ v% P0 R( |; x free(S.base);
$ }4 M1 c" c7 m' M0 I2 b3 v return 0;. K( \3 r0 \6 s0 ? S
}+ W" b" l3 s% O+ n- a9 `
4 M9 p: C; P* S# X" R
int ClearStack(Stack &S)( c9 f8 _. }# e2 _. O
{/ Q) e/ G% [ e. g
S.top=S.base;# {2 R/ [. c, g' S" s4 Q3 N
return 0;
# {2 O" e. a4 i1 M- p. p}
" m' }% {, \+ B5 j0 f n& b/ c7 r( D, j+ V8 D. W& S, U
int GetTop(Stack S,SNode &e)
# u; M z% {; v! p6 o/ v( J8 c# J{7 C$ }2 [. _- N7 _: Q+ T
if(S.top==S.base)
, [+ x* h9 b( }) y* W {
& `. U1 m X$ F1 l. C6 |7 h, ] printf("栈以为空!");; ]' i b# O0 k$ R; k+ l: o
return -1;
4 h* o! } P7 t4 ^$ ?( g7 x+ @ }
n* {+ h. T% | k. O) L e=*(S.top-1);* P" c- c1 D! o
return 0;% C8 u+ W9 Q6 a9 l% b
}
4 \% m r; x/ C5 ^9 d/ r P/ y% `3 k) r: {1 X
int Push(Stack &S,SNode e)8 I' I% `$ L0 c' f
{- _7 D: X2 C; q3 k3 q' q) D' i1 y1 J
if(S.top-S.base>=S.size)% T, i$ b3 i( G% M2 d" N
{5 I5 t( O3 {3 H" {* G# Q7 f
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));) j* V) Q* _& T7 V
if(S.base==NULL)9 Q( u9 \2 `( P- [. S
{
1 p7 W/ y% C" ~! x2 | printf("动态分配内存失败!");7 ]( e$ K6 y" D$ `8 D
return -1;
, x! D! A7 C4 `! Z/ U' { }
) [' R3 A( h7 j S.top=S.base+S.size;7 ^% F. m) W* O) f0 R5 @
S.size+=APPEND_SIZE;* ?* z- u5 D3 w( i+ h, r: B# V
}
6 q2 S2 q3 P$ [5 S( v *S.top=e;- |* {4 c. B1 F
S.top++;8 }% L' S W, Q1 ~
return 0;6 A P* Q. s" y" `0 J, V
}6 H6 l, {, Z9 e6 B5 O
' g9 L4 |. P5 N+ y: K5 d$ |int Pop(Stack &S,SNode &e)
. o1 A9 ?: Q8 w |4 c m{
/ q, C* _) `4 g( g8 r' Q$ ^ if(S.top==S.base)1 U, b! o5 J- N9 @. u
{! F% i/ C! c5 x# Q r# D8 v, {5 K
printf("栈为空!");
# B: a2 _6 Y, z2 U return -1;% {6 b2 C! @, L" _7 I, c( j8 J! Y) j
}" B; S0 A7 ~) }9 `0 |" D
e=*(S.top-1);7 y$ e. x5 b* H) z7 [- e
S.top--;
& b3 _' h# l2 [( V6 o. e7 u return 0;
! B% o4 p# R5 D3 w}
8 {1 _3 t) S, S9 i5 N3 c# z
! \8 a3 M1 e; mchar get_precede(char s,char c)6 o! x1 V8 M7 S K0 ~; P- k4 V
{
7 }! R2 A1 H* j% N) J switch(s)7 ]. ]( K" b, s0 J4 [# y
{
. ~+ @7 d1 l: [2 ? case '+':
2 E4 L8 l5 f1 i3 E' E5 F+ v case '-':
2 k. _. l8 q% B/ W/ j if(c=='+'||c=='-')
/ A* x8 H4 N, g: S return '>';( o( T+ L% k- S/ {! v* t" W
else if(c=='*'||c=='/')7 y$ v4 N& Q& I! u
return '<';( D- u6 L, k+ U. f4 |+ I8 U
else if(c=='(')4 p/ F/ P3 J; Y5 w& U$ M) V: P' q6 e
return '<';
: B7 M/ E, S: q! Z, g else if(c==')')
0 x2 s d6 A: U4 O" s$ j7 D7 @ return '>';
9 U. R, P2 H' m% \ else ; g1 T# p$ g& [3 n. |6 [7 E+ j. z
return '>';$ L* W. O4 u2 S
case '*':) ]5 j! u$ ^& Y3 W: N% q
case '/':
3 ]8 f8 {5 v8 Y$ c4 e" F0 b0 [ if(c=='+'||c=='-'). `& v4 U' O% ?8 Z# F; V
return '>';
" G. r& A$ K# K9 l' E! B. c& Z3 ^' w else if(c=='*'||c=='/')
% I2 [2 d1 G( C8 p6 r return '>';9 e1 @5 r: D! m) W1 Z
else if(c=='(')2 `( y% B* ?- Q, M
return '<';/ t# w( x1 y: Z V+ Y7 |
else if(c==')')
+ O/ N$ ]* K1 o4 k: E& h$ Y return '>';
$ F! y9 i5 J6 E( x' H9 _ else! @& \- e3 o) \ a& p7 J$ A
return '>';1 f, w* ^! q7 `8 c% b/ i8 B4 `
case '(':6 `: m( u7 {- J5 T- Z5 S" j
if(c=='+'||c=='-')
V' Z" n0 \5 Y: F return '<';
0 }% x5 y- G! ]1 \. K; V9 [( _! I else if(c=='*'||c=='/')
% I! M! M4 q* y2 } return '<';
( F- H; R& d. K# R1 v6 p* U7 e9 v else if(c=='(')
! B3 p) c6 m" q5 u" c* n! l4 j return '<';+ v8 e" d+ b7 S& e1 m: A9 G* H5 H
else if(c==')')
3 e. S4 z" H6 l; [2 R1 h return '=';& {) P0 a/ ]6 L* U. S+ v+ h
else
( I$ M+ M9 I8 C3 r* B4 j$ } return 'E';
. g4 i) y- y3 t. P1 Q case ')':
( V& c% d" V) I+ V if(c=='+'||c=='-')& O2 T T; F% y! \
return '>';& `( t" D* M4 n; U8 c+ w
else if(c=='*'||c=='/')
( E3 r) z+ g% @ return '>';9 f& {) j! }8 w) ]8 M) _( e* Z( m: z
else if(c=='(')
3 @3 r7 I% ]# G! P, V/ R return 'E';' e# P5 |) K- s3 o5 X% K
else if(c==')')
& A( l9 Q6 G3 n5 p4 C, b; {9 G return '>';
# m$ N' u8 `$ p+ Y( `0 C else
) \- g7 Z k: Q, P/ o5 Z return '>';
- N( b2 o/ B" B7 E case '#':1 @& T3 v( w0 u0 m l+ _) S
if(c=='+'||c=='-')9 ]. Q/ A$ Y4 m+ Y
return '<';
" ?( R: B" ~4 V/ C" i else if(c=='*'||c=='/')3 |" a# l- ~- h1 c
return '<';4 k+ u A2 ^# O/ j1 j
else if(c=='(')
6 d2 r8 a/ O) A- V$ n. U! m; K return '<';
7 y ?/ z4 F1 k a G else if(c==')')
1 w7 c) T( Q1 k6 d; X6 Z return 'E';
. d* ]: h) A. Z else8 M8 y8 }$ v& |$ M* ^4 U: {
return '=';
; O! X" e: z# w default:- ]- c: R$ D2 L6 K0 S6 {( ^9 Z
break;! r! @- s6 @/ B) p) {
}5 e8 v' x9 c" v9 J3 L$ e" K, J
return 0; * `' s" n. g1 g% Z
}
' y1 ~; H, I( ]4 p" V0 Z/ u2 Y5 N+ H; H, F0 c1 p4 j
int isOpr(char c)
( H c; m8 M6 Y# F{+ e( s2 ?# N5 h# a3 r- J3 r
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')2 W K# y+ D+ @5 C) E! q( E
return 0;
& z0 A) I" Q1 k# N7 Y. S else - q; s: ^7 T; T( E. e7 P
return 1;
0 I" F, W/ Y+ \, ~& l}
_) F2 }, o: d6 r+ ^) D* M# g$ ~3 T
float operate(float x, char opr, float y)+ c. L- v, G" Y6 x( @
{
1 P* v, @" L. K/ \! U float result;
. v6 G0 \$ S2 A9 }& a switch (opr)
+ G8 x! A" \- g4 @ {& ?4 Y+ r2 [0 m4 J! P' i$ s
case '+': 6 ]9 A1 i1 O$ h2 \ a
result = x + y;' O# I6 n/ x7 v- x2 a
break;
+ J# Q, [: X9 P; D( L case '-': / u; z3 v" }7 K4 L
result = x - y;
' _7 `) z; B% K# F9 y break;' v3 f$ H6 J* i. D
case '*': / W/ U3 ]1 J' t" Y% B' G9 o
result = x * y;
. w( N- U6 R7 g break;( J- R' R# b2 r M$ p% v: e/ x
case '/':
% S" h1 F* q5 x9 [) D3 K if (y == 0)" _& B+ t9 c! H3 T* ~
{0 c1 j6 ?! u! h; l: a7 e
printf("Divided by zero!\n");6 v& Y5 m8 w) G; ] C# q. C
return 0;
* E q2 x1 K7 h; U; g }/ l* t _1 z4 K# ?) x- ^: z5 ^
else
& B b2 x9 T- T9 }; w: l; F {9 g! ^4 L5 w7 v" G- y
result = x / y;
3 h1 p1 \4 _/ o break;# D2 ]1 S+ U6 ^6 C3 z. a
}5 Q- h; @+ Q! K+ ?
default: " a5 j2 o' b* [* x- |: d
printf("Bad Input.\n");
1 Q2 ]# S& }3 h0 G: x1 i return 0;6 Y8 R* ^0 c8 a, `8 ]3 L" W6 C G$ ^
}7 |0 g) B% G- N! r$ y
return result;
7 Z o k% o8 H5 b}
7 y5 h$ ]; }# _" w y$ `. |
5 j, @* [7 A8 v- M a2 cfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
. E# B9 |& Q6 {* F{
2 s. _: o5 R) ~ Stack optr,opnd;9 `+ `& x P/ l6 z% `8 J
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;2 F7 d" V0 `, r- C
char c;. I0 O- O( X; O! _5 }
char buf[16];) J; P# `' }9 L) b
int i=0;. F$ x# q0 A# X# g: b& l( g; b
' i7 U& u* ?5 d h InitStack(optr); /*用于寄存运算符*/
) g1 |3 M6 `, u9 B1 V InitStack(opnd); /*用于寄存操作数和计算结果*/, }6 T2 D8 y+ T$ w
memset(buf,0,sizeof(buf));
. z6 x: d9 B) }9 r* M
/ T0 N& [$ i1 k3 h t! G printf("Enter your expression:");/ `) m; i' g, l
$ x$ U5 _5 a) [ Z opr_in.ch='#';
9 G M4 ?( b1 `0 D6 x Push(optr,opr_in); /*'#'入栈*/5 N+ t) Q p( P( Z5 v @
GetTop(optr,opr_top);
5 O# s" h' _2 B6 K6 ^ c=getchar();
0 W. E7 b! |1 R$ M! L while(c!='='||opr_top.ch!='#'): L2 H" h3 z. q D }* H9 f [! x
{
$ x, e: w: v7 C. M$ [ v$ \( d/ \, P if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
5 Q! o6 J- D5 Y c Y: Y {
5 O0 ?& \' i$ Z6 m, u buf=c;8 m3 @9 W5 t3 p- R- g
i++;
) ]* N: @7 [+ b q6 O3 [$ ? c=getchar();6 z; |8 M! s9 @) X. @' l
}" b' A1 H0 H5 ]
else /*是运算符*/
* Z2 c. y8 ]) ^4 ^9 H: M9 o u! E {
; o% F: R1 f9 y' y! A# ?* l6 F3 P buf='\0';+ n* B& _& F5 H) q: ]
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
& x9 u+ g0 y+ J, x6 f1 N- ~& L {
# J2 M/ w- |1 k7 w8 ?2 D opn_in.data=(float)atof(buf);! E: w7 w/ s6 ~9 K5 l* o. ~
Push(opnd,opn_in);8 r# g3 V- y) A) d3 U1 w
printf("opnd入栈:[%f]\n",opn_in.data);
# v- A4 j+ e+ g7 i% C3 C i=0;( U7 h7 `$ x9 Q3 t
memset(buf,0,sizeof(buf));
; L7 @) q1 U; K6 A }
U" f& i: O+ t8 f opr_in.ch=c;2 z* Z$ j: M0 X6 a: J: X) U
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*// p4 M. s) {; J/ @
{. I+ ^9 c8 K* K4 g8 B
case '<': /*优先级小于栈顶结点,则运算符入栈*/3 s5 E4 B& Y' ?6 C5 W
Push(optr,opr_in);
8 s9 ?/ M7 h) x7 s printf("optr入栈:[%c]\n",opr_in.ch);
) }" ]( V" G( S3 c/ w c=getchar();2 O+ t8 @ ]& h- P' \) D: e* k
break;3 n) y. \0 k. n9 P9 s7 h j! r
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/8 @3 R8 q& l0 N) f, ^4 W
Pop(optr,e);
( E7 W9 \% E4 M6 W/ z; u o printf("optr出栈:去掉括号\n");
9 H! y+ g5 n3 e. ] c=getchar();2 f5 }; B/ a/ U! g
break;4 }/ G0 ?) ~: B8 a% \
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
( C' D4 L0 c4 x- R& l Pop(optr,opr_t);0 U* V$ ]8 {' y, k
printf("optr出栈:[%c]\n",opr_t.ch);( b! w2 v9 e5 Z1 a% m9 H
if(Pop(opnd,b)<0)
% p& Z6 c# r$ D. g! O2 ?" n' E) { {, ]) T5 i/ b% I- c, `" V
printf("Bad Input!\n");7 o2 V) _( c+ G6 r! b q; ?
fflush(stdin);
% b' ?0 R( Q* g4 p; c% t" ?9 m return -1;$ f, [8 }$ g$ O0 e$ |/ p
} _; V! V+ ~! g0 U
printf("opnd出栈:[%f]\n",b.data);
' U% X3 L! S: T- W' @5 j: n, g1 h if(Pop(opnd,a)<0)
4 G# m& l# H- `8 Y0 T {
' q1 L- i# F1 Z' w; x! F printf("Bad Input!\n");' o4 R& q1 S$ H& w0 l4 a" \' `
fflush(stdin);
+ [. V6 w1 Y2 m# D return -1;, l8 F* {8 C- a
}5 p5 g: N3 x8 Z4 H
printf("opnd出栈:[%f]\n",a.data);
7 ]2 \3 t* `# _4 ~; z4 y9 H opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/" s" D) ^; { A( l; @6 T# L
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/0 ~ ^/ h2 h8 h0 P2 B, F
printf("结果入栈:[%f]\n",opn_tmp.data);
# _, d, m' i' E. Y. B+ F break;
6 ^5 J* ^* b/ u9 o! Q! s* D5 @ }
4 P @/ ]" N% O/ ]! z* j, q }3 x3 z* | O5 j
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ : S) r+ W H" E; l' z% ?% C
}# d' u* y) A, x' o
GetTop(opnd,opn_tmp);
6 t% N7 N k7 J2 N* \3 r- P9 r DestroyStack(optr);- ^% m8 m0 K. K" T
DestroyStack(opnd);: H7 D2 q4 X( T [, u3 F( v
return opn_tmp.data;* Z2 n e9 l5 V+ [, d! F, @
} B+ P+ I! Y% }
( }3 Q7 [! m% t4 K
char *killzero(char *res,float result)6 K h2 o+ u* R0 F; C. P9 K
{
- l* Q u5 L7 R int i;4 N8 J, k _" X) B2 H8 I
! q2 L' g2 }" i) W
sprintf(res,"%f",result);) }3 R! b% y) v" x
i=(int)strlen(res)-1;3 X- m% ]' {2 o
while(i&&res=='0')
; E% { }* B- S {! e) Q/ i9 {3 ]: t! V
res='\0';3 } [& _/ x2 B4 W) f
i--;
! W: m% _2 T8 g! ? }
9 Q: w# p. T* ]# j! I0 b3 q if(res=='.')& d! ]! X/ Y k( o. _" D W
res='\0';
: l" @# ~" w+ a4 x- D/ ] [ return res;% }, v, `, z4 x3 ?. K1 Z4 O: C0 q
}
3 n' p$ \( g7 b# R$ }; X9 B
& X* b8 p" t1 ~8 i& E1 r0 [+ S' l) Kint main()
" r! V2 z" F H{
4 S! k; F: j3 h& I* v4 A4 g1 _7 a7 f char ch;
4 z9 _% f, K& [0 _# G, b char res[64];. X" ^$ Y# W7 @0 Y, M6 u! S
float result;" q8 G% K+ I( A- q
while(1)
& j$ o0 { r" E" j a {: t/ q! `7 c4 W4 m1 q7 Y* I8 O
result=compute();
1 Z% J8 W8 s2 j: l printf("\nThe result is:%s\n",killzero(res,result));( L! E4 g7 S2 e# ~5 w1 d. V
printf("Do you want to continue(y/n)?:") ;* e/ N- _& i; e! a
ch=getch();
! y: M$ T2 c% T' `8 v, I& W1 W$ l putchar(ch);
& [7 d: ]7 @' T' g if(ch=='n'||ch=='N')
0 {8 k$ O+ K" _& A* m; x# e break;& h8 \* e) E) @
else, h3 ?; j2 C) h+ \
system("cls");8 e8 V! m, |6 C Z
}
2 u. ^. p* Z$ z. c, _! {8 K return 0;) v$ p4 W9 @3 U- L, p
}, T# _+ q; P. Y0 g1 U
: \* I% G# n, `. }4 l[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|