标题:
C语言表达式计算器
[打印本页]
作者:
zw2004
时间:
2008-1-21 17:17
标题:
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
: p# I2 ~* z% \' z% I1 r0 X
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
5 ?$ U5 d, w' H- [( r
/**************表达式计算器************/
$ N+ W% U0 G$ h8 z
#include <stdio.h>
5 J. z/ F% s3 y/ w9 J9 L5 |
#include <stdlib.h>
5 f7 {- j! M0 H* \; i
#include <string.h>
) Y; ~0 I& D9 `
#include <conio.h>
- L/ b: g: J; C! h0 c `9 U! ~4 D O# G5 A
#include <malloc.h>
, Q8 g. i5 O! N4 M6 D
: m- a. m- B0 W: q: _! L2 \
#define STACK_SIZE 100
& F0 O a- ~: Q: k W \6 `
#define APPEND_SIZE 10
( j& z/ l9 _; B6 B. B
# |1 z0 t4 |" m& b0 R
struct SNode{
1 |5 X' ?* S9 v- r0 M# Y/ `" H# ^
float data; /*存放操作数或者计算结果*/
7 Q' c$ W5 q' U4 ?* O, P- j* x+ w/ [
char ch; /*存放运算符*/
/ p, Z: f+ H( P$ x" M
};
2 e5 j2 ?7 V# ^. m: k
+ p; I) d& b9 H% m. x6 A$ T
struct Stack{
: `3 K" d; t0 T$ K& x1 f! L' Q
SNode *top;
0 _4 j6 X" ^/ O) ?
SNode *base;
9 B+ e1 s1 z# _, s, T1 L
int size;
- T, X7 B' l$ l9 x% n" b( `8 u
};
9 k/ O; K8 ^$ ^
. b {, j5 k8 j& Y2 Q
/*栈操作函数*/
+ F, S M9 p+ e8 V
int InitStack(Stack &S); /*创建栈*/
6 B7 M% V0 x. q7 F4 b
int DestroyStack(Stack &S); /*销毁栈*/
: K8 ^- v) } l) J# h0 W
int ClearStack(Stack &S); /*清空栈*/
) A1 O- ^# [5 }( }( I# h" V* @' _8 T
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
( H# [4 J: b% x% i* b F6 P
int Push(Stack &S,SNode e); /*将结点e压入栈*/
7 s8 Y* A! q0 O2 W& R: ?. v6 w) [
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
. D1 r# |3 w" v! F+ j
6 x4 c( m* f+ W+ _4 E2 d. n
/*表达式计算器相关函数*/
5 ]" d0 x+ Z& X% y" n u1 B
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
+ D9 M; T2 j1 W9 k/ x, O$ a2 o
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
7 u4 t* j, f- e2 H' S
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
/ b, Y3 Q+ | ~0 t
float compute(); /*表达式结算器主函数*/
. D0 g# g% b6 l( b6 Q5 R
char *killzero(float result); /*去掉结果后面的0*/
6 p2 K! P) A Z# Q6 q
) e8 _! N6 I2 ?8 R, N! Q
int InitStack(Stack &S)
0 g. E" d. r, @& @
{
+ R8 l6 [/ Y4 Z, A2 _
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
+ w8 g% N2 ?" W% _1 F1 S7 |
if(S.base==NULL)
+ v. g+ V& u3 `/ j2 K- ]
{
: z' H2 t) Y! a' q* L; d/ ~: o
printf("动态分配内存失败!");
1 T1 z1 q4 ?; h
return -1;
- w+ X' `: k7 s- C+ f
}
8 N8 R; R' h' N4 u, B
S.top=S.base;
* S* c0 b$ C& w4 a
S.size=STACK_SIZE;
7 c* q- g6 J; ?; a n
return 0;
* }- u; v8 k# O: t
}
6 a9 k( o, m! R, C
( u' m9 ~. u) R1 e
int DestroyStack(Stack &S)
4 Z2 j2 U7 ^8 P1 S$ P9 Y
{
: q4 w: P8 `4 a% F( q
free(S.base);
& ?9 H1 c; g4 z# d& n
return 0;
& H7 v1 M% w. h) d
}
1 l, a [7 ]5 ?% t- U
1 x! `$ K+ n3 P, p
int ClearStack(Stack &S)
' o6 C7 _$ @( ~* X- F
{
; h# W7 j! @) p) S3 P3 c5 A' z
S.top=S.base;
8 [: Z$ t# d+ `3 i7 W' v
return 0;
- K8 Y \& L! L* a( O# A1 ^) L
}
* o% v* j. O% @& l, a
; X9 r+ B, s( J3 @- V5 z$ ?
int GetTop(Stack S,SNode &e)
$ d4 P& T7 ~0 m, v- H) {/ A
{
" ]0 D8 |9 t% G- J
if(S.top==S.base)
& b- s9 \3 b. [' a k) ]- x
{
- C4 ]# k+ Q% C0 l+ p
printf("栈以为空!");
1 a" v3 ~, } x5 X
return -1;
. Y& g. k$ J0 A
}
0 v! K5 v1 M, Y4 c( M! ]+ A
e=*(S.top-1);
$ l& O2 {0 k% O( P5 I+ H
return 0;
' i% R/ [7 N, S6 ^/ ?
}
+ N' L4 Y2 ^4 k& A' r
& n0 J( R# S2 E
int Push(Stack &S,SNode e)
$ k9 y# C1 O% {9 C ~
{
5 ?# n0 L6 }, y6 T- @! _ a
if(S.top-S.base>=S.size)
8 ? \6 t9 D- a% R
{
. F" }- q9 H$ d3 _9 y; k# @9 ^+ w
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
% r( Q7 t; P; F+ p
if(S.base==NULL)
. ?; x) }! c# O0 K. J3 P
{
* u' X' ^# \" F
printf("动态分配内存失败!");
% @3 E/ S/ O# [9 M
return -1;
3 A: @! X8 ^: }9 B& k
}
( J$ a# R0 B; w, d, Y# K+ o0 W
S.top=S.base+S.size;
+ m6 V5 n* @! r3 k+ [" z
S.size+=APPEND_SIZE;
C4 z; n5 Y2 c0 j9 v0 J
}
+ l( g/ H# |& x1 I2 H
*S.top=e;
5 z8 b& r/ E5 ]3 s7 i0 e4 Y
S.top++;
" N3 J( ~1 w2 U Z: _+ r
return 0;
6 R. b$ J9 h3 l" s% L: F
}
+ ~( U2 u! o/ k+ u$ S" H7 y
U, w" Y# d' |( \6 `+ E7 H" _
int Pop(Stack &S,SNode &e)
. w7 C1 ^/ N. C* z, G; v
{
8 T8 Y0 b6 [% w
if(S.top==S.base)
3 _9 R4 m6 E' P. I. g! v
{
1 a' v3 L" B! ]" w" ] a* k
printf("栈为空!");
! P: g# l+ P! U* |- @* C
return -1;
2 M! r) `1 b# \3 A* b
}
+ v# X5 ~. Y& w' A( T" J
e=*(S.top-1);
$ s' b! g+ r# {3 G
S.top--;
. I; M9 S8 u9 Q0 ~7 ~
return 0;
n! M( W5 m) I' X0 e
}
6 B( c+ i w4 g& u1 }
! v* z s3 W' L5 @
char get_precede(char s,char c)
' c7 \- O- N$ Y$ m9 M' z$ f
{
4 @/ m8 S) W; U4 ~
switch(s)
6 f; ~' R, |: E: i1 J+ L6 ?
{
5 @4 y* G2 Q9 o$ s4 Y
case '+':
- b0 D" Q' u- r# U$ _$ p
case '-':
/ |6 H* }: w$ f
if(c=='+'||c=='-')
q6 ~% e% l# N h" K) U7 E
return '>';
, O) ]) E1 Q9 n0 Z( v+ t# F
else if(c=='*'||c=='/')
1 A5 C7 Z& e, Z4 Z* e+ b
return '<';
, r) O% G2 e6 h1 A" Z
else if(c=='(')
5 N0 R, Z6 R5 U6 h2 V6 O7 L; q
return '<';
2 e6 ?9 @" f1 ?1 P; ~$ R2 O" }
else if(c==')')
3 C. y+ W/ s$ M0 I
return '>';
z5 `9 n7 i. F5 u* ^/ K
else
/ k: m. r! f& w$ `2 s
return '>';
. ` C4 }1 B7 z! }$ L! b
case '*':
8 L# i( b$ b- A- f/ ~7 h
case '/':
6 V, f- o& B" N* Z: l8 Y! j8 H
if(c=='+'||c=='-')
8 T3 |- a. H4 A' ]! T2 G% \
return '>';
+ I8 s( e) {8 O% ?
else if(c=='*'||c=='/')
3 S% `! e; d: d2 j
return '>';
( L: ~# u7 K2 [* D# t
else if(c=='(')
7 c1 D0 N' w+ B; i" W
return '<';
2 u4 }& P0 i4 ^+ j, L o- \
else if(c==')')
# N% M+ q8 [& b* b2 G" ^+ k
return '>';
! ]0 i+ v& ^! H; h6 q3 m$ X* G* j
else
/ }5 O8 x0 d) O
return '>';
: W2 N0 Q; R0 }+ t
case '(':
* N( r$ Q+ N2 J9 F& {' U) v
if(c=='+'||c=='-')
) s4 U* [0 ]6 k. o u/ m7 ?6 [8 d
return '<';
/ J( [( P8 m$ A) d" r- l
else if(c=='*'||c=='/')
; n# @" U' ?/ F1 }: u' [
return '<';
- Z1 s6 o6 s' q+ ?! E& E
else if(c=='(')
. H; M. C2 h) Q) m4 q( U$ ^, F
return '<';
. f# a! J( b4 t$ a' s+ u
else if(c==')')
( g: c4 ?0 K' h& Y3 H& l) s
return '=';
5 C$ u% G* _: |
else
9 s* E- T4 L1 `! F' x9 n1 {
return 'E';
7 z& d$ b- ^* `- s6 w( e
case ')':
# {+ m, j. x. x1 N, U9 h3 A
if(c=='+'||c=='-')
% W' g( p; X' T' p& u2 R) c, W. L! _
return '>';
9 |# m- T: x+ {
else if(c=='*'||c=='/')
) h$ U- F) ?( S' k: _$ E
return '>';
6 \2 h* U7 a3 R, K
else if(c=='(')
5 x) p4 \/ A& g5 a4 o
return 'E';
0 U. c4 U+ w6 P
else if(c==')')
! R$ \4 Q" v- B! `0 l
return '>';
: Z* R4 }/ Q1 C; j
else
+ }( S* ~8 T* J, P7 D
return '>';
/ @6 O9 l* J2 l" R3 o" ?
case '#':
+ n6 F, A) y+ ?
if(c=='+'||c=='-')
: x8 R" A9 v- E
return '<';
P E! O0 B. W4 X
else if(c=='*'||c=='/')
6 A1 C. p |. f. ^ [9 @1 x
return '<';
5 p3 D! C8 g- f5 ?" J* ]
else if(c=='(')
) \1 F3 e( z2 p n3 K2 P& t
return '<';
) r1 T8 ]5 \) I& X' C( M. f
else if(c==')')
# t' ?0 Q. N! d* n9 i( Y
return 'E';
/ ]( M; o0 j6 n
else
/ p. Z+ w: F+ V8 }8 ^% y `
return '=';
# q, o. t) K5 p g, b0 L
default:
}0 g: o2 b: {+ B
break;
0 J. q( p. Q# ~) o7 P
}
) e1 k" {: e. E- m! n) M
return 0;
9 S$ f. C. c1 f' N! `/ |1 z# r, Z
}
) j7 x y9 d4 E" V
7 d$ F. z3 D3 k: s
int isOpr(char c)
% C. J) c* A0 r0 y: H. n. d. d+ K6 W
{
+ H1 |/ V6 @7 [
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
# W& P( r0 K+ S; e. x, }( L
return 0;
. j/ _# c! r0 j! e s
else
2 h8 c+ j0 n% v2 S e% \' M" P/ I
return 1;
+ i. s W3 [% x7 ] F3 F
}
% h9 \1 B% ?& y8 h2 t- O- B
}) W5 J7 h$ m. X2 v/ B" w
float operate(float x, char opr, float y)
1 N, V) S: }1 |' A4 m5 e' e% q; [
{
) n, G5 V$ X% a' F
float result;
# H6 D) J/ H$ x3 G: M% {% Q; Z
switch (opr)
1 \. B) p, x" e0 Y X6 V
{
# J# ~) }, I0 _3 a, O% ?; ?9 j4 Z' G
case '+':
) |8 \% b. {$ h; E; U; |
result = x + y;
6 E: G. M0 H! A: h$ S6 c) O1 p! m
break;
. f! I% e$ L- m
case '-':
- W7 _. W2 x2 r8 h, ^% h" a! _
result = x - y;
$ h' {8 ~* h) n
break;
7 e- N1 j9 [/ T+ s' y$ N) F
case '*':
3 b+ ?: ~9 E! i% ?% ]; _6 c2 n
result = x * y;
$ h4 D) v4 X8 f" ~
break;
- q& t! m P; S) h1 |
case '/':
" [+ D) V; q* ^4 s6 n; W
if (y == 0)
9 d8 c/ d- x8 U: l3 W% x; a4 Q
{
# B9 S. f9 V T; f2 C/ { R
printf("Divided by zero!\n");
) A+ C# C, h( X# w# z& T
return 0;
8 x! g- d7 e/ c. }/ V* o. T8 X
}
8 V0 W1 x4 K8 H
else
$ ^3 H; m3 q# C ~+ J8 a/ t# P
{
) W, k3 p8 u, ]+ M+ U6 d- s
result = x / y;
* \$ B! B6 `% N# m
break;
1 Z; o! C2 I# j8 k$ w
}
/ }+ @4 }2 {, \4 B ~2 x; E' T8 K
default:
/ v N7 s: g5 I
printf("Bad Input.\n");
6 B- P2 L' w. I' k0 Y
return 0;
* k) v! v( {) i$ I1 x
}
% i4 m! g% N- [/ ~/ T
return result;
2 y4 R0 v1 N3 C' t5 a. f6 R
}
$ t6 n3 K, `3 d1 A
Q( G* o+ \2 j' L
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
5 [% U6 [ c7 i4 D& Q, Y
{
# J, Y' o6 A. |
Stack optr,opnd;
& ~) p5 [# b. H% ]& C; D+ H
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
1 l& x$ f1 p; [6 S
char c;
1 o6 T1 H! @6 p: M
char buf[16];
5 w: v8 s1 n7 n: q$ L# N' y
int i=0;
2 l1 \! F, V; r3 M' P) \7 o
/ l* m. Z. l0 e& ^( u. |
InitStack(optr); /*用于寄存运算符*/
! d5 N( r+ B6 s+ B3 F; z
InitStack(opnd); /*用于寄存操作数和计算结果*/
! ?9 e2 ]2 _. k" z
memset(buf,0,sizeof(buf));
1 M1 o" Q: K* P) t
5 }& \1 e# w: r
printf("Enter your expression:");
, B; X" D% T9 I" [4 a$ m
) v0 F8 U" Q. q w4 L
opr_in.ch='#';
2 v u7 L: T: Z9 w5 t, I% ~
Push(optr,opr_in); /*'#'入栈*/
/ p# `1 C% g9 V& C8 f
GetTop(optr,opr_top);
- X+ D4 q$ {1 `4 L" F. t/ u7 ~
c=getchar();
" d' e2 W5 i& W
while(c!='='||opr_top.ch!='#')
5 T5 A* K1 [( f7 r
{
3 g" Q, k: Y3 D
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
! I5 B" p8 o8 T
{
0 l+ T( Q2 Z9 R: o. x+ e* @
buf
=c;
* U4 } P; R I% Y7 L, X
i++;
2 h4 ?$ W6 {& K1 f4 d
c=getchar();
, |* p0 |( @" \
}
& U+ s& W! @ J3 u8 X
else /*是运算符*/
) i, ]% R4 T4 B: D; b
{
" f5 I9 o5 @; K( p0 e8 \
buf
='\0';
& F7 Q/ E3 `* ?' Y4 h4 _' e. e% X
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
: w+ q4 ?4 h* `$ R' Q) A5 q
{
8 N5 b& L6 W1 W
opn_in.data=(float)atof(buf);
4 _5 W v0 G8 X5 ]% C
Push(opnd,opn_in);
9 s% d1 O6 k7 C, R
printf("opnd入栈:[%f]\n",opn_in.data);
( ^' f F; C# Q; Z: I3 f7 `
i=0;
/ s: S2 |- E& `+ N2 i9 V* C7 L ^
memset(buf,0,sizeof(buf));
4 q' b4 z6 K+ e% r O
}
" |; Y* M& i5 C ]! u6 a
opr_in.ch=c;
8 ?: B8 W' b( Y4 P2 l
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
: `; c# w* c% b% b B$ n
{
4 t% X- [0 l* F7 E& w
case '<': /*优先级小于栈顶结点,则运算符入栈*/
& t+ Y7 u- D C4 D
Push(optr,opr_in);
: X% v' j: \2 G1 h3 H0 v
printf("optr入栈:[%c]\n",opr_in.ch);
& F I1 ?& V# P" b
c=getchar();
N) T# ^9 T* ?6 l
break;
/ u- d7 e3 r& O5 A& r; |
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
. v- f' F, N) z3 t7 b% n0 M
Pop(optr,e);
8 e! J" j* N, v7 e( S
printf("optr出栈:去掉括号\n");
- s: B# _: w; \2 G+ p
c=getchar();
7 m. _$ I6 [2 H8 L) \8 m6 Y. C
break;
V6 T$ D0 I8 ~7 Q3 v# k" X, G
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
5 e, h) v: r. L' X7 |
Pop(optr,opr_t);
" W, q+ e' ~ Y& y$ N; H
printf("optr出栈:[%c]\n",opr_t.ch);
6 \8 A. l6 n; t1 @; W- P
if(Pop(opnd,b)<0)
9 z* m+ m% W1 y9 V* u" r4 H- o
{
$ V6 m$ ~. Q0 n$ B0 b, r
printf("Bad Input!\n");
& `& @; S3 s9 }
fflush(stdin);
5 X7 p' u+ x# D! b) R9 ?5 X& A
return -1;
, @- X/ ~6 W9 H1 P
}
* R" j1 q, }9 J; B _
printf("opnd出栈:[%f]\n",b.data);
! e( d8 {" i6 W- ]+ p7 p
if(Pop(opnd,a)<0)
% @$ s5 b% c+ k
{
$ c. }1 U9 E( p2 L" F' |
printf("Bad Input!\n");
5 C# A, i e$ M. j
fflush(stdin);
/ E' `2 n" y! b( x q* R
return -1;
9 a; {& m/ ^6 P5 G+ Y4 Y
}
! U7 a8 V" E) h& _2 v
printf("opnd出栈:[%f]\n",a.data);
7 W" _7 P( v3 d! ]7 \/ S8 p
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
. ~; M/ b# z2 h, H4 f( }9 A
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
1 C" E8 @7 b; ~& M! M
printf("结果入栈:[%f]\n",opn_tmp.data);
- o$ Z$ ~6 S* E7 ?% i7 G
break;
0 h3 C; b2 x# y
}
/ e l9 t( h$ M
}
! D$ d! f$ a9 z; o" I0 `4 _
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
( W7 _* K5 |7 i ]- \6 \- l+ c. s" \
}
6 v( a$ w9 B) a& T2 G8 s1 l
GetTop(opnd,opn_tmp);
( Z+ Q1 z) n w
DestroyStack(optr);
, S5 k7 ~; H9 s# \1 ?. v* l; z
DestroyStack(opnd);
/ q6 `8 ~( B# |/ F% c" v9 n
return opn_tmp.data;
! |1 q) ?+ r2 x, q
}
2 b) s% S, e/ p- s8 S M7 b1 m* O
' K& m s' V& b2 F
char *killzero(char *res,float result)
e! A5 P4 b5 p, I. R2 i
{
: n d/ C! F# w- u" z
int i;
: r7 T8 V# W2 j7 f
% {% K" R6 u4 d/ k/ t+ J& }& Q, Z
sprintf(res,"%f",result);
- a ]7 h6 _* u) F* j8 m* A) u
i=(int)strlen(res)-1;
3 ]4 f& I1 C0 _; i2 H: M4 H
while(i&&res
=='0')
+ ^) ~4 ?, ^: L' J
{
7 E: D5 d7 ~0 `5 j
res
='\0';
* c8 b) C: `; d2 |4 o
i--;
; {- m( V+ G7 }' [+ ]: m# d
}
4 N: |( Y$ x0 {' x: q
if(res
=='.')
3 _7 ]# }* t! G6 u
res
='\0';
y4 C1 k, Q/ `
return res;
# L, a0 x4 h* `/ y# J, {
}
+ v; j. W; d& N/ \6 }/ S' D
7 k c2 ?- E6 N6 b4 {
int main()
! u9 {1 K' W# g' W7 k9 b8 A9 a
{
7 S5 L: @; t9 Z+ C' e$ h6 k
char ch;
; _* B6 `& u" w- ?; u: Q# e
char res[64];
$ P5 G" T2 i' D. N8 t) t: Z6 U) s
float result;
/ ]/ N6 j7 J; G! v2 e" [0 _" C
while(1)
0 V: v" |" o8 j+ Q, o% z& K
{
8 q, z- O0 {2 W4 \" g$ a$ d
result=compute();
1 _6 Y& E \; ]) f: F* L, k+ e0 H7 O
printf("\nThe result is:%s\n",killzero(res,result));
8 L' B( X8 _) V' j$ c* _+ v
printf("Do you want to continue(y/n)?:") ;
* e6 q* l1 A( y$ M# v0 o, V) u1 ~! l
ch=getch();
V, D4 D, z; k) w5 B. c- I
putchar(ch);
/ x2 b7 P$ C2 L' |3 m* [
if(ch=='n'||ch=='N')
; \0 I5 [6 Z' s+ b( W
break;
7 z1 B; ^* j: [
else
8 o4 _( x; g6 D9 A5 U0 P! v, M
system("cls");
5 W$ n8 ~# s) K/ U1 w; }0 u
}
' n" ~* B. U! H4 {" O
return 0;
% |4 z9 Q- k9 p* V2 K- g9 _, B
}
2 ^9 v( Y$ G* n' M* O9 P* I0 `
/ B5 y# R8 O4 h# J
[
本帖最后由 zw2004 于 2008-1-21 17:21 编辑
]
欢迎光临 捌玖网络工作室 (http://89w.org/)
Powered by Discuz! 7.2