标题:
C语言表达式计算器
[打印本页]
作者:
zw2004
时间:
2008-1-21 17:17
标题:
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
! n3 w! [; Q( j7 d
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
6 l5 Q t+ C$ T$ O. b% C9 K% q0 z
/**************表达式计算器************/
# c- N+ x% O' n
#include <stdio.h>
! e8 B6 h2 K. t4 x: g
#include <stdlib.h>
4 s" z9 v4 T. |' Z
#include <string.h>
4 q# B6 D" v! i
#include <conio.h>
/ V* f% u# w: Y& a# X& g4 E4 p
#include <malloc.h>
% q) S. _3 V7 v/ ?: h4 }
K/ n3 {4 Z: O7 c
#define STACK_SIZE 100
) n% }3 N, [$ _
#define APPEND_SIZE 10
8 t" c7 Y. V$ m
n7 O& b+ w2 h) F- N' e, w; e
struct SNode{
& }" f8 C. U/ P! P: J+ n" {# D
float data; /*存放操作数或者计算结果*/
I' q# X4 @" d6 O
char ch; /*存放运算符*/
, n+ U( L; `) ~* u8 D* m' @4 j8 O& h/ O
};
3 A3 y* C# X: l( }( k
2 S8 F; D& \! q
struct Stack{
) N# l5 L" k% Y- e6 [4 I& ]
SNode *top;
5 j9 J3 h/ B3 e2 h7 i
SNode *base;
/ |; ]& J& w+ `! f: a! r: J
int size;
; ^2 c4 n! a$ ?# p) j$ I
};
1 `3 k' ]! y5 P4 o2 j' E- B' p( e$ _
- U" H3 {5 [) }
/*栈操作函数*/
0 t( E( h1 y+ ~. A; h5 J( r8 B
int InitStack(Stack &S); /*创建栈*/
5 E9 L, ^6 J2 u* F& g- M
int DestroyStack(Stack &S); /*销毁栈*/
+ F2 ^ D- Y" f( `* Y% u
int ClearStack(Stack &S); /*清空栈*/
6 b. B* G: I7 f
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
' {' q/ c) i5 A# M
int Push(Stack &S,SNode e); /*将结点e压入栈*/
/ j: d8 S! n: J+ ?
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
1 v; B- V( k) D: { s
4 v: u* w6 r, G2 X# O
/*表达式计算器相关函数*/
! o$ f" N+ M3 C
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
+ ?: h9 Y: S7 ~4 a' y* l) m+ X; |' }9 G
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
& W" D4 }& T$ E( K* K0 x5 n
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
$ j" t- d; C* E# |
float compute(); /*表达式结算器主函数*/
, {6 D$ E$ X. y
char *killzero(float result); /*去掉结果后面的0*/
* S& O7 a0 L9 K* |
3 Q" |# Y* v2 O. F8 Q
int InitStack(Stack &S)
& o" B* h( S: G3 m) g
{
, H( D9 q: C& `3 y
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
' o/ q3 e0 ~0 w! |
if(S.base==NULL)
; T" l$ G7 i9 V9 Y* s4 d
{
1 g" v% ]9 v% I( G8 p
printf("动态分配内存失败!");
& W4 D! D$ d' Y5 _, V. p" ]
return -1;
" T% O" W7 J; D
}
! a* M1 Z U {: r! o
S.top=S.base;
; Z0 S& H, v* V+ p
S.size=STACK_SIZE;
# Z8 F! M) Z y3 x2 ?
return 0;
, s* Y) B o7 z7 B7 p% N1 {2 F
}
" ~' i3 k, f& ]
& D4 O! i( L3 d" U4 g9 D8 w! x
int DestroyStack(Stack &S)
2 u% @% b* p- t, f
{
" E3 |7 `; }& Y1 C
free(S.base);
- ]% n8 J4 l% {% ^# N- ]
return 0;
, n% ^/ N U0 c: F- d* v
}
T( P) M4 F7 Z9 {' t2 z& \4 b+ C
, N* k9 x4 \1 n4 A8 s$ e
int ClearStack(Stack &S)
6 ~9 s$ c' ~- F$ |* [
{
) W2 f; \( }6 u# ~ f* u- k# _
S.top=S.base;
7 d' W j @+ x2 y: [6 N
return 0;
# q& R& Y) W$ X' R; {
}
7 g# i! Q8 |( p/ R% S/ y' I9 f4 X
/ t/ x9 d" R: I+ ~0 Z/ S3 |
int GetTop(Stack S,SNode &e)
3 ~) t5 e# ^4 B& d5 C
{
* J+ I h- ]8 V) B) X& W. V' v
if(S.top==S.base)
8 l( [, Q; `4 Z3 z2 i
{
) x( j9 q# r- f. M& X! w$ `3 A& P% E
printf("栈以为空!");
% R5 G& U) w' m( E8 N
return -1;
" s. q: O/ I" C# x$ J8 k
}
( m! e3 ~. X) V% r' B$ q7 u
e=*(S.top-1);
! ]3 T. r( k9 c
return 0;
# |( z, J3 y4 K- s
}
- y4 y! S) e1 W
/ p6 B" i* S7 n) D
int Push(Stack &S,SNode e)
) W) R% b( h* m: P
{
' J0 E* G# Z' [- Z4 `
if(S.top-S.base>=S.size)
2 a4 J' A1 c2 Y w! M% ?* z/ i) w% T
{
* {) x/ r% s: h& ]! {* l1 K
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
* A9 @; s6 d5 S
if(S.base==NULL)
" ]7 a: Y: ?! \" X" D- }) \! J
{
9 c( I+ O; t8 ?! u4 E# D! R8 W
printf("动态分配内存失败!");
* I& B# Y! ?+ Y* O5 h0 ?7 `3 d
return -1;
+ l" D( `$ _" o4 n6 y& _) M( Z3 _
}
2 C# ]; [* R: S% X8 N
S.top=S.base+S.size;
( O( _' F: v9 ~3 `
S.size+=APPEND_SIZE;
3 q# [8 d1 ]9 c k2 E% P
}
: t2 D/ b1 o9 ~
*S.top=e;
% M" s$ E d: F0 h" G
S.top++;
' ]! U- i9 Z- }" X: N
return 0;
3 O0 @. b3 \7 H+ C, ~5 v3 U# k- A$ L
}
/ a: u7 J+ Q1 o3 |
" j9 X( w3 j3 e7 v3 D) k- ?
int Pop(Stack &S,SNode &e)
. E& C" s* D5 [0 O5 @' [- r1 s' `
{
- K) [! ~ C8 m. _' m6 S) A+ n
if(S.top==S.base)
' ^# [0 u. d9 n! Y! A
{
3 q/ w3 v3 n2 }/ Z2 _9 F3 v2 i
printf("栈为空!");
6 S1 u3 U- Q. T6 H% J: m/ Q, i
return -1;
* E/ E: G! z7 T! f% b5 {) i0 P
}
2 h2 x8 g( T8 R5 t* q( g
e=*(S.top-1);
% M' E2 m1 } ^. o/ p9 J* R2 n T
S.top--;
- \; N; e5 } B3 L7 D- Q
return 0;
6 i3 A9 ~6 Y9 W
}
+ A' x7 _8 n( Q2 {. P! u
! m5 A! _/ r6 i8 T: f! N! N0 }
char get_precede(char s,char c)
) o1 O8 z8 _8 H3 g3 g/ @
{
9 W+ K8 o! ~) Q2 G
switch(s)
6 o$ o" P( V6 h0 v) }8 f2 j' p" C
{
# Q/ O8 w2 P+ \; M/ t7 W
case '+':
% l: j2 R1 C3 Y+ T v9 i
case '-':
, t3 q5 G6 v0 c
if(c=='+'||c=='-')
; ?; l0 E. T9 t+ F* z
return '>';
# @) V% `: I$ O2 s! a6 V
else if(c=='*'||c=='/')
8 q9 @0 a. F0 o1 K; n* k2 l% Q
return '<';
: C% ^+ M. d) w: x
else if(c=='(')
0 D4 S. N7 [5 o' T& y& G4 E
return '<';
* W9 }# B+ ]4 G: _
else if(c==')')
2 i7 S" n) a1 \8 T
return '>';
5 P3 r) W$ M( u* Y
else
) H& T+ v" \4 L2 p
return '>';
4 w: ]' l) ^- M% e
case '*':
% B, \8 x, f) m# M8 z7 O; _" [
case '/':
8 ^/ w/ ~0 Z2 c2 \8 t* d( d6 @
if(c=='+'||c=='-')
7 k. Z+ I; A# |6 I
return '>';
, k1 K- U! M8 W: a
else if(c=='*'||c=='/')
5 }! i) }) {' ?. I# U: F
return '>';
& Y N7 A& X6 w. y. i
else if(c=='(')
4 t8 i& F. U- g( R4 G3 ^ `
return '<';
6 o! d6 _# o& O* u" e. E
else if(c==')')
n( Z% {3 \. n9 P1 ^" U1 J
return '>';
0 z; ~8 ]4 J F6 w' [) j
else
+ \: R- H9 N% H/ z: m, @
return '>';
* j! _0 Z3 X+ g
case '(':
6 `! R; i1 f5 t4 r0 s. F
if(c=='+'||c=='-')
$ l5 M, G5 x9 m! N" k
return '<';
- o/ t: N1 ~6 T4 n
else if(c=='*'||c=='/')
2 E- u0 c! y1 Z0 I: S
return '<';
: o3 k; i: h7 k0 p2 W0 Z
else if(c=='(')
( j9 C8 j7 I$ V9 U$ G
return '<';
% H, C* Y' P+ j" r: f
else if(c==')')
" L( S2 j, ^! k5 _* c, R# V
return '=';
& X7 Y" f4 A: M
else
; f4 D( M( b( H0 q5 J3 L! t& Z3 K
return 'E';
+ j0 Z; E2 K& n# Q- p, f2 b
case ')':
. W. W Y7 O% i
if(c=='+'||c=='-')
, w) L1 v. m1 W% y# k
return '>';
! a" }" z0 B+ s9 c: I! `) e/ s( [0 I1 X6 _
else if(c=='*'||c=='/')
5 j# k- Y* ?3 @) [' W( q
return '>';
6 ` J7 q1 N+ g* }! b# o; X2 r j
else if(c=='(')
" z* w- b L n) {! b) T0 M i
return 'E';
; r8 n( K* C6 Q& w- e
else if(c==')')
# J3 ~" Q' a5 I( \5 L k
return '>';
" W& J, H$ Q0 J; H0 @! N9 J& d
else
% `; `0 c& y& C+ Y! G4 M! b: D
return '>';
3 T+ c3 X/ {+ q; p# w8 i5 w& N
case '#':
* Q+ k) j: j7 `: g: s
if(c=='+'||c=='-')
: @" s/ G5 k* t% M* h+ Q: H
return '<';
- `0 s. P& d( J0 k1 s1 {3 r
else if(c=='*'||c=='/')
) i- o$ H0 a. ^5 |: H u/ c
return '<';
0 U1 \. x2 P! v" w( q% s
else if(c=='(')
) X3 s5 S' r1 }, V
return '<';
( B& B# m& W) R5 z
else if(c==')')
& U+ D$ O- \0 L! c0 G
return 'E';
9 z* l* `' u' Q: E. W/ T6 d* ]' D5 t; }
else
" D$ f! ]+ H" K1 s
return '=';
) d" I" D& J, h2 `/ `
default:
( O' A7 S, G' m: |
break;
$ G% V c5 v. H$ }. j) z
}
+ Q# x3 o, d5 F1 e C; H4 l
return 0;
9 Q s% w$ d8 V# X/ o# t
}
! }5 B* }1 P; h( V
7 B# K5 b) z) b3 T6 I
int isOpr(char c)
* G% W' q' H- N# W: U* B
{
1 X3 q& A' }2 Q$ ]: f9 g
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
1 U, C3 n$ d' w9 R2 w: q
return 0;
4 c9 d( S0 o$ g( |! Q2 n! {, Y& z
else
" q* q1 g4 R. ]5 y B9 _
return 1;
! f' A q. D8 a
}
, N y' W4 X. N8 K/ ?; o( `
- ]- }& y v' G' @0 b
float operate(float x, char opr, float y)
( R8 j; o% h2 C9 [
{
- P+ L, g0 w2 M6 ?$ [, T
float result;
4 i" B/ L5 U. \/ J8 H
switch (opr)
4 D: |6 z& ?3 l. K
{
% e3 Y. f$ j/ c# J- c1 l- X
case '+':
" M6 T: b: `8 A. [1 N: z! `
result = x + y;
% g' n; C4 M5 ^' k2 j6 S& M1 T
break;
5 |6 P: t1 A8 T) w. H
case '-':
" A0 {3 O, d4 C5 a
result = x - y;
) R8 Y0 {' e4 @/ V
break;
3 w' ?& q3 ~" C' w7 n
case '*':
4 Y! T7 k4 i$ v4 `4 Y6 _2 N! R; Z
result = x * y;
$ J! R' \5 H" x+ O; }. M2 o# [, {
break;
: O: }5 s# w7 R* Y8 b* @; u
case '/':
* i9 d+ y) J; E& f2 t
if (y == 0)
8 t+ O( N2 s- W [7 \" @ J
{
L. {9 R! B; }% ]
printf("Divided by zero!\n");
$ B5 ? E) y, G/ X( i! T
return 0;
J, @& r; q0 H( F
}
% p" P7 ]% J2 c5 m# C" j" G, [
else
5 R: k) E/ L" k* C4 F4 D8 B
{
9 e0 ?3 ?) S+ v" Q
result = x / y;
' a# g/ o6 v: O3 n5 q" G
break;
& R; k3 O5 n) s4 F- P
}
6 y" i8 V# o# \
default:
& |' E4 L* V: n$ K' r4 X
printf("Bad Input.\n");
! j" M! a" d- @8 O2 \4 b% k
return 0;
0 x" h; R6 l! B* |% z$ j2 Q4 M% m
}
0 {7 A$ N7 m( I! }2 j" m9 g
return result;
x. O$ Z/ S! `% Q# H b( F! f! O
}
3 i# ?3 [/ k3 X) T7 @/ y
" c' O( L! X$ `" U1 Q' X% |; z
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
' g+ a* r3 v- {
{
/ {! z; M; m- d% q5 e
Stack optr,opnd;
; [! L7 ?6 J& M8 m! H
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
& }! r" y; c- {( A, U: x
char c;
1 i/ I Q8 \+ ^/ m/ q$ H
char buf[16];
B, S- A0 |5 V2 W9 ~' O. b
int i=0;
9 W! U( T& G( M: T, S
3 t1 D6 h ^" t- K8 i
InitStack(optr); /*用于寄存运算符*/
8 }+ z. R0 [ u M N
InitStack(opnd); /*用于寄存操作数和计算结果*/
/ J5 K- j' D6 K/ m! N
memset(buf,0,sizeof(buf));
/ `5 E( q; x, Z( r# n
8 n) o& u( \. ~' v
printf("Enter your expression:");
5 I& @/ K$ J8 \1 E4 ]$ o. r
3 V k9 L1 A7 U9 W. L& r
opr_in.ch='#';
7 I: ^7 y2 z; U( z% _ |
Push(optr,opr_in); /*'#'入栈*/
, E$ x9 `* Y% _1 a9 H+ r
GetTop(optr,opr_top);
5 [2 ~0 I( n( w3 [: n7 Z
c=getchar();
" ]! t& n& r' j, t5 B( B
while(c!='='||opr_top.ch!='#')
* P" E$ A+ N0 b3 A' \. I
{
2 C9 f2 k7 t4 B; N1 z$ R
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
9 l1 t, s8 G8 H) d( i+ V/ C
{
: v" q/ }" Q* v0 X
buf
=c;
. a6 i- M P7 a
i++;
2 D3 B3 H, J+ i6 l9 _
c=getchar();
% s( C- w- H) `$ `4 ]
}
4 _2 W5 `: w/ K8 I% A1 E/ b& d
else /*是运算符*/
; k _' S0 v/ u7 a
{
) Z5 H7 a: R; L! F/ ~
buf
='\0';
- f: V# h) B8 x5 z4 m' D6 f( @
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
, ?9 e) O/ B* E
{
- g6 V0 ]" H9 _1 o; ]/ Q. J
opn_in.data=(float)atof(buf);
8 k4 H8 N! A& p) n7 z
Push(opnd,opn_in);
2 r, A; h# z% b w/ U* C5 [/ O* B" \. Q
printf("opnd入栈:[%f]\n",opn_in.data);
% n5 k( g1 b1 M5 F% G- ]* w$ e
i=0;
+ k7 n- V: I" r1 X/ d
memset(buf,0,sizeof(buf));
' p; w/ J1 S# V2 A( I/ A+ q
}
2 q- ~8 w4 Q/ c0 L1 |
opr_in.ch=c;
/ l# m6 y. r6 G4 Q
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
, |, T+ c- Z5 z g( t6 V! C
{
1 M$ K4 G( f) G( z3 F, v i
case '<': /*优先级小于栈顶结点,则运算符入栈*/
4 z0 O( e" L3 w
Push(optr,opr_in);
# V+ J" v+ g) H/ h# F
printf("optr入栈:[%c]\n",opr_in.ch);
' d& Y3 ?$ M2 Q5 M& U
c=getchar();
. y& T, j) D" V3 Q7 m
break;
. V: ]! L0 ^5 Q
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
) A- R& H$ `. ~- `9 ?! X+ S x
Pop(optr,e);
$ ~: Q9 E$ M- O9 K6 i
printf("optr出栈:去掉括号\n");
% E9 S; M: {0 f2 Q
c=getchar();
; l0 d2 z2 p6 Q- ~9 J& G) m
break;
- T3 n8 E0 g% }5 J; e' Q9 V2 t( Y
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
4 L X! W% U+ x: l+ `* E# h5 A
Pop(optr,opr_t);
0 d n( B) C$ b. q) n
printf("optr出栈:[%c]\n",opr_t.ch);
$ c# [) R# \4 ~5 J; I' B5 [
if(Pop(opnd,b)<0)
7 U8 N6 B# ~ k& q
{
% K# N" Z2 y. y- X
printf("Bad Input!\n");
3 R8 d5 g( y/ t: z" n+ N
fflush(stdin);
# N# e1 Q4 S8 D& u
return -1;
. \7 L. J: F, q
}
4 W8 S3 P+ b# K
printf("opnd出栈:[%f]\n",b.data);
1 r1 y( J+ x+ W( @% d0 Z
if(Pop(opnd,a)<0)
: v8 P. J1 @8 W3 V" l
{
* w" }# ~. P% f2 L+ F- E1 N! ?
printf("Bad Input!\n");
6 _; g) n: {' x# ?5 F* j) Q
fflush(stdin);
7 s8 ?# ~9 a: a3 Q
return -1;
1 r/ j; }/ U/ r; f5 x
}
, p# ~9 o' K8 A( f/ ^
printf("opnd出栈:[%f]\n",a.data);
& O9 v: |# n5 }
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1 a; _+ _. Q% ~. D) {
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
( S- I" P4 q6 z
printf("结果入栈:[%f]\n",opn_tmp.data);
9 ?0 ^2 B' C! p2 s$ w
break;
# o& C( L3 s' C2 v7 o. h( H" X
}
8 C. q& N/ P% h9 R, |& a9 G
}
& C, {; F# ~- |+ Q
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
. O& h) r) w: j1 q" ?
}
1 U/ q3 M, i M) n6 _+ J2 m3 m
GetTop(opnd,opn_tmp);
# C1 e' u6 p* `* w" [, W! g
DestroyStack(optr);
& p6 t5 I+ I R
DestroyStack(opnd);
3 g! c- i$ [; x
return opn_tmp.data;
9 ^9 ?4 \) t7 O$ L" q
}
0 j0 @0 Z6 j8 i: T7 Y& K5 e
& D1 k8 z& h; O1 T( N6 m
char *killzero(char *res,float result)
# c7 s9 H& ~5 g+ y, Z
{
9 b2 i% B6 e: i5 G7 V
int i;
. x2 E# N. Z( C( n& `
0 c% F8 M& w& i; d
sprintf(res,"%f",result);
/ \, G9 R/ n9 j, F; L& [
i=(int)strlen(res)-1;
& R# x( p7 H$ b/ E
while(i&&res
=='0')
( w# i. x. t3 q0 `% a* G4 d
{
- W5 b/ V+ t0 Y% T$ |/ g( I) x% M
res
='\0';
& d2 h# {4 d7 v( Y0 a
i--;
6 g- W a. X" ?, J6 Q. e
}
! X) x6 X. c! w3 y c
if(res
=='.')
- a7 |9 K' h" o/ R: u
res
='\0';
7 V! w+ _ ]' G7 |' l1 ~4 ?. `/ k
return res;
) D- c3 h) E3 ?8 U- d9 j: J
}
; K; D9 x% K r8 u) t
5 \5 u f5 R% `4 Q; D
int main()
1 w) l4 S5 q. |! O- e" q" R
{
& w6 X2 [7 C2 A7 c8 z) |! j
char ch;
8 j6 d6 G, _1 |( M. H, R. ]0 `5 ?* g' `
char res[64];
0 l1 Y4 Y0 |+ Q* u6 a! J
float result;
. K( s# p/ O: c/ h
while(1)
0 p6 v# y/ |6 B
{
1 ~, s" f# l: {5 t' C; J4 {& P7 q
result=compute();
- C- Y# J$ k3 ]" [3 W
printf("\nThe result is:%s\n",killzero(res,result));
: U. L: w3 c% }. j; Y0 _) k# K
printf("Do you want to continue(y/n)?:") ;
( C3 l$ U& {6 ^0 R. V' G8 u
ch=getch();
x! u% B; p- g& e0 Q6 n/ j
putchar(ch);
; H3 L; x" @+ ^4 Q" P
if(ch=='n'||ch=='N')
1 f3 p n7 U+ V; d. U" T
break;
: n/ a! p1 W+ `2 g# `
else
1 e/ y$ m# k% S2 J, a
system("cls");
# E6 n- B$ o+ R
}
- u% G% e1 G$ J3 O/ H4 D
return 0;
( Y, w, S' F: J) b* f& B! L2 {! K8 D
}
) j( |5 b# r9 }( S
' d% l' o/ q) ^, L0 H& t8 C
[
本帖最后由 zw2004 于 2008-1-21 17:21 编辑
]
欢迎光临 捌玖网络工作室 (http://89w.org/)
Powered by Discuz! 7.2