标题:
C语言表达式计算器
[打印本页]
作者:
zw2004
时间:
2008-1-21 17:17
标题:
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
+ \2 K: G" B" ?# c* }8 ~
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
! Z: K' N# X5 L1 G* w' D
/**************表达式计算器************/
2 _# d+ H2 D( g/ _6 T& R
#include <stdio.h>
3 E- t' D% I: x/ x' n z
#include <stdlib.h>
9 Y, ]( S: y7 u
#include <string.h>
7 c. b, ]- e I6 ?
#include <conio.h>
9 d9 m" |9 ]# m
#include <malloc.h>
3 _% u6 M9 c* Z$ V% S& C* N; G
; O( ?$ n8 N) O- O
#define STACK_SIZE 100
* ?% r6 r* v* I' o# Z6 ~
#define APPEND_SIZE 10
0 G& m9 ^0 C3 u. e S2 k7 u/ |
5 N7 ?& T: k: r" ^) ~) T
struct SNode{
; P( p/ ~8 E7 j' d }3 V# F
float data; /*存放操作数或者计算结果*/
7 t" R. g( x- K0 x% ]/ h
char ch; /*存放运算符*/
1 s( G7 O( r3 i" \
};
. y8 E4 {6 X; b9 Z
4 J0 f' W% j3 K% l5 H; Q1 w5 j9 u
struct Stack{
; g$ x8 r9 r& C. M9 k+ ^
SNode *top;
! H0 E% t) D! z7 V
SNode *base;
1 F: P8 K+ p- \5 C: D. r
int size;
4 ]9 e! I3 h# Q
};
1 y& o# F6 H+ l1 |
% D! ] C% |3 s/ V
/*栈操作函数*/
" B) i2 Z( d8 O- Q: T U
int InitStack(Stack &S); /*创建栈*/
5 N2 \& r V2 @$ E
int DestroyStack(Stack &S); /*销毁栈*/
" Z" F8 j: ]6 x" |# y
int ClearStack(Stack &S); /*清空栈*/
5 n: O4 v: g# H0 U, l. V' I
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
C x# k! g- @/ U l+ y
int Push(Stack &S,SNode e); /*将结点e压入栈*/
8 u- F1 b- @# \( A8 E0 R
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
" {- E; ~1 p2 b4 k
3 R8 m5 ?; B* _. \
/*表达式计算器相关函数*/
3 {* P! m& a: \* M
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
4 p& u0 D' J O0 C- E+ f
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
o/ V/ x% k$ q- E
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
w3 p+ j; P0 I @
float compute(); /*表达式结算器主函数*/
' n, P5 B& N$ G" B( Y
char *killzero(float result); /*去掉结果后面的0*/
) G$ i+ ~. r! _+ e) F4 s
: M6 r* Z' c& P) n7 K( Z
int InitStack(Stack &S)
) J, u2 r" y7 O2 t4 M# {% U
{
/ q& h3 @6 A/ Y: y' q
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
' m8 n1 [& {2 A2 [
if(S.base==NULL)
6 D9 P4 s( c+ s2 h- D) T1 l3 L1 u
{
: F3 Y8 N( S/ g+ v3 |
printf("动态分配内存失败!");
9 [8 R1 J/ v+ Y
return -1;
" h }; x; ^6 ~% n
}
0 s0 U$ X; i: | ^& D
S.top=S.base;
# G0 z3 Z0 S9 L; ?
S.size=STACK_SIZE;
, Y1 n0 |1 i5 P1 l- u$ o% [
return 0;
% W0 I- @2 ]9 `* l$ [7 H
}
! \ w& s) X0 d, M
1 v9 ~& A3 a Y: x
int DestroyStack(Stack &S)
; w; t# A' q# c" T
{
% t7 u' _$ g8 h. Y; ?2 U, E3 |5 U
free(S.base);
. \: ^, x' n4 N' ~! e$ m
return 0;
2 w6 \5 f: r2 W) F7 }2 M& g8 j
}
, u S6 ]- m& N/ U6 I% f/ ^
+ V% H: A0 u- q! @! c
int ClearStack(Stack &S)
% K- E6 H4 ]' l! f4 S) [
{
# w6 Z# s" x8 l9 E7 {9 k* u9 {
S.top=S.base;
. U! j$ G6 k! F2 C- u
return 0;
4 `" \/ l7 G) a
}
1 b/ Q+ V2 q" \# @
2 V: X- X' L5 ^0 U+ j" x
int GetTop(Stack S,SNode &e)
" X* o) E7 I1 d" b+ l& R
{
- C* w; @6 G/ H/ N/ w' [! L
if(S.top==S.base)
; z7 o1 j5 ^$ c+ _, W( B4 j+ Q0 n; Y
{
$ o$ X! I" Z3 l5 K& K2 d
printf("栈以为空!");
2 T) o' V! a7 n/ I% e4 w3 Q+ H$ @
return -1;
5 X0 X" p) m* n" z/ k% T
}
- p% W- {9 e: U; Z, l1 @
e=*(S.top-1);
% d$ B; Y1 e- _* Z( G
return 0;
5 j# |5 ?- J) ]( E; h: d
}
' c9 Z8 n( S# E& o6 E4 V# h' X
7 V7 n+ O/ Z6 w- h a( `8 N) y
int Push(Stack &S,SNode e)
5 V1 `& }/ H0 T* @. V9 U1 T( N
{
& \% C0 z5 Q& ^# d1 k% }- N' I+ ~7 J
if(S.top-S.base>=S.size)
P+ E: r" R" u/ m
{
9 G. V0 P' n0 i
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
& X$ G/ v8 N7 ]/ Z
if(S.base==NULL)
: G Y+ k' v4 m, B
{
: r* H! i% a3 ^
printf("动态分配内存失败!");
4 l8 m/ _6 q+ i' ~5 X: c( G
return -1;
1 \. ^; w3 h) |
}
! @! r/ t4 o; F$ q
S.top=S.base+S.size;
: _3 ?% M. r# b' Q7 Z
S.size+=APPEND_SIZE;
$ w" `' m; a& M
}
$ C. D# i6 i$ x* \1 S# j' c
*S.top=e;
+ s! @% @) ?5 P5 S. Y2 Y1 j' ^. H
S.top++;
; F' W) \) [/ R: Y
return 0;
3 ?* Z. j O. P; r1 J% q, A2 v
}
; {' c; r6 T9 t8 d
' J- L0 R: j/ D& O0 `
int Pop(Stack &S,SNode &e)
! n2 K0 j. ^0 r) R/ k8 x1 b; K( W
{
9 R; s0 r7 `" [- a9 w: R
if(S.top==S.base)
$ n1 y# A1 Q! |. l; d7 o
{
& s- b P3 E. K7 u
printf("栈为空!");
9 o ~! P! }" j7 @) I
return -1;
! I2 v& D4 W& @0 b$ m. o
}
, C* ^& b" S9 f# F
e=*(S.top-1);
7 `" ? n! }, Y6 r, _! _4 `
S.top--;
4 ~3 g" c% F& n- y$ E F
return 0;
. m4 P4 Z. G7 B9 f
}
* V9 ~( F/ r2 |
9 f- n$ h0 B2 D# N: E
char get_precede(char s,char c)
. d1 r4 t+ z% M( H
{
, w7 X) T3 G4 ]
switch(s)
2 U! Z# Y6 D8 Y% V9 o1 `
{
8 T& @* z$ N, }2 t! _ t+ [2 Z+ p
case '+':
2 x* c9 W1 Y7 g" U. [; Y
case '-':
3 J6 u. p' F& a1 Z1 s
if(c=='+'||c=='-')
% G1 e: |2 O& d7 f9 X
return '>';
' |# b3 F; d2 w7 O
else if(c=='*'||c=='/')
& v+ v7 v. o' ]
return '<';
/ s9 U$ J% Q6 i6 k& n: X
else if(c=='(')
" r0 I4 \5 F, ^6 T4 q. r, F6 T7 c
return '<';
) v- z4 L, M, { y3 A9 O, |
else if(c==')')
5 \& d0 v) y, V
return '>';
& Y: B' u {8 B7 _7 X% {+ k% x6 U
else
& Z4 f% v3 L$ [; ~ W" h, I+ \5 n
return '>';
' j0 i, H4 ^. S! I6 F9 R% X
case '*':
8 G$ g" N7 \. M( L
case '/':
; Z" y! R* a! S
if(c=='+'||c=='-')
8 U6 A2 p) x6 W# W9 P
return '>';
* q7 ~0 {- v/ H* s) {' E, I, ^- n
else if(c=='*'||c=='/')
2 N& N- a3 k0 q3 l0 k
return '>';
: ]0 ^' w: K8 `* \% ?
else if(c=='(')
' }$ |- L+ h0 M5 z2 ^
return '<';
! }* C8 D _5 |" O& S& l
else if(c==')')
- q2 o$ I$ O8 M* i- }8 A+ G
return '>';
! I! a' J5 I8 O- U& c- G( T8 V
else
& D# I9 \' W1 \: [! Z
return '>';
- n0 c5 t$ p. Z1 C
case '(':
! A: m6 z* k( q, P/ F
if(c=='+'||c=='-')
, B5 R8 q1 r5 K: t, t. f! k# \* `; C
return '<';
) i3 P5 W7 x8 ] l: D1 T
else if(c=='*'||c=='/')
, k6 `3 ]7 Z+ `" v3 p; h$ _, B. ?
return '<';
1 m. [7 p: s2 ?) c: M, I+ W
else if(c=='(')
0 s% y8 J2 n6 L3 G+ z
return '<';
, ]8 D. Q. k$ J( M8 t: z
else if(c==')')
, j r$ R+ y9 W5 h4 ~6 G
return '=';
/ [( w$ K4 u& Y) i% a
else
1 v0 V+ X% `) m
return 'E';
1 Y/ t- V3 x& q4 p
case ')':
1 e8 n& v2 z& t' V+ R6 d) |
if(c=='+'||c=='-')
2 @1 u) K6 P8 z8 l/ e3 s5 D- j
return '>';
& j/ s% b4 n- h5 x( M
else if(c=='*'||c=='/')
6 J: Z3 E, S1 \/ |" r7 H3 L
return '>';
0 _, [* \' ~& ? p
else if(c=='(')
! C" z3 l; q5 f+ q, [9 @
return 'E';
$ e; B( [7 ~: r; W
else if(c==')')
$ h2 V' H+ L! f
return '>';
, J |% |+ y) i/ b. B
else
0 s2 n% ?# H6 F$ y* N8 \" p
return '>';
$ ` o4 n3 p8 k/ o) y! {
case '#':
2 x& Q+ {3 v: o6 x, d
if(c=='+'||c=='-')
+ p) w; M: u- O* p2 U3 z9 P7 O$ W; e
return '<';
1 \- V# t5 _$ Z/ w! b3 ]/ g+ C3 a
else if(c=='*'||c=='/')
; q& f \# J* E v2 W
return '<';
% m$ ], c; m7 w, m& e
else if(c=='(')
% Z6 |8 T p' X) ^8 A
return '<';
% u6 w' L6 o- z1 b- Y
else if(c==')')
8 f, C5 X9 ^ d( y" n7 K+ O
return 'E';
9 h2 I( X7 x$ i; ]
else
7 W7 z$ j' O# n! n( X
return '=';
' u3 h) `3 {$ ^4 @' e1 F: S
default:
1 @% `5 G% A& S/ R! l2 [7 j2 V
break;
6 L/ U% p& E1 t' n
}
9 ?3 J5 }- b9 z; k; s
return 0;
1 W# V# H9 V5 u/ k* `1 z! J4 j
}
# [0 L2 ^' d+ F$ j2 U9 @3 A, g
. G0 S2 T" R# x* s* K* M
int isOpr(char c)
( N) R# t: M9 ` n, N
{
. z4 n/ e3 X: ]; s3 Z+ a: ]
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
& R! c$ x( Y& ~# E
return 0;
( \* \( }2 G1 e& j0 \! n0 @- j
else
3 ^1 j. E0 `# ^; u& t5 {' K( a' i
return 1;
' P& y3 m R' _6 g- C- k: l1 h+ e
}
) f$ O6 g) S& _5 o
' \ @" y2 ?, V8 f9 L- M8 k7 F
float operate(float x, char opr, float y)
E/ g% C7 Q$ H+ Y1 n
{
) s Y) X- p$ u5 x S; U7 Z
float result;
2 u% s# \# V7 Y, H' v4 g
switch (opr)
& W$ L l9 l# s+ k) \5 P! S( w
{
; A: j' ]# j, d6 E& I( i) G
case '+':
% p$ e ?1 o4 M. W; ^
result = x + y;
3 z* D! d2 {6 ~* J' k
break;
' ]$ T, H2 C! g. ]) i
case '-':
: U, X& G# ^- W3 M
result = x - y;
. i5 n0 `) w+ ~4 y7 d, e
break;
9 Q! g2 ^( _1 F5 u
case '*':
( l& ^4 q. v# K0 l
result = x * y;
8 ]' D+ U9 X6 O' S0 h) G `; k i
break;
0 x7 L0 ^- C- h
case '/':
1 d5 \/ S; _9 j0 ~: K
if (y == 0)
! `) ]+ E( C v0 G! J$ K
{
# Q% v" I% w" o9 ?4 V% e, P m
printf("Divided by zero!\n");
; K M! @) c+ x* D, P
return 0;
$ g! ]4 Y; S2 v+ G9 n! i
}
4 L$ p \; h. r2 S) X" I
else
! h2 K# t& t& V$ C& @5 E5 m) X
{
0 M. h W8 [& j5 h2 c
result = x / y;
' K0 t& P5 o; D
break;
+ X: G+ b0 {7 I3 a- P: I$ t/ y
}
$ E+ d& z. r+ X4 k# t; f/ {- r
default:
1 q% C7 Y1 c+ e) q1 ^: T
printf("Bad Input.\n");
3 r# q2 {* E$ m/ j/ p7 Z
return 0;
: f, z- z, p5 D9 _; B
}
) m6 H- d; _1 x1 r
return result;
7 z( f2 d* L/ C3 k3 J
}
% q6 o- u7 \. D! {& y3 N
9 ]2 [9 @9 B, X2 a/ o, ^
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
4 ? c. n) ?$ x" H! k
{
" \+ _2 I9 _( ~+ T; J
Stack optr,opnd;
% j9 V+ u- S! O9 K5 g
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
2 K i2 y% `" B# f
char c;
1 X+ {* e0 i, Q5 V9 @- y0 n
char buf[16];
) M C% j& _7 t: N+ O8 I8 Z' I
int i=0;
( e, }; S* U |/ y
: w( a# v0 {+ B: {: o# W
InitStack(optr); /*用于寄存运算符*/
" k/ J& o: r+ Q4 J. }* |
InitStack(opnd); /*用于寄存操作数和计算结果*/
0 b9 L8 d. x4 K9 [8 d( C" k4 ?( _5 N/ }
memset(buf,0,sizeof(buf));
2 x$ s: V8 R- w2 A }
: @6 O: ]; r: o$ k& h
printf("Enter your expression:");
3 e5 D) W( G/ a6 c, t
0 Q0 M# z% R F* p
opr_in.ch='#';
6 h: W" F0 x, Y$ U
Push(optr,opr_in); /*'#'入栈*/
) x. m; X8 m, m- m: Z ^) x
GetTop(optr,opr_top);
& }- `' F: D9 k# T5 s
c=getchar();
: G( {- b+ e' b8 t' c$ i$ N% Y
while(c!='='||opr_top.ch!='#')
$ h% G$ p( x& J+ ~2 ^
{
5 N* `* [! M' X" h( E
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
9 v9 F0 J4 o, |# j% ?7 c
{
% d5 e+ x6 m' j+ j! ~) `
buf
=c;
m: i. a4 \+ @ ?
i++;
$ i4 b3 s3 q3 H9 I! R
c=getchar();
% i3 H% [6 u* M& c% @ X
}
! t( V+ ` Z+ a2 Y0 e
else /*是运算符*/
/ {6 u8 Y. ? C' s# S
{
; {, c2 o$ e: _, b1 u+ k
buf
='\0';
4 [5 D3 K7 O$ D6 H4 `* Y
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
& D' [/ i! G3 x# \7 z8 ^
{
% i: \7 H; }% ~, z# j- ?$ ]: O
opn_in.data=(float)atof(buf);
. k/ N' O" l7 r e# r
Push(opnd,opn_in);
& y& ]& p' V6 o- _- r9 [3 |* i
printf("opnd入栈:[%f]\n",opn_in.data);
; G6 L/ k: O2 [* z: k
i=0;
; J0 o1 C5 v* i7 s7 h% w
memset(buf,0,sizeof(buf));
; B. y6 b) h# c: k# n
}
0 o6 I1 a4 p0 w0 J
opr_in.ch=c;
( d$ N/ R# Z( s! P3 d/ L
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
4 C, o X: b/ K; D
{
/ A' b6 p+ K S. W- H* H
case '<': /*优先级小于栈顶结点,则运算符入栈*/
2 V A- f+ o1 }3 _
Push(optr,opr_in);
/ U7 I) q- e5 H7 p; C
printf("optr入栈:[%c]\n",opr_in.ch);
Z2 T% Z) F- Z1 b( \6 ]
c=getchar();
! h! A& `6 O0 n
break;
) _: {+ j$ j. d, O3 [" B" m
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
9 N1 T- A, ^$ _( o
Pop(optr,e);
, ?* f5 J" h( m4 `9 g
printf("optr出栈:去掉括号\n");
- i7 @, N) [7 c6 n0 p: @
c=getchar();
Z( h) A- K( ?) X+ O5 d9 m6 x
break;
$ B1 {# a5 D! B* i! N" W
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
. S0 G5 N0 ~) P0 L/ f
Pop(optr,opr_t);
4 P0 T$ X7 W1 Z1 I7 t: R \$ e) x' N% P! N
printf("optr出栈:[%c]\n",opr_t.ch);
) d4 K T, _" D
if(Pop(opnd,b)<0)
2 y$ W$ {5 w L& ?
{
2 J, K% @% G5 l6 x! t5 ]
printf("Bad Input!\n");
5 C' N& \1 |8 a2 A6 s1 D
fflush(stdin);
0 Y. e7 [9 }% e+ B
return -1;
O- V$ ]& k C3 Q- a
}
- P7 Y, q5 e+ G) M* S, I% j
printf("opnd出栈:[%f]\n",b.data);
1 F% j- u. P7 T! j7 ?- _7 X5 A
if(Pop(opnd,a)<0)
) v; ~$ f) Z" ?; x+ z" {8 {
{
4 ~4 v8 a4 j2 P2 F! a6 u9 k+ {
printf("Bad Input!\n");
b1 @# c: v( v- e: `* K
fflush(stdin);
& `8 _! y1 y- @) s' m
return -1;
+ W+ [: V0 B- @+ ?) _; G
}
) f3 y! g( o# l, G; V2 Y! R- ]
printf("opnd出栈:[%f]\n",a.data);
* z; }4 l+ x$ N- N1 g
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
. m* d0 Q0 i9 c* ^3 u' @, V
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
, f# [8 J$ h4 m+ d
printf("结果入栈:[%f]\n",opn_tmp.data);
# t; ~8 H) `/ i7 ]* |1 i# v
break;
- E9 I6 w5 J0 J: P8 c5 Q
}
, ~+ T6 n" C0 N. _1 ?7 E
}
* I% p: J* m- y2 E
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
, R' J9 u3 O1 R
}
- S" i0 n9 k% @8 z
GetTop(opnd,opn_tmp);
2 R) x7 i& p* _3 E
DestroyStack(optr);
+ ~ S: b. w5 ^" P0 n4 w
DestroyStack(opnd);
; L& ^5 S& N* L
return opn_tmp.data;
( M, Z: K& P( l) V# \; E5 C
}
( P1 S6 }1 v5 L X
3 q. S3 P! }) [2 T7 f
char *killzero(char *res,float result)
4 j5 L6 S4 g+ v) \" G; a& T2 ~. c
{
5 j) I' @' o' t* \. b
int i;
6 j# M! I% T7 K% j. R
7 ]1 B. u7 P6 m
sprintf(res,"%f",result);
! m! C7 T- e, A: }
i=(int)strlen(res)-1;
: E7 }! m# L3 q
while(i&&res
=='0')
7 d3 }) ^. w1 U' F; `4 _
{
2 Y' P. n" o% L: S& x
res
='\0';
# o* O- G$ z% l& r" c
i--;
4 F- j& M- A* M6 T9 G
}
6 o# Z) p2 X% T8 C' R
if(res
=='.')
' d# j# z. x* X; a
res
='\0';
: X2 k3 z v$ i; Z4 A
return res;
( T/ v# |& ]! W
}
; ?; p) k8 n: e- {$ x" `
6 g8 x. o% g( q, I8 \0 C
int main()
4 V7 d0 _/ |3 b3 V
{
2 H2 y/ b# z, P0 |$ W
char ch;
, N# G. O- a# W- R5 |/ t
char res[64];
& C$ M. M5 U: J7 c
float result;
, F2 f. ~2 y/ q* c' Z& y5 k0 n+ j8 g7 j8 D
while(1)
; ~/ {2 I# E5 n% W' X n. y
{
" h S+ T7 b5 B: k2 m
result=compute();
1 K; O+ U/ n1 X
printf("\nThe result is:%s\n",killzero(res,result));
; B, o/ V4 f4 W3 `: K& M
printf("Do you want to continue(y/n)?:") ;
n" J) c" ^$ N, e' G, ~$ S! |
ch=getch();
$ R; d- y5 X/ T% o8 P
putchar(ch);
; @3 k- ^8 k9 N: ?! l
if(ch=='n'||ch=='N')
5 x' X7 ?+ T8 U a# J$ z& c1 p
break;
4 Q6 J- W% J1 G" U
else
! w! \* ^' U. k3 f8 n( T
system("cls");
- J2 k4 E. c F: i
}
- r! z% ?' U$ s1 ^
return 0;
4 d. ~( d7 w, J) V4 E" C
}
B8 l9 {" W9 l! r
( K9 p( N+ G& D
[
本帖最后由 zw2004 于 2008-1-21 17:21 编辑
]
欢迎光临 捌玖网络工作室 (http://www.89w.org/)
Powered by Discuz! 7.2