标题:
C语言表达式计算器
[打印本页]
作者:
zw2004
时间:
2008-1-21 17:17
标题:
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
: G' f: Y! ?) Q& v' w* j7 P
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
1 c- `7 f% g0 H/ l: z9 ^9 M
/**************表达式计算器************/
( P- Z u n6 `& q
#include <stdio.h>
" Z0 { M. J0 n; B
#include <stdlib.h>
) J/ r) o. E, J5 w! h) ]
#include <string.h>
6 c/ U# e1 O1 `. G
#include <conio.h>
6 j# U- `, I. H7 b$ ^8 W
#include <malloc.h>
& e/ _/ X3 I# r( M- v" ?
! B5 z9 N& ^+ N y3 O
#define STACK_SIZE 100
7 Q+ q4 l# q2 M- L6 g
#define APPEND_SIZE 10
d. d( |5 d. t% m9 ]! L( v3 {
+ o6 a! A3 `0 b8 ?" V2 e0 M
struct SNode{
1 A% @+ n: y+ J# V
float data; /*存放操作数或者计算结果*/
+ U3 t* |; f1 q F
char ch; /*存放运算符*/
" I6 e) n1 C0 v! X0 j# t$ [- A1 C7 a, c
};
3 i4 ?8 D& h0 G% j* a% [5 f
+ Y p0 Y, u4 `
struct Stack{
- r' ^' {# S3 B# g: s& U+ W
SNode *top;
% p' j' f% R" j+ h. f1 V
SNode *base;
$ O% i9 j& a+ V% t* A
int size;
9 q- {- i9 z$ t! g
};
( p( s8 a1 v) l. T. ^- h$ l J
% w+ `3 w% s, I# w: K3 ?7 X5 h
/*栈操作函数*/
' L. n4 E8 R6 k) `% e- l
int InitStack(Stack &S); /*创建栈*/
* x+ w8 }2 L+ {3 @! Q9 r& X5 J; ~
int DestroyStack(Stack &S); /*销毁栈*/
& G* a# {; L( @1 D; p$ X' G6 }3 g
int ClearStack(Stack &S); /*清空栈*/
' B! j" t T- ]5 P& Q. L. D
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
1 H0 K8 X2 }: e/ f/ g) V# E
int Push(Stack &S,SNode e); /*将结点e压入栈*/
" c# {8 A# r/ y a) R
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
! T( ], Q, P4 G; q9 Q! W
) m5 K. c' D; I+ \- D( i7 d8 w
/*表达式计算器相关函数*/
& ` e" M6 ^) q0 l9 c) t
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
* y' a$ v+ }* a# i! a, }0 Q
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
P( ^1 z, P& U3 G4 g% ~+ t
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
# h* X; D1 C: _; Y, v
float compute(); /*表达式结算器主函数*/
1 N1 n7 d C' v" n: |5 B9 n( {
char *killzero(float result); /*去掉结果后面的0*/
0 {: B) V0 S- P* Q8 ?
$ [* N/ m/ X. ]0 n$ i& F* l; }! J
int InitStack(Stack &S)
" m3 c& L; N& w) b+ F( v
{
: M. h* p, ]" n6 \6 a( r" Z T
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
|7 M( g& W) y, @, `( ^, \; c
if(S.base==NULL)
k' n; O# Z' F: P9 A* l0 o
{
5 |9 m# e: P" c& h% v
printf("动态分配内存失败!");
" l6 B. X& Q/ }( o
return -1;
7 h2 O$ l! w/ E) f" d( v0 [
}
$ Z1 D6 ]: j8 J! ^3 `
S.top=S.base;
* O/ I* `9 K, U6 K* y
S.size=STACK_SIZE;
% `. f" e6 z5 n7 V: A! W7 X6 q
return 0;
1 [0 v% r* ]: }8 Z
}
* L) M( `( d8 r3 ~( S
$ G3 P# m' t; ~
int DestroyStack(Stack &S)
7 }4 n) R6 _. S1 r$ g! M
{
! l7 J+ t: y4 R+ i2 J; ~9 Z
free(S.base);
8 ^6 L0 R6 j) S- \4 D2 f
return 0;
% D3 Y- j4 I! k4 D
}
: R. E5 Y3 I1 \9 H
; A, k0 z1 Z/ D- {& F D# z
int ClearStack(Stack &S)
/ [6 o% _4 f, s( e4 q
{
2 V# X9 h7 O* f
S.top=S.base;
: v& o2 G: k( C8 @# `
return 0;
9 J6 |4 W; r# C# a6 e; O
}
1 w9 `- [8 l& P7 B' \2 g" E. z
0 m/ w+ V: L' k- a6 E& W: R
int GetTop(Stack S,SNode &e)
, r, w: X& G- A; G' O" l
{
, Q+ X0 F% o* i4 c* O
if(S.top==S.base)
( C& t6 `% C" [1 `& n- u
{
# e4 a: H* s5 X
printf("栈以为空!");
! i; s3 E/ T/ Z' j
return -1;
9 w9 I E$ j4 v' u" L' b' ]# }
}
7 P+ J& `8 w, s' d+ o4 f1 M- u
e=*(S.top-1);
5 P% d4 B5 n+ [% |, U
return 0;
4 ~8 S! ]1 d+ I) V0 @
}
' F3 h, m" S# X( B% P$ h: {
3 S/ \: w6 ^& p U o
int Push(Stack &S,SNode e)
3 Q) Y$ y: r8 l, q5 ]& I
{
) I3 e) ]) _7 T5 h* ]
if(S.top-S.base>=S.size)
: Y0 {( D+ [5 J+ Q3 A
{
6 z2 _7 @, @ M L4 h$ h% W
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
7 M* T- L/ k* u; Q/ U2 V, P
if(S.base==NULL)
5 T k, o2 ~$ [% C* X
{
, L2 T; H/ v' Y" a* e% c
printf("动态分配内存失败!");
8 n+ G- G! b% N# q! c! n* F
return -1;
i; G9 v! N& V
}
/ ^3 [! d) c8 j, p/ N# p# U: C7 s3 m
S.top=S.base+S.size;
: ~ ?+ O* K1 _% {
S.size+=APPEND_SIZE;
4 X i N% _/ }! R% X$ y
}
/ g5 l% U5 e% v2 f. ]3 F
*S.top=e;
5 R U* Q9 ] Q; g4 a# `
S.top++;
) E ^' S, N0 X- a( q, u4 @
return 0;
; |6 F* r4 G& g+ H( |' S* u3 W V
}
r8 K y( K* o9 U1 q. U- ~1 U
8 @- W0 c0 l; _$ E: ^
int Pop(Stack &S,SNode &e)
% F' V; s6 k- L
{
/ q! F6 k: p' Y2 Z9 v: i( ?! ^
if(S.top==S.base)
$ V5 Z9 U% h& @- r' b4 V$ f, x$ v: q
{
1 V4 ^5 b( x: V) z$ b" E2 o
printf("栈为空!");
) L$ q1 M1 j( D+ x$ y/ B e$ r! m
return -1;
/ y+ p t" g' |* y7 |5 a4 R
}
7 W: @# s9 b" |# }" y
e=*(S.top-1);
5 n2 Y* C9 o- E
S.top--;
7 K, ^8 P7 H& g9 }; k4 D& A
return 0;
$ J* H0 U* B# i+ s# a4 t$ }; H. [
}
: O. B* @% K$ T2 w3 d
2 Y# ~& k) g7 m- Q" }6 u/ H
char get_precede(char s,char c)
. B1 y9 o7 b6 B- J' o T, _
{
( F) A$ g9 V" W( J5 }, r( W+ u& q
switch(s)
& [9 O* u+ w) E d, ~) ]; j0 _7 [
{
) l- \7 U- T D# Z3 r% w
case '+':
. y% Z) w1 W9 J) R2 o) @. B
case '-':
" m/ }; d" T6 s' [& z
if(c=='+'||c=='-')
6 f' B5 O P; s: V0 v: Q
return '>';
( ?$ D; p3 J0 d! F# ]! ?0 D
else if(c=='*'||c=='/')
4 `/ _0 B, S1 a: N
return '<';
5 e7 g3 C' [! r5 o* d0 }5 x# I
else if(c=='(')
1 C1 P; S$ m1 {! t9 A+ q
return '<';
' c5 J) w" r) i: a! n4 X
else if(c==')')
+ ~: G' A& t" l5 X* y; U7 E
return '>';
& T7 t/ Q3 ~! |/ |* ~4 ] u
else
) n0 g4 g6 e X2 J" w, o9 j
return '>';
5 q- I2 Q5 @5 h) K/ r2 o7 u
case '*':
0 d& \" l! W; y2 W4 W T% e
case '/':
. {# C* p& e: u0 y1 Q6 ]3 }$ O5 R1 r
if(c=='+'||c=='-')
# i0 a/ u( X4 L$ [
return '>';
% I& C' S+ r D& T _
else if(c=='*'||c=='/')
, m+ v* l W; B2 W8 ]" G g$ i
return '>';
8 R& w. k+ F% I8 j
else if(c=='(')
6 n6 h1 b' Q% \$ w- P
return '<';
' J U* @. ]/ H
else if(c==')')
5 ]( P7 h4 A+ u0 M( c5 d. V
return '>';
) c0 b) f' _! e8 C" v. a& r
else
4 g Y* Y- T! g, I, P* K* g
return '>';
$ `+ b7 o" h h- ?. G
case '(':
: P. | g7 q6 M
if(c=='+'||c=='-')
. l# `) G, N* H% m4 _
return '<';
, g, {& E% x8 j3 L4 O
else if(c=='*'||c=='/')
% S6 t ?1 r* z
return '<';
" ^8 B! F) a& C$ L! M
else if(c=='(')
! }, l5 W' `& W4 \& F* y
return '<';
5 ?/ G# }4 V% P c
else if(c==')')
+ u& x, Z. y+ v! m6 T) Y. A
return '=';
3 K' ?; G5 T% H' x+ h8 R
else
% L5 x8 `& @/ C$ i- s3 `* W, q
return 'E';
$ I& V$ n7 Q$ [2 `: |' F
case ')':
# O2 N8 B b- H8 @- l
if(c=='+'||c=='-')
6 q+ h. {8 J% k( t) \+ P% |
return '>';
8 z q+ j$ d- \# j9 X0 e4 }
else if(c=='*'||c=='/')
' ]6 U: }0 o8 e G! V8 w M$ L6 i- X
return '>';
! ?$ H; m' g- V. P
else if(c=='(')
, E" o7 w$ P3 A& E# t& \+ I
return 'E';
L' l. }% L# |
else if(c==')')
# n' j( z8 S; `0 R$ `7 t
return '>';
# B6 i6 }* z/ T! t2 Y
else
) @# V k* ?0 {# T2 q% M
return '>';
S( C4 J' x5 J7 q0 H
case '#':
3 z" h* y0 p, {; ~% O4 T
if(c=='+'||c=='-')
+ N! P2 @' o, ?. z: u7 N1 R0 c
return '<';
( J8 R. w9 }# p8 M: Z
else if(c=='*'||c=='/')
, x2 P! R1 {" g2 [5 k4 D; \
return '<';
4 E) A) E8 W, {- A3 g' F* K; _
else if(c=='(')
, w" L" f2 F8 S" u4 N- K1 ~
return '<';
2 c0 x% z% P4 r) x4 g3 i4 t6 Q
else if(c==')')
' Z9 a# ^4 r2 q& @' f
return 'E';
( c. ?' U, o5 h+ c3 w; S, T
else
5 q7 D7 C; N2 Z* M
return '=';
( i7 W; V% l T; r' v
default:
" P q6 a; ?( d8 T
break;
" W- L6 f& {# ~+ q/ U
}
# m6 v+ c: [$ H: i
return 0;
; z$ ^* M3 f# t
}
: V! b; k' H, i- x5 H
: w* D( v2 Z% A7 q7 C# e) g
int isOpr(char c)
( Q7 X4 h1 S& _: t! q) O) }5 r, `; [
{
* S" e# e" T* `. [7 y
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
1 L- i1 V8 D; U \* L
return 0;
: r# d. \' }0 R7 j# @/ g$ ^1 u
else
# Z+ D7 G" I/ W. b4 o# O* c( v
return 1;
# N( f& X- s6 V2 u; n# Q
}
! B/ [1 i7 b! L7 Q' A
$ s M. k+ w) A+ Z$ K/ V
float operate(float x, char opr, float y)
& @3 U. B. ~$ s
{
- l2 [/ I y+ {1 M: m/ g) K
float result;
. R9 k( d2 C& \$ X, e
switch (opr)
) r) F8 K% ~/ d7 x$ Q" g8 A
{
! m" n, c3 O- d0 M- @1 c6 @
case '+':
$ e6 e8 V& B! R5 h
result = x + y;
1 i0 r5 @: S; p8 o7 @% f3 F% B
break;
! n8 X5 c1 q. w- M! W/ `
case '-':
4 w& ]0 B$ \5 j* L
result = x - y;
7 D0 \" C" {2 l6 |
break;
" ^# a0 P; U2 i% v
case '*':
8 o1 u/ f6 ], N9 O5 p
result = x * y;
! c, r" v1 |" o4 h3 b1 V
break;
6 O: w$ E/ l- P0 _/ c6 ]
case '/':
+ { l- V! I& U! w
if (y == 0)
$ Z4 y& j9 n% D; X% q
{
: S3 N1 y0 L( y& w% {. w1 M
printf("Divided by zero!\n");
5 b/ |& N* x4 x0 U
return 0;
0 l; O+ s$ b& c; {4 _" [
}
( N$ |: U) o! {0 b
else
% u" q; q/ P# B
{
% m; j, ?: H. U
result = x / y;
1 R# g) U$ |8 w; C! w/ H
break;
6 [0 [4 Q3 |1 i; C
}
: l; [5 F* Q+ I% e
default:
1 }- _9 d& v9 t9 h' y" I* h
printf("Bad Input.\n");
2 W. I* ^: e- O8 B r: Z4 {! c
return 0;
+ M8 R: J: [1 h
}
! M/ W5 O! ^+ Q) _* L
return result;
+ o2 W. {; b0 s' r( D: Z9 t! J
}
q1 _: J' j- ]5 o5 d2 o$ F
. d1 W7 E7 d& o0 i8 T
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
( V& x0 q; h; J
{
" @0 D) ?8 v# [: \
Stack optr,opnd;
# y9 ^: j" C. r! j: o% t9 T8 p
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
/ A {2 ^) D, ]' p' S! p
char c;
1 n7 O$ _1 b0 K. r; X" B
char buf[16];
1 K* D( M3 _7 \, C# G
int i=0;
8 I; b0 g, z6 C0 ^7 | K2 D6 W
+ B1 h$ Y8 e& p5 |
InitStack(optr); /*用于寄存运算符*/
* ]: n: X: t: m) g- G
InitStack(opnd); /*用于寄存操作数和计算结果*/
1 o ~" O- l- ?5 Z1 z( e( e$ |
memset(buf,0,sizeof(buf));
; V) |+ b, }! x3 t& R5 F
- N& g7 o, N, k
printf("Enter your expression:");
8 j4 }/ P) h+ f* j o- U
) U! q# S8 @/ f
opr_in.ch='#';
O0 @6 ?4 h% j7 U! v
Push(optr,opr_in); /*'#'入栈*/
4 z7 d* v9 h2 S
GetTop(optr,opr_top);
: x$ ~7 ?( t* y
c=getchar();
: f9 ^% u) a2 C" g- k
while(c!='='||opr_top.ch!='#')
4 f" Z! {8 B/ j. g5 D
{
# p+ z# Y/ | h( k8 H/ T) m
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
1 R' `9 _& h% w) I) V& ?) B
{
3 U9 m1 D* q1 `( j
buf
=c;
" i* m( V, q4 I9 O9 Z
i++;
* ~0 X/ {& K9 `
c=getchar();
) z) [0 R& E/ C
}
' r: D7 \4 |& x; U5 G0 ?% I) i
else /*是运算符*/
) h- s9 }& N8 \8 Y7 Z
{
+ n& r+ k# p" p: q% ?
buf
='\0';
% ? p! E, \! \/ J2 i
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
" _/ L' }% \/ t8 h6 U
{
n! c; ~6 u q& w
opn_in.data=(float)atof(buf);
! H$ t- w' A4 c% J/ T% Q; I4 g) I3 e
Push(opnd,opn_in);
) o. _* B- Q$ s
printf("opnd入栈:[%f]\n",opn_in.data);
: u2 [/ F0 ]2 t2 T% |8 f! U
i=0;
% m I" T0 ^5 r& \" L; m
memset(buf,0,sizeof(buf));
n: A3 `0 h! x* r! z
}
, X$ M; V0 K0 f5 I' ^! s) G
opr_in.ch=c;
' J2 \* l9 l9 l( D7 }4 G$ _; u
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
, L$ \: t D0 P9 A. P8 s: l
{
, T# e% @( l: p3 d: M
case '<': /*优先级小于栈顶结点,则运算符入栈*/
9 m" i0 w+ R! W% b1 H
Push(optr,opr_in);
* j Z* f8 r/ i0 y3 m% M+ f v
printf("optr入栈:[%c]\n",opr_in.ch);
! l& f8 J5 \1 Y' D2 B% l" i( W
c=getchar();
0 R/ K E2 v0 f D! [6 v9 T
break;
; w6 e7 K/ p* P. a; X' m) F, {
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
' \. l" N& F/ i2 h: _
Pop(optr,e);
3 D" E: |% [$ N1 f2 k
printf("optr出栈:去掉括号\n");
9 V: A# `' C f: z
c=getchar();
; \9 ~& X$ j+ z3 t g
break;
4 [9 b8 X. m U- Q
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
1 D0 H- y4 J9 s; q5 O( @7 ]
Pop(optr,opr_t);
8 V! [9 V- q, s& D% [/ _
printf("optr出栈:[%c]\n",opr_t.ch);
" |" H- W$ k3 E! x- ~5 a
if(Pop(opnd,b)<0)
7 M& s: P6 F! T; o. r( `
{
' }; D2 a4 v$ j# Q5 l. F
printf("Bad Input!\n");
' U: M* ]/ K3 _# ]7 }% g
fflush(stdin);
0 n/ E0 G2 Z5 r+ ]6 B- U
return -1;
$ L4 j g/ s% X3 Q' T$ M& b0 k
}
, \5 P& t- m( i6 n2 _- D
printf("opnd出栈:[%f]\n",b.data);
, k: q) F; d% G9 J& A
if(Pop(opnd,a)<0)
0 F. {7 B% Z8 p3 q
{
& y& f) y# |4 R; c: A4 s; y4 A
printf("Bad Input!\n");
' Y' q5 d8 K* ]& r6 h. N
fflush(stdin);
# O- a4 u& K2 ^6 K
return -1;
6 z8 k4 u* T; d( L
}
1 k- M' M. s. u8 M
printf("opnd出栈:[%f]\n",a.data);
R1 u; Q# G) r# b
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
; b0 F1 B5 S2 I" K) A
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
7 l7 {+ ^; L7 n3 o
printf("结果入栈:[%f]\n",opn_tmp.data);
% z" @6 I: P5 j$ z+ g9 e0 q
break;
# `# E4 E( T% V( G+ G% s0 U
}
, h1 W; i( K: G5 Y; C( C$ Z1 z
}
- ?& j; c! R3 P+ P" n
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
; ]5 u# z. E; w6 ~" w) B
}
% }) M) `- ^: I U1 y, `
GetTop(opnd,opn_tmp);
5 k" K' m. i5 \" G; p; q0 m
DestroyStack(optr);
1 _! h5 a; D1 X/ v% g
DestroyStack(opnd);
. t% X5 ~* g; C* J k: |# R
return opn_tmp.data;
8 N& U4 A) g0 G9 o$ e. ]. U
}
/ T% \3 V/ A+ s4 `
1 _5 B$ N o. E
char *killzero(char *res,float result)
3 }, G* D0 m9 w- F; a& {
{
8 b" G" m( m$ |
int i;
9 {4 Q4 G6 r# C3 R. C+ R2 v# n
8 a0 T( Z; C' K# O9 c1 `
sprintf(res,"%f",result);
. y! h/ j; T" ^$ o# j+ n
i=(int)strlen(res)-1;
8 X0 R, v0 N8 O$ N* u' D3 g
while(i&&res
=='0')
: X9 G: N' p9 Y; S$ z" ?# L
{
' E" r" M7 F/ Q- S
res
='\0';
3 \4 U! A3 g2 e& ]7 G1 p
i--;
8 I' P% N2 J: Z
}
) n6 P, {* V8 y6 t( L8 h
if(res
=='.')
/ z2 p8 F4 f# S3 r
res
='\0';
: d1 D) B* I, @# R' d$ }
return res;
4 ^% I1 b1 v+ V# Q2 w% ?
}
0 M1 q; f# w6 n
% M$ A$ l* h$ T( M8 c
int main()
% L% `5 g0 [. D( d
{
+ E; [6 f0 |# D8 u- H
char ch;
9 m. I) L7 p% x5 F! ?
char res[64];
9 O0 o* r+ |/ a; i5 X5 e
float result;
9 X7 Q& }6 \9 u Z2 d0 P+ |
while(1)
3 N0 Q' V( t& D
{
4 t6 S6 o+ \' ^% H! S
result=compute();
) \3 U, A4 s# c& N
printf("\nThe result is:%s\n",killzero(res,result));
. I3 c5 {; V8 N! S* t4 @
printf("Do you want to continue(y/n)?:") ;
$ X& Q6 u( g* l* e. S) r; l7 s) `
ch=getch();
3 C, _* z0 L- S/ R8 X) _7 E+ t B
putchar(ch);
- D* n' v4 ^; [# N3 B
if(ch=='n'||ch=='N')
( A& k" y$ F7 D: \. S
break;
. K8 s# [5 J( g4 h3 J
else
" J, v5 t6 I+ Q$ p. X3 ?
system("cls");
+ E, C% k* q) k7 F, v7 D
}
% i, _+ I- @" `* @# @ C7 e
return 0;
$ l, E _! Z0 j H
}
/ j' \$ |- x; _
* R* z- S( A# ~ u
[
本帖最后由 zw2004 于 2008-1-21 17:21 编辑
]
欢迎光临 捌玖网络工作室 (http://www.89w.org/)
Powered by Discuz! 7.2