标题:
C语言表达式计算器
[打印本页]
作者:
zw2004
时间:
2008-1-21 17:17
标题:
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
8 S% ~! f/ U! c1 l$ {
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
' R D I; m9 e$ `( n
/**************表达式计算器************/
8 z" C; y6 ~& M2 \
#include <stdio.h>
% f- |% }- r( K2 B5 V* y
#include <stdlib.h>
0 K: j* d; }: M/ d' b7 L( W3 D
#include <string.h>
- ?7 s% l1 A$ G
#include <conio.h>
, c2 g$ t( P# I- G8 W$ v2 n
#include <malloc.h>
! y) _/ a3 J7 l2 P
X( H( }7 }2 j% t- `1 q# X
#define STACK_SIZE 100
1 L, u, O5 x+ J3 Z5 o8 }' s5 L
#define APPEND_SIZE 10
7 C1 @; r: b9 U6 l2 L
; E! g$ m& Q F6 N a
struct SNode{
9 H& N8 x. e; y, R
float data; /*存放操作数或者计算结果*/
. {. [5 D/ h# L! }# p2 d- C
char ch; /*存放运算符*/
* ]( e, `$ Q$ t1 `% {
};
6 H4 y7 c3 |$ b- R) V+ {
' O4 k: o. X0 h3 \% }) M3 \6 T
struct Stack{
. v) O I. W9 h
SNode *top;
+ A. @- \7 c- D" K
SNode *base;
7 D# M7 Q. S; A/ O1 h
int size;
2 e/ \4 ?0 ^; l5 E
};
* [" A/ |% I7 P- g8 z3 p
' [0 Y' t' K0 D; a C; ?) e0 x& z& A
/*栈操作函数*/
( Y* y' T- x- d0 R. R1 z$ ~
int InitStack(Stack &S); /*创建栈*/
3 w8 q, x3 X M) c E* i
int DestroyStack(Stack &S); /*销毁栈*/
+ G# Q- }4 z+ c6 O4 I
int ClearStack(Stack &S); /*清空栈*/
1 Y% w- ~8 e! T8 u) {) l
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
' a/ C/ Y) n3 u' a
int Push(Stack &S,SNode e); /*将结点e压入栈*/
7 Y5 Y# O- B( g7 h' ?8 P w* T
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
/ j& A) T# I0 t) {* f7 ]3 l% D
5 Q: K, Q' J; j# \! H
/*表达式计算器相关函数*/
! P# O5 T2 j X' Q( C
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
' ^7 C# N7 \0 T3 S
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
x2 ~* p! t9 @. N- F+ {& p0 b$ g
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
2 u2 _" X3 N* i
float compute(); /*表达式结算器主函数*/
* o. j# a# `$ @7 [. N" O6 t. y. M5 t
char *killzero(float result); /*去掉结果后面的0*/
9 O% A6 i( c9 ^5 `# y9 S
9 ^% w' ^$ k5 ~& J2 V3 N3 @
int InitStack(Stack &S)
7 Z& n+ Q! i' {
{
6 d! ^& i- H/ F2 F+ v
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
; `4 h8 R+ t; l7 j; [
if(S.base==NULL)
8 J. ~0 K# {. u2 a( b( x! c
{
) t7 L, [3 g0 A }5 G" A
printf("动态分配内存失败!");
' {* N6 x! C- r* e+ f0 z8 j* Y
return -1;
, D. X' g: ?; R4 E
}
. i4 J; w& o0 q1 e6 w0 T) h' l
S.top=S.base;
$ l* w; _) X* j% P. G
S.size=STACK_SIZE;
1 I* k- \8 l2 u$ n' d
return 0;
! R- x, L+ R z1 Y; M# S3 a7 s
}
+ l) y, R0 M p- ?; }, ]& l# {1 U
! Y2 T9 g. U) Z2 `/ _! S
int DestroyStack(Stack &S)
" s+ q v3 N6 @9 k
{
% M5 M2 r! \8 o) ], \
free(S.base);
& _5 b9 P6 T' X0 A5 q' D* y
return 0;
' X3 p2 ~; Z- N' e/ T( w# [
}
* L6 Q1 f$ N" u+ ~+ Y5 ]
: t, t! p) }6 |. Z
int ClearStack(Stack &S)
; `. O. r+ N# R U
{
: b& m [1 y. m2 z) N- M
S.top=S.base;
: X+ D: o% J: J* y, T$ @
return 0;
8 ^* q! u( x+ k$ M `* b+ H% o) y
}
. w* n& Y; q& D$ h& C
: p0 U$ k/ p5 N
int GetTop(Stack S,SNode &e)
1 \) h( s9 S, G$ v
{
" B6 G6 E! {# S" {# Q7 F
if(S.top==S.base)
" ]! Q$ T0 T+ ?$ y
{
0 ]& d( H' x* B! G
printf("栈以为空!");
9 f1 m. s4 i0 }1 Z
return -1;
) J! P4 q; [5 W) J, J4 v
}
% M' O- A3 ?' M0 r I
e=*(S.top-1);
1 L {4 K' v- m2 b5 N8 y
return 0;
3 S9 l7 U3 a+ C( @- h! C$ u
}
' \# U% N- N4 E+ w
( j( J' h1 X0 K, q6 G: Q
int Push(Stack &S,SNode e)
$ Q8 ^/ j% A1 R" D9 X
{
% c+ ] c7 X" `- G# f
if(S.top-S.base>=S.size)
7 W3 `7 {1 n# v. |' J! M2 `
{
' w+ t: M3 g5 X3 ?1 L9 V- z4 V
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
) _6 ~- |# ?* Z" ~% b
if(S.base==NULL)
c0 g, x2 ]$ [! G! L
{
: |% z" t. v8 H: n: L/ z
printf("动态分配内存失败!");
; u! w0 ~4 A; }# J5 E% P
return -1;
! g$ h8 O# \( f- [: P" j2 F- g5 N {1 S
}
- K6 y8 d! @4 ]% }
S.top=S.base+S.size;
+ S1 _1 F5 J; C- b/ }6 p
S.size+=APPEND_SIZE;
8 G% B4 H- g! {, R
}
% m+ D5 p, v; ? p* [' e
*S.top=e;
2 v( K h9 R, _- q6 M) _3 M0 m
S.top++;
" m- N2 r& J3 B' e7 ~
return 0;
; p5 J$ C3 @9 p# o
}
! G6 L V7 f& ]- [, [# T4 X
( g4 j2 n& i6 u; n; |/ M* H
int Pop(Stack &S,SNode &e)
' m3 d9 t8 O' A
{
+ W% Z) Q) w& Q$ @ n
if(S.top==S.base)
7 j; R- l) v# r3 u! A7 w \$ j
{
Q7 `5 y5 y+ |$ o& o* o5 |
printf("栈为空!");
+ Y, v1 y! D( Z$ s
return -1;
- q- a) Y: t. A X, w9 W
}
: g; n4 l) F; \$ ^5 ^7 r' X
e=*(S.top-1);
3 \7 G" a. C) ?/ w0 r
S.top--;
^: e! t' R6 a- K
return 0;
& Y; s6 N0 _- B, A' l: C# ^
}
% ?& w* l. \+ n/ q+ |+ k$ m* l
# J; M& Z3 A% @& t
char get_precede(char s,char c)
' D: |8 H& W1 I3 G. _
{
* [# b( D; k- ?0 Q
switch(s)
# ^! ?+ u0 @* x/ O, W) ^1 I
{
; t \. A W6 t
case '+':
: P; o3 e1 Y- p, q# i
case '-':
" f7 M, M& c( k$ ~) T! j$ z
if(c=='+'||c=='-')
1 l+ K- O# p# Q1 f) P
return '>';
4 W" z; T1 c' K+ @& N
else if(c=='*'||c=='/')
8 S9 k K, r) E, [9 H% I
return '<';
( C" F7 C0 [3 ]) s( K
else if(c=='(')
, ]+ n0 h5 D# c# ]
return '<';
H6 p* M6 Q& d: A4 a8 {
else if(c==')')
! {4 _ u, L( U$ L& n; H! @
return '>';
. i6 L3 j! g8 e! I2 X5 s6 Q$ \
else
+ |1 J6 n: W7 |7 A" h
return '>';
# F' v" S( q9 l) [. g2 F4 c
case '*':
. o4 {+ r6 }+ X
case '/':
* M! w& D( X5 u1 z, `
if(c=='+'||c=='-')
m7 I) P) Q8 ]
return '>';
; |$ I: Z2 i8 }) d/ }; v
else if(c=='*'||c=='/')
* `2 O; k/ Y; F" O4 b' Q: I! o' N5 d
return '>';
6 J0 A! q# J& V& `+ E
else if(c=='(')
+ J4 @% L! \$ ^8 M
return '<';
) m: Q4 Y3 B1 W# F5 o0 o
else if(c==')')
9 J, v( Y2 t/ |3 l* ^& z K
return '>';
3 H3 d; ?: C8 M" C. c- g1 h! f
else
* v8 M8 N6 t' J- f
return '>';
+ Z8 w8 v! A4 L, g2 l+ f8 j% f
case '(':
$ o9 N' ~+ H4 I2 b9 w
if(c=='+'||c=='-')
/ i1 b7 c! A; q
return '<';
K& f4 K; [6 O! @$ O! P
else if(c=='*'||c=='/')
% t& _/ u/ t T- p0 S4 V
return '<';
4 q# m1 d" _- b% E
else if(c=='(')
* F- P& p2 E) `; R: ]3 `1 _
return '<';
7 b6 j. x/ S9 [- [. z# e
else if(c==')')
S8 x! [ m. X3 e
return '=';
: H3 ], S( \! U8 g5 Y8 o
else
$ W7 Y/ t+ }/ B5 b$ B
return 'E';
; C# ~( `: E' h% x0 S! P: S
case ')':
7 M2 `. Z, s m6 {! B
if(c=='+'||c=='-')
% q3 O& R1 l9 |: U9 o2 L( f4 V
return '>';
6 r% E! M1 q Z( m2 I) ]
else if(c=='*'||c=='/')
, P [4 \) D: E! B2 q
return '>';
0 y4 ~# j' ~# b- Q4 Q7 @3 n
else if(c=='(')
n5 D4 F# ?# j. h7 X2 C
return 'E';
4 {' p' H! P! o- a4 m+ U
else if(c==')')
! N b. H7 b p, V
return '>';
# l$ R' [# ]8 [2 p, N/ V) l4 q
else
5 d" ?. G7 O D& M( V
return '>';
; q" B7 M2 O6 G: } D: u. p
case '#':
1 u: v4 u9 x' L2 B$ L! A
if(c=='+'||c=='-')
- o7 X) j0 a' T
return '<';
- Q7 R, F' C7 g
else if(c=='*'||c=='/')
/ j5 a5 S4 S3 x3 V6 P( f1 Z5 H; |
return '<';
. f* P5 e5 x! q" a N7 E5 \
else if(c=='(')
$ H5 Y8 G$ ]& X$ u5 m; {
return '<';
9 e& z5 |' p7 G: L7 X% F) K% d6 i
else if(c==')')
5 S4 U3 Q0 ^/ [5 B0 u! U
return 'E';
1 u' P$ |, S5 F' [" D8 w4 G& N1 w
else
6 c- {, l! V( h" w. M! |
return '=';
/ F. X# y9 ]- x$ {( e' M. ^5 }
default:
0 G- ~. E3 d) j/ g* ]5 B" v
break;
) u6 Y: B5 v: a; {, ]0 M3 ]
}
) E7 x6 r' }% L* u; H
return 0;
1 f" r9 I' G# Q% a
}
1 p. F# ?5 W# F6 p2 Z# n! @! n
! Z9 o4 |# a6 F. O; m2 ^
int isOpr(char c)
7 H! d( r! n) k# h& z- h
{
) c6 b7 u+ D6 p2 b
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
2 P @3 M6 t4 @! y$ w
return 0;
0 M$ k. r/ {1 R h- U8 w
else
: i. C: Q( b4 H
return 1;
1 r! f1 }( r' f' P* H/ ^$ X
}
9 x# u1 A+ J! \" Q6 ?, ^& ~
9 n& y* q- T8 O$ f- w- e
float operate(float x, char opr, float y)
' ^* K8 ^) Y+ \3 `9 ^: ^+ y
{
6 @: A0 U" A3 F. @, K8 K
float result;
# u4 R5 _8 l! j* T4 F: j' o: x% W
switch (opr)
3 k+ C% M1 z3 e5 r; e2 U/ O
{
1 m' W" M( m% |$ e- D/ P& e
case '+':
& M: _3 |1 \+ K* W. g' i
result = x + y;
" w# P2 ~$ p W2 i9 L1 l
break;
$ g9 Q+ u5 k2 V
case '-':
8 _% _& u; Q ]9 P- v3 V" @. {
result = x - y;
( b' n. k6 d# x9 H2 C4 z* z
break;
9 M0 \ L( }- a( B; w3 o( B
case '*':
& y# L4 n. M, G& f
result = x * y;
, D0 y Q: Y, v9 D! c6 `) P
break;
& `( A" p/ i; m+ W
case '/':
" J" J2 y* T( l
if (y == 0)
7 z! o' l" M& \9 l9 u c8 [% r" ]! F
{
" C8 I2 t* I* P& y* H. }
printf("Divided by zero!\n");
0 \1 X* V( j5 R" B
return 0;
+ c, N2 o( o' E: M- q
}
1 g3 K1 K) A0 C; P* O3 ]
else
# O9 `9 R) K, V6 @
{
& ?2 S: A1 Z' E: H. O, _) V: V: @
result = x / y;
& u0 D) o% S; ?. t- v7 D# L
break;
- C) U3 x( P" T7 G& a
}
9 R; X" R+ Q% U3 }* j. c- C
default:
' ~$ T, i! w c' G
printf("Bad Input.\n");
/ F9 l, T0 F8 P; k- F
return 0;
1 f3 f, I7 o' m+ p& a4 x
}
3 Y8 c3 `& V6 g3 X
return result;
& [. Z6 M% Y6 t
}
+ j6 o% e" u- z1 t9 W. J
& B! E! {4 `! f0 ]* x9 O% S
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
3 _6 u/ T, h# }- i/ ~ |- w; v
{
; _+ p% t& s% e
Stack optr,opnd;
( a# k$ P. X* [7 d4 d
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
* x# t( Y: i! |4 @ @8 ^6 Z
char c;
% }0 c8 Q$ l0 n2 _ }! r+ W+ [
char buf[16];
/ ]( f& G o( [
int i=0;
& ?. k% T) F! p. J$ D& q& D
2 j0 G3 G) m. f; o
InitStack(optr); /*用于寄存运算符*/
2 f" @# t5 E- E. b! w' o1 |
InitStack(opnd); /*用于寄存操作数和计算结果*/
" A& |% }, _" R7 V% g. u% [, [
memset(buf,0,sizeof(buf));
$ |- G: k" I% Q2 N/ j+ x
9 ]3 ?6 {+ G5 A( B
printf("Enter your expression:");
* O& t; Z1 P Y& p- }
! e. r# Q% B0 I8 c9 @
opr_in.ch='#';
6 C2 q: {. b/ a1 t! H0 r
Push(optr,opr_in); /*'#'入栈*/
! _1 A, {, D# n7 U6 N/ O8 K. K& H/ B
GetTop(optr,opr_top);
# G: Q3 S; z' p2 ]
c=getchar();
8 Q8 \5 U6 u' p& D. ^
while(c!='='||opr_top.ch!='#')
* b" I9 Q* @3 J" d- G5 J
{
0 e4 I1 I ]' v: n5 V# H3 l
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
4 e* A0 W, q; w1 O; R$ q
{
4 k% `9 Q/ O2 S. [$ l# Q; L
buf
=c;
; m6 \" b2 V% a0 ?
i++;
/ N% F4 q, o* J. b- W
c=getchar();
3 l+ b0 S) ~- Q& u3 {+ Q4 M. |) u
}
1 N8 F3 R# R0 l, @ s0 t6 g) W
else /*是运算符*/
0 _( b; w) c/ M8 a. ^- h
{
6 @% p+ h. O p- y9 J! E; P/ x
buf
='\0';
2 E5 X L+ g% G2 o, A
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
F H5 X+ W; K
{
* }- H# x" @9 Y. A
opn_in.data=(float)atof(buf);
: h$ ?0 x6 X- _! _9 x* T
Push(opnd,opn_in);
+ e* P# a, j: S
printf("opnd入栈:[%f]\n",opn_in.data);
( c5 H2 D( g3 o% h! ^% e
i=0;
' i$ Y! V- v! O+ E* t3 h7 _
memset(buf,0,sizeof(buf));
! ]- G$ n! E% f9 d4 j7 R# b# E
}
1 k. {# @) n8 b* q1 f
opr_in.ch=c;
8 |: F. H4 {) Z& U+ G) k9 F
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
3 Q/ ? j3 s7 Z& L. X
{
( q W0 K( b% y S
case '<': /*优先级小于栈顶结点,则运算符入栈*/
3 ]- g7 }$ [7 R/ R+ ]* {& b' n
Push(optr,opr_in);
7 e) ~: _9 t2 `; p. J5 m
printf("optr入栈:[%c]\n",opr_in.ch);
2 Z, W; P a' o' }# F
c=getchar();
]( J. R9 L8 p# w4 Z' _* U4 K5 [
break;
: N" S/ G: n7 G% U% k8 ]
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
3 {/ @; \3 ]5 [0 ]# K+ Y) d" S" `
Pop(optr,e);
8 V% I3 ~4 C9 y
printf("optr出栈:去掉括号\n");
4 A5 V4 J& i. L5 v
c=getchar();
6 |; X+ P' P0 Z. Z
break;
3 I4 W7 t) V3 [5 o' q3 O% S
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
0 M8 r2 q' T+ l) ]* y
Pop(optr,opr_t);
' z' J4 T$ a; D5 ]# h
printf("optr出栈:[%c]\n",opr_t.ch);
9 k3 K, n$ x4 f; N" U2 e* L+ W2 g
if(Pop(opnd,b)<0)
6 f* p6 G# f, O
{
% P) c* y3 L" U
printf("Bad Input!\n");
6 _ I7 M0 T+ A6 Q, o
fflush(stdin);
( |* P# F4 n$ J d: [6 o
return -1;
0 R2 E3 f+ c, g4 P1 q
}
, [/ D$ Y' ]7 x
printf("opnd出栈:[%f]\n",b.data);
4 e- ]9 o; h( j
if(Pop(opnd,a)<0)
7 _! r$ B" I* Y
{
. a8 [% W$ @1 Q# k6 _
printf("Bad Input!\n");
( U; p; }; Z4 G6 f" x9 |: I# s+ m
fflush(stdin);
! I" n% j& B8 M% v" F+ ~1 I
return -1;
# y% M _# _2 s9 Z- y' w; }
}
0 o3 _) u: I' ]4 ~ T, f; z
printf("opnd出栈:[%f]\n",a.data);
$ o4 R& ]& h5 `3 [" x5 D! R
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
; \) c# c/ f2 L0 S
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
1 j5 l- @/ S5 A M# }
printf("结果入栈:[%f]\n",opn_tmp.data);
0 H0 R: h/ q& E4 ^" D
break;
6 }' P2 L9 `, P4 F
}
+ J0 [. c+ j F- E, j
}
3 j0 H' R N2 U1 k
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
8 ?' t, [! U' C$ W
}
( Y% I7 _4 Y p
GetTop(opnd,opn_tmp);
: I- z' w, Q) i U4 N6 l/ M
DestroyStack(optr);
8 g: _& b& Z: y
DestroyStack(opnd);
0 I' k% w! Q, E0 q9 U; s3 Z
return opn_tmp.data;
9 h6 l' a' O, y& I6 c9 b
}
& ~9 \8 h+ ?8 Y7 V4 E
, k# g$ H4 z3 E" V+ I; Q
char *killzero(char *res,float result)
, S, t) a# Q- g- c4 h% x
{
% E: q1 h4 ~4 V1 ^
int i;
: x! g0 j2 e$ F
# Q5 M+ E* }2 \* y! a- Y
sprintf(res,"%f",result);
; \+ }0 e/ t( z. P1 \) T& }
i=(int)strlen(res)-1;
* y$ |* x* }; a$ \( w. @. l
while(i&&res
=='0')
! A, w* f3 X5 v7 R- G
{
7 Y1 k; \7 ?9 y! r( x
res
='\0';
7 f7 y5 \5 d9 H9 ]# O
i--;
7 ~0 ^' I% R5 a, M( c2 L' v( V
}
' z# k. d, m4 H( \8 H' Q! L
if(res
=='.')
6 ?" J) e( y( D @1 J
res
='\0';
( S+ m* E S5 F: ]
return res;
7 V: o, T- u6 ~6 A
}
6 Z4 A6 k1 l `9 n5 \3 v+ B" y+ r
% n- A" p% ?7 g2 |& ]; X6 p
int main()
( _3 K. N# l7 F8 M; _ t, O4 }
{
' A# }% `# f2 p
char ch;
6 T0 z$ P3 R. Y% H, s# U* I
char res[64];
l6 X# d" P5 R9 e/ l
float result;
/ I, R8 A; ]' h! x. v, q' a
while(1)
, e" J$ Q. r, H4 M2 H3 g
{
1 Z% N. Z' C6 m4 y& a) J) X7 u, N9 q
result=compute();
" G c/ G% u( i) m" Y
printf("\nThe result is:%s\n",killzero(res,result));
4 b l* Z2 Y0 U5 y2 `! O) S
printf("Do you want to continue(y/n)?:") ;
/ N! f7 W2 ~! k- m* l, f
ch=getch();
/ v9 I& T w, ^% H- z2 U& t
putchar(ch);
) v3 S y! a" K. I- @+ G
if(ch=='n'||ch=='N')
8 v; Z6 ?9 A; H* [. r# n. ?5 Z N7 }
break;
w0 ^1 E$ ?7 F7 u, I. w
else
- @' i; m( N) f7 S
system("cls");
( E! F2 f: ?' C
}
. p+ H1 z* ^5 p
return 0;
( r2 r# P6 z$ B9 F
}
4 H+ d8 W) y: z+ }' f
* }8 w+ l6 x/ u3 B) m
[
本帖最后由 zw2004 于 2008-1-21 17:21 编辑
]
欢迎光临 捌玖网络工作室 (http://www.89w.org/)
Powered by Discuz! 7.2