标题:
C语言表达式计算器
[打印本页]
作者:
zw2004
时间:
2008-1-21 17:17
标题:
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
0 C4 u4 b' o0 s
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
7 e! q9 X: A* F) t. S
/**************表达式计算器************/
3 A4 ^/ ~7 G/ r1 d9 Y
#include <stdio.h>
: x3 M& i" T3 R6 ?5 [
#include <stdlib.h>
8 } E5 O" i& o9 n- C2 b
#include <string.h>
8 S# B0 |1 a! U) v n$ z0 Y3 F
#include <conio.h>
3 I1 P# r, I( U. O/ B
#include <malloc.h>
# e! Y# I! `$ O7 {) H
" P! G" d) I' @' Z; c
#define STACK_SIZE 100
& f+ t2 K# m: B$ O' z
#define APPEND_SIZE 10
, Q3 T0 f: z4 B" v, M
9 _0 I( q- j/ K5 m
struct SNode{
# C: r9 m5 L/ G) e0 t
float data; /*存放操作数或者计算结果*/
, B7 N* r5 e) W. H2 F7 ]+ ~
char ch; /*存放运算符*/
8 p' b; Z( @, \/ C; p1 H; \
};
9 K5 t b/ E- q# H& C& h( @# x
; i- S- L2 M1 u
struct Stack{
" Y' ^0 ?! {6 M3 Z* m
SNode *top;
0 B' W l; d t# ?4 i$ M& i
SNode *base;
4 i) h u U4 G
int size;
. ~' [" m+ M% F5 v; R
};
6 c: X) o/ \. N: J2 I6 ~1 j, Q- l# T
& d# I/ @/ p' J6 n& I( A
/*栈操作函数*/
6 ~1 r& j3 O E( {8 g
int InitStack(Stack &S); /*创建栈*/
1 B" x2 Z$ `) j
int DestroyStack(Stack &S); /*销毁栈*/
2 |" f7 i! T/ H, o/ x% L0 [) y
int ClearStack(Stack &S); /*清空栈*/
* s3 q( T5 c c' Z% g
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
$ a) U& d! s1 ^: v- J
int Push(Stack &S,SNode e); /*将结点e压入栈*/
5 r0 Z4 I/ [/ W/ a
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
- N- W; t7 ~, M+ D5 `$ V. a
' {! a; M% H) k' q
/*表达式计算器相关函数*/
1 [. q+ G1 u; @( b7 h
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
, U( y3 }. v% A# ^
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
) D' H6 w7 y" x: e1 }, t# K! o
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
2 j) V. |9 b7 j' N8 I+ Y/ T. p) O
float compute(); /*表达式结算器主函数*/
j F4 U5 n: @
char *killzero(float result); /*去掉结果后面的0*/
) a/ p0 |) V/ M& a
3 t% t1 k' c- H% L( G
int InitStack(Stack &S)
( F+ J8 Z- ^' f7 O- i
{
6 L! I$ S; ]8 y2 \* S- o; L# R
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
t* L* L# }5 ?8 `+ ^; G( p/ h& r
if(S.base==NULL)
% j* P' l# K; S v, k
{
' W7 j1 c; D( L
printf("动态分配内存失败!");
" U- { z1 e: \& A* r
return -1;
: F/ w1 v; A1 Y9 A) |* A( s# W: p
}
5 z6 V9 J: x; N& O
S.top=S.base;
8 g" z& S/ q9 C5 s% T
S.size=STACK_SIZE;
3 l0 |! F5 s; B* W1 s
return 0;
. |/ I- h& m' }- ?9 ^9 {& Y: G9 ^* {
}
& O5 E) n# \& k% G* a
( w; G5 M' l' i, m
int DestroyStack(Stack &S)
; P( ?/ U% w p& i) @ A
{
]; W; ~& Q9 ]0 W! K2 {
free(S.base);
* p! e; `% \+ }5 Y& P5 e) l3 ?
return 0;
. q* n7 k. p$ q5 h t
}
) r9 w$ a% a+ m; _$ \" P, l
i6 Z/ I7 r$ h7 b6 }1 Z
int ClearStack(Stack &S)
2 i1 _9 b' |' o
{
. N& z& m- A6 a8 _. R
S.top=S.base;
0 F; {' W5 h4 W) o- \* J& k
return 0;
- C, V* t# w( ^( C& b
}
+ |+ V0 A( k* r2 O2 l# Z/ u+ Y; J4 P
% @. K$ _7 i( {, F( i9 @
int GetTop(Stack S,SNode &e)
9 `% d3 f: g9 Y
{
% w: Q' s- i3 c7 o; m( k% p
if(S.top==S.base)
& }9 m* v) T p; p* ?; D
{
1 x7 ?) V: M' z- Q, n+ J
printf("栈以为空!");
% G' R! P2 e+ C
return -1;
4 \& C& C. C8 z
}
9 e4 Q2 v2 Q1 V# @2 I. `
e=*(S.top-1);
9 j, K, Y# x! f8 `& W% c) A$ Y
return 0;
/ o6 y( u' Y1 }3 c+ O0 R# z: A( k
}
' P% p" B V# X
% K; n+ n: ]3 l; j
int Push(Stack &S,SNode e)
$ L$ f% S- ~' I2 I9 v s/ w
{
: e& t$ W9 j# x- H' O
if(S.top-S.base>=S.size)
* h' i' c3 o. {1 b' Z
{
9 g7 R& g+ ^- O u" k
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
5 a, O# t; P4 p9 g+ X/ G* v
if(S.base==NULL)
: @+ G& w# z" ?7 N; D5 `& Q
{
v( S0 J! M" b! d3 i0 ?/ m: a; h
printf("动态分配内存失败!");
9 I a/ M8 c" ^) h9 O1 \
return -1;
- F: E% Y Q; P' B" N6 A
}
a3 m" }9 ^' J& m
S.top=S.base+S.size;
* }% }2 O) {* l% ]8 M5 T
S.size+=APPEND_SIZE;
" U: S+ T8 R p4 f# T4 `
}
# ^: j# _# C$ I+ g+ x5 X1 i6 v4 Y( o
*S.top=e;
3 k. j% W+ A: [* H; O* k3 j2 v8 o
S.top++;
6 J a: Q7 N' `* v X8 Y4 A; }
return 0;
/ L% ^9 ^' X7 q. C
}
& O, d- M) O( h4 v/ w
" w8 H8 c7 o- {4 ?% p" m
int Pop(Stack &S,SNode &e)
+ |; \8 u$ G0 u
{
Z3 M1 K7 U! \+ H4 K3 @/ W1 d
if(S.top==S.base)
' |; z) Z' |) k! e: c$ e
{
1 a% J E& E4 G" G6 Q3 c
printf("栈为空!");
# C7 j9 w( A9 P: K; E) I# `( A5 F2 P
return -1;
+ q. O* o7 i7 V U
}
& R5 D% f/ _! D/ d1 ^; l0 y
e=*(S.top-1);
4 k0 d" Q- z% C/ {5 V# R
S.top--;
* f( Z2 {$ c, q: N" {& h: z' c
return 0;
5 p) z Y+ J- }! f
}
2 [ i' g. {$ m9 ~' z+ _9 T; b
4 I$ _+ b. r4 y4 Q" W
char get_precede(char s,char c)
9 t! `! S. V5 l3 B( \& D
{
2 n+ Y; k4 S6 Q; m; I8 ~+ g% q
switch(s)
3 H% N) |1 X8 }' n# C1 O; s
{
2 C, U1 F! i% | Q' c
case '+':
" p M; m! t- T# A x# u1 \& d
case '-':
0 @# l A+ h; Q: Z8 I0 B% @# m. j
if(c=='+'||c=='-')
0 c' ]' b+ l% H$ [, K8 F. ]) `( F
return '>';
4 J% z# P# k$ o/ K' K/ h3 u2 A
else if(c=='*'||c=='/')
, C d& `: K$ [$ f7 i+ I
return '<';
% ~, k/ E% P% u% Z
else if(c=='(')
5 y, J5 V8 V# {# \ ^$ N/ B' |6 ~
return '<';
- V/ `- H% h% B5 z% ]: n4 e
else if(c==')')
4 O: e# ?- o2 k2 ~1 i
return '>';
: p. F$ M$ }! G- l
else
% n* J P7 M v, |
return '>';
& o. v! v6 j9 P5 W
case '*':
1 R6 O+ j7 |* H: g7 v! `0 f
case '/':
% D2 ~0 `2 ?' h* _+ \# u
if(c=='+'||c=='-')
+ g" R' B) ^% D2 G# A0 L9 S$ X
return '>';
* g/ g" F. Z/ V, d
else if(c=='*'||c=='/')
% E! F( a6 W1 l7 R' h3 H9 ?$ d, s
return '>';
3 G2 m: {: [" h8 H/ O
else if(c=='(')
. W- _/ f2 h+ D+ s1 q
return '<';
/ m' O$ V; [+ _' _* J
else if(c==')')
4 B' \$ O5 S% x. c! L. p
return '>';
* o, Y% O X+ s" p
else
- L; N# _! ]( z$ @
return '>';
) l7 p+ k b) @1 S! j" r& X
case '(':
2 j4 t, E8 t$ i+ [& b; @* }% \. Y9 _# [
if(c=='+'||c=='-')
+ L* L% q9 F( E9 m) n1 g" p. e( g
return '<';
; s J2 T5 n7 i4 `
else if(c=='*'||c=='/')
* ]' Q0 i5 R* y }, c4 k0 t
return '<';
# j' f: `' n8 ^0 { y0 I
else if(c=='(')
8 ~. H! D" Z" f) }8 A
return '<';
1 c7 o, l, U: c4 F
else if(c==')')
6 P. l8 N2 _+ s* _) Q
return '=';
# z, U/ l3 `2 H' v/ Z$ _8 G- Y
else
& p2 P2 N. p7 X }8 C
return 'E';
# k7 h4 j3 ]5 l1 q# I$ ]( k+ v
case ')':
# c- F$ L |% G" l. t
if(c=='+'||c=='-')
0 \+ h* U$ q1 g; k
return '>';
, z, }, Y$ E1 h+ F) D
else if(c=='*'||c=='/')
; ]' o& G) k4 [/ a
return '>';
% K t a. M3 Q* h7 C8 Y0 ~- _
else if(c=='(')
8 m& `' @/ ~! q* ^, ^2 [
return 'E';
" U' o, p4 q4 P, {/ ]5 B
else if(c==')')
f3 g# p; E% H1 J0 g. r( G
return '>';
\: A+ A' [9 o' p5 S: \
else
& t1 M/ t1 ?. f7 W; `; ?6 \; X
return '>';
8 R1 z/ }* ]/ z
case '#':
; U n+ w- Y6 W$ @0 f& g
if(c=='+'||c=='-')
4 c4 S) N1 k: l
return '<';
( L0 Z5 h( s9 o! [! X- \* a( A
else if(c=='*'||c=='/')
+ w& G0 i$ L7 o1 ]0 @
return '<';
; o$ l: i, n3 b7 x r/ s
else if(c=='(')
- n. j- d# Z; ]) y5 X" ]9 F
return '<';
* v, Q1 m( z9 i
else if(c==')')
3 C2 K0 _ [# z% L" Y
return 'E';
6 j' r, C& s8 Q! M w8 H
else
! t7 s8 p6 {7 o6 |/ w- T
return '=';
) }. O$ L# U- j( l
default:
+ d7 X6 Y9 O! R
break;
3 [* R7 J7 h- ]' }
}
& Y8 x% ^& ~3 ?4 k/ j
return 0;
. b4 ~) S; C. C' ?) | ], J
}
. P& N/ G2 Z: k8 S$ ]% C1 ~
7 B% n: H3 m T% ]. S5 c$ W" y8 c0 l
int isOpr(char c)
8 b3 ]0 A. Q# V/ N3 g2 c- h
{
9 }% y* k0 N4 i D: x
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
4 C$ C1 Z7 Y" S* ?" l
return 0;
) T, ^9 Z8 {' ^0 K
else
4 D( X3 t4 @+ K
return 1;
' g/ c2 b% p/ B, e
}
& F) G' u# `0 c2 ^3 Q
4 W0 V" N& h4 i* l7 K' `
float operate(float x, char opr, float y)
! A3 t2 N( ~9 j9 f$ g0 {
{
; t6 H5 I* Z$ ?! L
float result;
+ w3 @ f/ W, q* U! V3 e
switch (opr)
; p% K# b. V3 F) `+ E Q" ?8 u
{
4 g2 U3 s H+ h \+ w4 i7 \
case '+':
/ s) I- `/ Z) u4 {8 C# [1 v V( C
result = x + y;
8 S x, u& c+ e7 Y
break;
. F& T. \0 h5 O7 o ]3 F6 P5 b
case '-':
4 I4 A+ ?, A7 }' t Y6 [0 @1 \
result = x - y;
, k) B: e, h- \$ u6 y
break;
! b" B1 p( q6 w
case '*':
( [7 A$ k$ f: G; _/ x( q
result = x * y;
' k# g. _2 g3 q+ v3 t- L
break;
! n; l |; y6 d& x7 R r* ^
case '/':
* e, D- \6 v" ~% ^# e
if (y == 0)
- [ p0 @ O6 i
{
" t7 N# |. |) A9 p8 k
printf("Divided by zero!\n");
) T: m. `0 p; z5 H
return 0;
8 Z; g1 K/ C8 Y$ z% K. w) ~% Z
}
e( } s) m2 f# E1 z- e8 d
else
, ^( t* {# Z; q, X1 }& a- g
{
# W; `% V5 A4 R2 `9 h8 H
result = x / y;
- ], B9 o$ @& b- F0 H5 t+ H9 L
break;
% ~) E* U; S: w- G
}
# a# B7 v4 p8 a0 K. f* N1 B0 h
default:
/ V( u9 H' ] C- L
printf("Bad Input.\n");
3 H6 Z3 Q$ h7 V4 A' C+ _! c% B! H3 C
return 0;
9 l2 H6 C8 [4 P
}
) F7 o' I, s& h$ P
return result;
+ m# ^- _* O7 b
}
1 \# G5 M7 m2 o
+ @, e) J% E% Q: G
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
+ v+ K7 g+ [0 S. ~% e
{
7 ^( n( B, |* z
Stack optr,opnd;
$ O. f0 ]/ {( u1 T O1 w; H% O
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
* B6 @4 w* Z% |( B9 ]( f; x
char c;
, Y9 C* x) M% E+ R% b; b2 R
char buf[16];
2 {" S5 `7 z# }; s, {+ `
int i=0;
/ Z1 r! F' S0 J( K* J, X
) C( B' z& D: l8 l
InitStack(optr); /*用于寄存运算符*/
) s" W. g$ e$ \; K
InitStack(opnd); /*用于寄存操作数和计算结果*/
) h; t8 T8 E R/ _, r3 ?
memset(buf,0,sizeof(buf));
0 g$ K" V3 U* ]$ M1 `; k+ E0 [4 A7 c
; W" i& J# u! N9 f- ?$ m) a
printf("Enter your expression:");
. [; W! _3 {! c
& z0 y2 \; N; K7 z! R+ C
opr_in.ch='#';
# C) y/ I% m. U2 P w5 l6 B5 J
Push(optr,opr_in); /*'#'入栈*/
1 F: {6 G+ k5 G6 g4 J
GetTop(optr,opr_top);
- r. _" [( i- s+ b' ]
c=getchar();
: Y$ O: O6 z7 Z3 Z5 f7 S
while(c!='='||opr_top.ch!='#')
0 m- s$ L) S: z6 d% e
{
% f) `. G1 F4 p+ |
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
/ U0 ^+ k; v) w6 O0 Y
{
3 C7 t) R" G( I$ O; a8 s6 t
buf
=c;
! @; Z/ V. ^$ r6 \& y) e. I% ]
i++;
. n5 V# x# I! a
c=getchar();
- t; O* y) n: B) X% A, n
}
( Q' X" J5 w5 j, t7 E6 z. K1 ?
else /*是运算符*/
* D( n P; M0 W$ o2 M
{
: c( l0 @3 @/ P% W7 T" v
buf
='\0';
* r: o4 s2 m' K1 \( |. m3 m
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
: M% A, Y1 T( v6 @2 E% P
{
! O' Z. L# @; ?$ c. |9 ~
opn_in.data=(float)atof(buf);
5 @ @! ^$ M- L+ X
Push(opnd,opn_in);
4 _1 }3 G3 b- ~
printf("opnd入栈:[%f]\n",opn_in.data);
z- ?" P7 g0 C/ k9 J
i=0;
$ a o, f" v/ M
memset(buf,0,sizeof(buf));
0 w) H3 z; `0 w5 D& Z7 S, h
}
) v3 N9 M8 h# D) z
opr_in.ch=c;
" n3 I! r! { M* k0 g, P* Z
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
" [8 M- Y* H& b( h+ R% {
{
* K; d2 G" Y8 m0 r9 I+ n/ e2 v
case '<': /*优先级小于栈顶结点,则运算符入栈*/
' C/ ]0 S! A( W! d" M! t
Push(optr,opr_in);
* j3 A1 [6 @7 [2 R; _7 W
printf("optr入栈:[%c]\n",opr_in.ch);
/ y8 g) K9 R. E! e+ M5 |* Z
c=getchar();
6 D6 m( a& R3 j9 A* U
break;
6 X( h. m5 s0 w
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
: N: X8 w7 p4 N2 z8 I! T& Q, @ V
Pop(optr,e);
) |% t9 ^; b7 M6 }
printf("optr出栈:去掉括号\n");
8 q/ A* p6 v# A- m7 T
c=getchar();
& W" E$ T3 q8 L0 H! p6 b
break;
6 k! W. ~/ a: H* J* v g5 x$ y
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
/ j0 y' ^1 D( r- }, _
Pop(optr,opr_t);
* B# Y; L5 g0 F4 m, H
printf("optr出栈:[%c]\n",opr_t.ch);
6 e. `- f$ x2 y) k* f z: V
if(Pop(opnd,b)<0)
5 Q- f M, v3 G7 \( m! E
{
# W2 j/ M0 q, p. q
printf("Bad Input!\n");
) p& D2 U! `2 k7 |$ j5 j0 `6 _
fflush(stdin);
* ^6 r5 }9 ^0 |6 q! S
return -1;
# J8 ~/ z5 d* [& e) V# s6 p' s% L
}
3 R: k6 N9 }$ M$ \
printf("opnd出栈:[%f]\n",b.data);
! X$ C" }! r! E* q) j) [
if(Pop(opnd,a)<0)
0 p3 E# [( _- z" o; g
{
7 K7 A3 o6 a% A1 E
printf("Bad Input!\n");
7 }2 P, ]- k9 K. H
fflush(stdin);
4 D8 y) S! e, s
return -1;
. Q+ R7 R {$ {2 ]. N6 H; D0 j
}
. c3 p* C0 i0 u* F- F3 l1 A* G- n
printf("opnd出栈:[%f]\n",a.data);
- K' ^! ?+ C) _( t4 E
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
9 [& K0 D1 M# p. X$ t- }# L& ?+ s
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
8 i& u% t; W6 a( t6 f! q
printf("结果入栈:[%f]\n",opn_tmp.data);
, `% n* ]; [* U
break;
. Z: \0 q' n1 w; S$ J
}
3 O7 ~; V& @1 }' `, w& `
}
+ z; [' p: K, U" ~7 I
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
; s9 n( U3 _- C6 {
}
4 U$ H, D! Y& [! ^+ G& |' a
GetTop(opnd,opn_tmp);
. Y7 |! C. ]4 L- R8 n" V) P' p
DestroyStack(optr);
( B5 }7 R) w- N, }
DestroyStack(opnd);
" g& Y- H) m5 P; }, e4 c
return opn_tmp.data;
2 J3 s5 U% C1 j5 N6 x1 {4 W3 a9 A
}
9 l' U1 J' X8 z1 I) J" ]8 q
3 ^: U e/ ]( K6 v q# ]1 F
char *killzero(char *res,float result)
7 W* Y( H/ X) e
{
! E; I+ K* g3 o& ^. k
int i;
! H- [, H) W* n7 c% r
; p6 b. v7 `3 J9 R1 ^- {
sprintf(res,"%f",result);
$ q3 e, {# m: x* Q2 J5 s
i=(int)strlen(res)-1;
! L0 p0 L$ O* G# \* P8 S
while(i&&res
=='0')
0 q- X/ ^# Y2 U
{
: i$ z/ v) `* K- B" E
res
='\0';
4 D9 a9 B* O# \; H. w
i--;
8 I. x7 t# ~7 v: M: T" `
}
+ d/ s+ G, s' K6 K) q' }( X+ s& s
if(res
=='.')
% z& ^3 K3 K, K9 T1 N4 a
res
='\0';
9 J; h) C: j6 H; W8 p
return res;
3 Z e) O s$ S9 l4 k1 N% Z# G
}
+ w! v) E( {/ ]* m5 G
" V5 e- u a8 U* ?8 f
int main()
, ?3 i C0 N* m* X
{
2 b" m; s L) g
char ch;
' m1 F2 I- p" h0 M" n
char res[64];
3 S' Q4 X8 Q6 p; p7 L0 c# F; D
float result;
" w* y: Z) L% Q9 I5 m3 ^8 ?( H
while(1)
! r) z1 j$ @' `* ~
{
G1 F3 d3 y# \! W6 I! I# O- p
result=compute();
3 o4 N0 q0 [& I. j+ {0 U
printf("\nThe result is:%s\n",killzero(res,result));
- I; [; a- O) B+ w1 z
printf("Do you want to continue(y/n)?:") ;
( {5 L4 g5 E2 O: N" W2 R1 g
ch=getch();
5 }8 `1 A& ]1 A
putchar(ch);
" k) t) y/ A" Y9 E3 }( ^) ^. U
if(ch=='n'||ch=='N')
0 G' m" A* Z. F% f8 v
break;
& A& L$ l& ^2 P$ J' k
else
" r' l, l: _1 I; c; f
system("cls");
G* P0 g( I3 t" x6 i( K7 B" @1 j! t/ F
}
$ {* c0 L* s1 @5 D: t# K
return 0;
$ O; [4 w1 E3 i# }/ X6 A5 p
}
$ I; ]- Z0 h4 K
- Z. v: K/ G$ M8 g
[
本帖最后由 zw2004 于 2008-1-21 17:21 编辑
]
欢迎光临 捌玖网络工作室 (http://89w.org/)
Powered by Discuz! 7.2