标题:
C语言表达式计算器
[打印本页]
作者:
zw2004
时间:
2008-1-21 17:17
标题:
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
o! k0 j* u2 r
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
" h% T G) p$ @- S
/**************表达式计算器************/
& G: _4 {: P z1 H [9 ~3 h
#include <stdio.h>
7 O* X( w6 F: S# U% l/ v
#include <stdlib.h>
- g R7 [0 \5 C8 `) A
#include <string.h>
]) z% [' d6 j& u/ b8 i% {
#include <conio.h>
; b* ~4 |2 s8 R: a2 d
#include <malloc.h>
0 B& P) {+ {! Q& F: a
+ e- M9 o+ n) \% e. I% N% g) J
#define STACK_SIZE 100
0 h! w, K6 E6 p. O0 [
#define APPEND_SIZE 10
% |+ j6 f! L8 C
: P7 S$ Y! Q* x
struct SNode{
7 [, d8 h+ n( e- D
float data; /*存放操作数或者计算结果*/
1 a, y t; J- Y- b% A, D" n9 e' k
char ch; /*存放运算符*/
9 p/ S0 y' K8 Q% Y7 @# [
};
( `9 w4 Y0 {' L1 H0 V5 j
# h: i. s. h. ~% }8 y& V- e" i
struct Stack{
2 D3 f N% G( ]1 L0 z1 z
SNode *top;
1 i- t6 b& H* W8 o$ R( `
SNode *base;
3 V0 i5 {" l0 \
int size;
5 N0 P( w) |% E
};
C- P, X; w! v4 ?9 Y. I
/ s* P: y, k) @4 I9 @
/*栈操作函数*/
- T: S) z' y% S$ u k
int InitStack(Stack &S); /*创建栈*/
- a* p( H; R2 L% Y W# R
int DestroyStack(Stack &S); /*销毁栈*/
% J% X" r( B! T" R
int ClearStack(Stack &S); /*清空栈*/
3 T( P; ?6 S% I: B. ?
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
( I9 V5 ^% y0 ]0 ^
int Push(Stack &S,SNode e); /*将结点e压入栈*/
2 W! l( f( a8 M# G" f# i
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
3 O4 p( j3 _- I2 ?
- I0 [0 e7 J! x, a% K
/*表达式计算器相关函数*/
3 a2 E' ?# x: @1 o/ O
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
+ \5 V( @/ I* }
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
$ I) l$ `% v$ y
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
/ u. {& c: l* A
float compute(); /*表达式结算器主函数*/
8 _2 @; z8 D) p k1 x# T
char *killzero(float result); /*去掉结果后面的0*/
, ?2 ]' H5 I# i$ I& |
1 d. e: L1 f' O3 f6 P9 ?1 J: g
int InitStack(Stack &S)
( b' t6 |! b* k8 ?9 I
{
# a G6 V$ U. t8 p) e! r# ~1 J
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
9 T$ T5 m: H H% l1 s9 _* E( k
if(S.base==NULL)
% t. k/ i" D+ f% v; } J& f. L
{
0 V; c8 ]# B, \8 ^0 k% @
printf("动态分配内存失败!");
6 R4 N6 P" m; j- F
return -1;
: q9 C' C/ A. W% e- N
}
. S2 R ? n7 {# ^ P& f& N5 T
S.top=S.base;
7 C" Q5 V4 m+ V9 K( s' ]. m& ~
S.size=STACK_SIZE;
5 }2 F" j* ]# |/ Q9 N' ?
return 0;
( n! _5 D K; P6 c1 q. Q
}
9 T1 b1 a2 [; Z! R
7 j4 i3 }3 M0 P4 O& y
int DestroyStack(Stack &S)
& x3 E2 _' q9 p2 g+ ^
{
3 M* H# O: O5 e
free(S.base);
0 t; J: q% \4 M. v( e5 p3 H
return 0;
' h) i$ _+ [5 J) K w! v! Q+ y
}
. ~) X$ C9 @% B: H6 j4 A, y: y3 U$ J
' q, h& d. M# {4 d
int ClearStack(Stack &S)
+ o# T6 e. q# Q6 V
{
5 V1 O. }( e2 f* R) e
S.top=S.base;
5 W$ M# n0 }+ X
return 0;
8 x; ]1 \$ a6 Z
}
8 J/ }- U, B4 R9 d( A' Z
4 W; U! }, d: d% Y6 T8 S6 x9 Q
int GetTop(Stack S,SNode &e)
6 X# m3 b9 i8 f
{
5 M5 M& b% E6 c2 c$ c3 [3 E" b) b
if(S.top==S.base)
1 x$ |9 ~! a# B k
{
0 o1 j$ Z, {* b# \# m
printf("栈以为空!");
s* Y+ S5 Q' ~
return -1;
. A8 n1 {# U! E
}
. N) }8 q2 I; u* j; S
e=*(S.top-1);
- u/ a# |4 o7 U' P) V% r9 z" a1 G
return 0;
% n9 o, z; |+ R; ]
}
8 i+ P2 Q5 @/ O
8 K& [& {. H0 C6 g; y
int Push(Stack &S,SNode e)
, V* @0 Y* i9 @
{
0 n% M' T |# J. x! {& S7 a8 ^! g9 x
if(S.top-S.base>=S.size)
1 ]) ?1 D8 [& D1 U1 I, c) S" I6 U
{
8 h/ u: B. B! S
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
* s7 \0 J7 A( U' ], {8 H. s* W
if(S.base==NULL)
1 S$ j# J7 ]* K$ f/ B
{
, E! l1 Y2 G: B
printf("动态分配内存失败!");
" k9 s; t( `' L( S4 {& t% R
return -1;
, @. l1 v: O5 S+ {- ^" H
}
5 J# F0 L" F! p0 f: v' l B2 h! e
S.top=S.base+S.size;
! Y4 i/ L, y' F
S.size+=APPEND_SIZE;
S5 A" d: s( M6 E3 `8 `
}
% N" @ z; N9 A, {
*S.top=e;
9 O8 q* F8 i# U) [+ r
S.top++;
0 D7 y4 |5 }/ }+ L
return 0;
; X* R" \$ [% v' g+ }( o+ s: Y
}
h1 D4 \/ B( m; D6 `
; d k) {' Y! w! \2 ~- r
int Pop(Stack &S,SNode &e)
2 C% `" n7 F; x2 E
{
- K2 g1 P' p6 y0 q6 S
if(S.top==S.base)
8 ]9 z& b+ k, F9 G7 I8 r6 o
{
e6 U, J6 r5 ? ]3 e
printf("栈为空!");
4 R, m( ?8 x ]+ l; E' s
return -1;
) v: R9 R6 ]3 B, N. w# ? Q
}
1 x$ ]. x9 V2 t5 y) K& x5 ^
e=*(S.top-1);
: _6 n& Z( w4 B/ T$ j
S.top--;
2 a$ A! [( D# a) U- V9 q1 Y
return 0;
# } ~. s* g% g. H
}
7 X7 Z$ x3 Y/ @/ S; X' L' a+ a/ k& V
. Y. n+ {1 C9 ]3 W7 H* ?0 m3 S
char get_precede(char s,char c)
" U) n2 _8 g! u4 L2 G& y
{
: i- k, s0 I4 T$ a; Z
switch(s)
$ V& t, r$ Y/ }+ Y e. X8 W% G
{
4 R3 @& y; r2 S2 n) d! D( F
case '+':
2 g- Y" x9 k! ]# o
case '-':
0 h5 x& [) z+ C2 J
if(c=='+'||c=='-')
2 Y$ ]8 N6 ?- f: W6 S7 _
return '>';
" L# S5 f5 x# T c6 `9 G* s
else if(c=='*'||c=='/')
, y. F( C+ n2 _ Q/ M' S
return '<';
) b. }8 d# r4 f8 l y' T
else if(c=='(')
3 J; [0 M+ k2 t$ G* }
return '<';
, Z! V3 S8 P5 ^. E7 h8 q2 V% U" a
else if(c==')')
5 A7 H; v# G( s, ^( u4 {& p
return '>';
; U0 R, T' I, x3 z
else
$ u. u b* y' v$ T8 F( ^
return '>';
3 {, ]# s8 Z& ~, u
case '*':
0 \2 [( d" y* u4 J! @$ P S
case '/':
# @3 E* O6 j; J, n' l4 \- e( _
if(c=='+'||c=='-')
R1 D4 c8 X9 q# t+ |9 w
return '>';
7 `8 U5 |7 F+ q- L5 h+ w' x( U
else if(c=='*'||c=='/')
5 H! c5 o$ R0 X4 X
return '>';
2 t6 V! j/ x. x. e5 a1 I' h$ y
else if(c=='(')
- |2 c9 L, I. _1 U! F$ x/ S
return '<';
5 _' }3 S& B$ l, ]
else if(c==')')
4 X3 o% C2 G# j2 s, A8 k
return '>';
. P& T4 `3 A" K0 Y) E
else
9 E+ P! \; a+ Y) V( s( C, L
return '>';
$ X% x) Y" y w7 o; _5 V6 X' F
case '(':
( n- l x7 I5 b$ S
if(c=='+'||c=='-')
- A+ n/ i3 O u& \
return '<';
8 e% ]* e8 Q+ F4 Y, _5 E# _, ?+ s% h
else if(c=='*'||c=='/')
* ] E9 z" I2 k# ^) v. p
return '<';
+ T) Y0 Z! d9 T
else if(c=='(')
, i& R; R% q. m1 Z( _/ }3 \, H; ^- Y
return '<';
3 h3 R' k, {4 i& H( o3 t% Y6 G" o
else if(c==')')
0 R. E% p5 f7 V2 e- F& A* n: R
return '=';
- H; d9 i- T# ^. g, K8 B
else
0 |4 _8 z, N1 Y3 i7 }* h; l; g
return 'E';
( ]. T/ F8 i# a, k) i
case ')':
6 b/ q% |; C2 I' a" Y& F' d
if(c=='+'||c=='-')
' X1 C* }- ? S) `4 r8 s; _
return '>';
7 Y( m3 B7 ~) G/ @) M# P
else if(c=='*'||c=='/')
8 `; J) A3 d" M7 l% l
return '>';
g- w' P6 I/ l9 i' C \
else if(c=='(')
. S! r: _( v$ S* F: c8 v
return 'E';
# v5 B7 g( _3 |2 @- q
else if(c==')')
# \0 E9 v- J, C8 R
return '>';
3 b3 ^5 O! `# o' Y7 M, `
else
# b0 ?! d# Q/ X% e' ~+ R! v) `
return '>';
1 R5 w g! P3 u. g* N( _& p8 }2 j
case '#':
5 C$ n' o: Z/ G0 u5 n8 C
if(c=='+'||c=='-')
9 d$ ?, t/ E, I9 y; B
return '<';
; b* t; N& `5 @/ X/ c6 \! k1 E
else if(c=='*'||c=='/')
) C, i$ g- }" b! n
return '<';
, _1 G* E" N8 y% K+ ]! @4 @) f
else if(c=='(')
) ?5 h/ B2 I& R& j1 ?. y+ s
return '<';
5 O' A2 x5 S! b+ D# M+ k
else if(c==')')
: i/ f6 W& T. M, V5 T% Y( p; V
return 'E';
& S' n1 F; A* b9 Q) ~
else
5 q4 B: V7 t9 A: ]* z
return '=';
5 l# c, N+ F E2 u# x& z
default:
$ h# h7 S" A7 n5 S/ m
break;
$ F2 r' Z4 i; m+ t5 p! q5 @
}
, A, R( L1 s0 k! z' d5 n. A
return 0;
7 c5 d6 @7 W- T1 K% A
}
9 V' N. D5 H: r
" Z% T4 b! {9 e" A
int isOpr(char c)
, ?3 e R. l3 f9 i) ~% Y
{
$ E1 Q) X) ~6 B
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
, ~1 o; f; E0 x% q/ H$ ?* ]5 h
return 0;
4 A6 x. H8 V0 W; O4 q- c
else
& D4 t2 o7 X5 y
return 1;
, K9 N6 u2 U c# U* J
}
9 u6 J' ^% c4 y7 H1 u; @
- k: G0 J: A9 O2 ?; r& \
float operate(float x, char opr, float y)
9 e ?8 C" B: h% b4 y9 w
{
5 M1 j% Z5 K' G. s6 j8 D. D
float result;
H& n \) m, T3 f, ]5 i e3 Z
switch (opr)
$ G1 ]" n6 ]2 A; c, ^) h3 Z
{
% y8 T4 h1 H$ D( `
case '+':
; |# r" U- B3 g
result = x + y;
: A% w9 [ U) k8 `8 W
break;
7 ~7 q7 T3 U$ Y* A$ k
case '-':
& o' y/ B8 V- d: i S
result = x - y;
/ k- _0 Z' I7 |# S
break;
& T! R( `- w/ m7 B7 b1 I
case '*':
3 y4 a- t% x# ^/ b: H
result = x * y;
. V& s: C' b1 s" c% c+ p; a5 H
break;
$ y, b+ `; p9 G, ^, [
case '/':
. O* @. x3 o) j5 F
if (y == 0)
_- J0 \$ h) {
{
, E7 l6 Y0 E+ I1 m1 q3 s' {: x6 Q* j
printf("Divided by zero!\n");
, Z7 d$ j( M+ n& v2 G
return 0;
- Q: ?( {5 v' [/ h8 Y
}
1 j6 ?/ w+ ~3 a5 D
else
$ c+ X% h" I) p' K0 G
{
5 ~8 G+ W4 c g5 o& P7 ^% H- r
result = x / y;
: i- _, z' B% D; ?7 [$ n1 `
break;
7 G6 f& s7 D0 E( {' ~
}
6 H/ Q4 K6 ^9 N! o( d
default:
2 ]1 g0 y, ~( e( a. W( G
printf("Bad Input.\n");
7 B" V! ?- b) E- U% e$ F% g
return 0;
& [0 D7 E& G& q8 @+ ^0 |
}
7 \' \/ p; I0 H1 z+ {
return result;
4 h/ l! l# } E {4 q2 ]
}
/ ]2 r; G r5 a
" b6 @- U& W/ c
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
# S/ B0 z% I; J- y6 a
{
. A. } P# F5 u
Stack optr,opnd;
/ M# B$ D8 i. N$ Q
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
( |# q2 g( P! b) v
char c;
5 ]- B- h0 R" i# K" X* g5 l& P
char buf[16];
2 u5 c8 j0 T* {& }0 z: G) b
int i=0;
" ^* ^% W2 m6 v% r. ~% @: k6 j3 `
& T4 a" ^) V4 C- {& h g& S7 w
InitStack(optr); /*用于寄存运算符*/
2 {, f0 E0 t7 R; Q0 Q- Y; v
InitStack(opnd); /*用于寄存操作数和计算结果*/
/ v4 Z/ J8 j8 J9 R$ ]
memset(buf,0,sizeof(buf));
9 v' X2 \ z# g4 P
5 M) w0 D4 v# V) H8 F) B8 W" d
printf("Enter your expression:");
/ Q) V. f* L$ d
?0 S( f1 b; m4 x6 a: v( t
opr_in.ch='#';
% }# J+ y u( n
Push(optr,opr_in); /*'#'入栈*/
& K3 A9 H4 Q, h# M2 Y
GetTop(optr,opr_top);
$ F7 M r! h2 c9 y: w$ v0 `
c=getchar();
: W3 s* ~' L2 x. \# u6 U' k% Y! |( }
while(c!='='||opr_top.ch!='#')
; U) ^# D. s2 ^' I
{
5 I3 d; W: {9 s* M
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
" {0 G+ ~2 F. }4 @
{
, P" E0 n" J3 V W4 `+ j9 r4 U, m
buf
=c;
|! u: J5 v6 a6 x @# T
i++;
, s+ ^3 y0 T" h; c. E( ~ L8 l
c=getchar();
2 y) s+ c8 g9 M7 \+ R
}
8 g: x9 h# q7 w, Y6 ]5 _+ N* \: a
else /*是运算符*/
5 N* B: ^4 E# G6 _
{
( J* i7 Y2 W( z! H0 i
buf
='\0';
' z$ r! \/ i l( G& o# |
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
+ u, X; V9 [/ G& F9 T, P) P
{
) L$ }5 \ B# X3 j+ Z$ C
opn_in.data=(float)atof(buf);
- w+ ~0 i, J& m* \+ t# ^+ Z: y
Push(opnd,opn_in);
& a; f1 M) C% T. I1 Z; T; i
printf("opnd入栈:[%f]\n",opn_in.data);
) J2 j& v7 E4 w' R
i=0;
2 _1 e& [ C/ j- q
memset(buf,0,sizeof(buf));
2 S% ^: c/ {9 C2 v) I4 u- u
}
2 ]+ y0 U0 S% `' K. l4 X
opr_in.ch=c;
I& E. s+ @1 E& n" K- r
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
8 ?8 t" ?) |! A6 W; j' c) h: U
{
! K5 L) l& {% G6 F! a
case '<': /*优先级小于栈顶结点,则运算符入栈*/
1 u `) j* k1 j/ X
Push(optr,opr_in);
5 l# L* u7 x7 l: d4 r# ?
printf("optr入栈:[%c]\n",opr_in.ch);
$ m: H& J, j, X9 k) Y) x
c=getchar();
; y- m, Q0 L/ L9 L1 {* ?
break;
6 B+ s0 Y5 q- {2 }
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
4 E, w3 t2 K" J8 F! S. W' u# {9 E
Pop(optr,e);
* d0 ?" T5 ]0 n6 L) A2 {
printf("optr出栈:去掉括号\n");
/ j! a6 @& j* w! H( u
c=getchar();
* }, g S: I- d" t; B
break;
^/ G: ?1 P0 p0 T* z0 F
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
9 E% w6 J2 v" I" t
Pop(optr,opr_t);
3 y' s# r9 J' k, t
printf("optr出栈:[%c]\n",opr_t.ch);
- j' n, ?2 O; y/ H9 B
if(Pop(opnd,b)<0)
) H/ x/ o' j% }9 k# }
{
1 g/ u- w7 Q( s' S1 J, A
printf("Bad Input!\n");
$ u8 ]" J' E' Z* X1 u0 f+ x
fflush(stdin);
?6 z$ j; h/ W9 `, j
return -1;
" `& w, |: p+ w0 L8 q2 w: n
}
{' a; n9 w9 d5 R8 J
printf("opnd出栈:[%f]\n",b.data);
+ c* A7 B, ]8 b0 e. b T) |
if(Pop(opnd,a)<0)
8 }5 s0 X. S# E8 U& O6 Q
{
* [3 q! y3 i# ?0 b0 c0 s) f
printf("Bad Input!\n");
- S0 @' g5 {. r; }6 c3 L) S# O
fflush(stdin);
( s! v* s9 o: W3 [9 O% i+ Z
return -1;
% j1 E& B, P7 Z" Q
}
$ s0 \( j6 m' N) M3 ~! I% K
printf("opnd出栈:[%f]\n",a.data);
; n9 C. Q& p9 Y% N) `1 ~& N
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
) o& p) ~7 ? k8 r8 ?, f
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
0 m) C- u, ]; P
printf("结果入栈:[%f]\n",opn_tmp.data);
; \# u" s9 l1 E( u
break;
! U$ h. ^ E, I3 y7 f* |
}
+ b% j2 }! P% F1 a/ N
}
( c J7 Q2 H6 ]0 G i
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
4 T8 e5 m! J# f; A. k
}
$ S) \; u- r( n" v% C5 w% s
GetTop(opnd,opn_tmp);
1 d3 [( P% ~+ }; F( q# C# t5 Y8 h
DestroyStack(optr);
* J3 J$ ^7 w7 i6 }+ }. k5 t( M
DestroyStack(opnd);
6 l/ P$ F7 h6 A, r* j) j
return opn_tmp.data;
( ~2 h( B! h! A! ^/ X
}
: W5 z7 ~1 ?6 b" A- ~
. f* M+ k4 {9 A8 s/ ^
char *killzero(char *res,float result)
! u- }5 j1 s0 K$ d" x4 f
{
3 V$ t/ q U2 G: o* ` P1 q! b
int i;
1 S7 }7 L* g$ w( ^0 L- i4 v& o6 w
! W' H2 H9 l7 c3 d
sprintf(res,"%f",result);
% ~" F, s s7 S, f1 ^( A
i=(int)strlen(res)-1;
& r4 ?3 H5 J5 N2 ?
while(i&&res
=='0')
3 d- f7 Q$ y! J0 X- |) _9 {: t0 y$ s4 {
{
- P1 r. ~. G6 _$ q# w
res
='\0';
! f5 a# _) X/ S3 W
i--;
' R& A2 m. p4 T) P+ ~
}
; b- u4 I2 A4 Y" ^8 L- X
if(res
=='.')
% o5 _# L5 R0 x4 Y; Y& Z
res
='\0';
" ~4 c' k; v: @' _- U$ u
return res;
/ s' v+ D+ \5 ^
}
0 c2 `' [. b& F- a- A* W
& Q: `$ [8 m/ K
int main()
. P! ] t. N1 w/ m& b3 a
{
# E$ A) S9 ~* z0 E K
char ch;
% L/ t# h/ D/ |/ u+ m' i, s. N
char res[64];
* N- _- L2 b( h; i Y" }5 Q' ^
float result;
! |6 h, f/ Q. O, \( Y- Q
while(1)
q. w" j& J) M& m: ^/ _$ x
{
; ~+ `) `9 u& R, \8 x
result=compute();
- K/ c' ?5 ]! Z1 s+ P' `+ R
printf("\nThe result is:%s\n",killzero(res,result));
U2 Q, |* ~( V$ S# Q5 t/ m% |: Y
printf("Do you want to continue(y/n)?:") ;
" ]( D9 i7 v* n8 ^8 H
ch=getch();
/ N1 s: c: g' V$ X; h
putchar(ch);
# ~; r9 _) I) V; d8 k
if(ch=='n'||ch=='N')
# ]/ O3 x* v' j& i
break;
- m; B& n b6 z. J/ E
else
: ?# p8 n/ a' P$ z" Y& K6 u- U
system("cls");
# h$ h0 I/ z8 ?: z4 g
}
, Z5 q/ A7 |) v6 k! B9 R" q9 G' O. p
return 0;
& b# `, D0 p7 N- k' M: w
}
9 W8 V# s- \* w/ A5 P9 g
; r9 J \5 d0 G0 Z$ `
[
本帖最后由 zw2004 于 2008-1-21 17:21 编辑
]
欢迎光临 捌玖网络工作室 (http://89w.org/)
Powered by Discuz! 7.2