标题:
C语言表达式计算器
[打印本页]
作者:
zw2004
时间:
2008-1-21 17:17
标题:
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
/ ~$ J4 L1 G5 ^' x& m: `
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
/ @$ |+ h: D! @2 K/ d, U
/**************表达式计算器************/
) _: j R/ p/ b4 v" K$ k" n4 L
#include <stdio.h>
: ]0 b1 h2 |. X# ~8 h+ L- r
#include <stdlib.h>
2 u% l. V+ {" K' p/ n7 |
#include <string.h>
% c, Y, R2 Y. Q& C' Y ]5 R5 }
#include <conio.h>
4 g1 b( s# t! K
#include <malloc.h>
; y0 k- b; `- o
0 |" J# P ]8 p$ R0 d
#define STACK_SIZE 100
+ ?1 s- M/ j' ]# k$ v; T
#define APPEND_SIZE 10
. K+ _5 s$ x" N" o) q# K6 f1 M
& @! p! _7 n9 b) C6 ^& i' {
struct SNode{
% G& G o* }7 r& W; M! X2 s( x
float data; /*存放操作数或者计算结果*/
' k; L9 l b7 p$ y$ C
char ch; /*存放运算符*/
; y/ B3 X# q3 \( S0 W
};
! U) o9 s* [7 ?6 \# U% s" c
8 w* z; `+ P* r) z. q* M9 J
struct Stack{
" V* l# z! P7 ~. C
SNode *top;
6 v9 K$ i( `9 o- |
SNode *base;
# V" N' F8 d9 S' p
int size;
! y& ]: z8 Q. T. x5 V" s
};
% R( |/ D4 F9 P+ x
1 k$ N5 L1 G3 u5 y" R; [+ J
/*栈操作函数*/
7 b0 @4 ^; Z6 E
int InitStack(Stack &S); /*创建栈*/
- ^/ D7 A8 ~: V, m
int DestroyStack(Stack &S); /*销毁栈*/
( ^1 M- r7 D n
int ClearStack(Stack &S); /*清空栈*/
% \' C3 R, a3 Q4 B1 m8 c8 J9 p
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
7 Z L) _9 A; [8 X
int Push(Stack &S,SNode e); /*将结点e压入栈*/
' r* B5 }/ [ o K6 h' M' L5 F
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
& S. V2 k2 k5 d6 n* p( [7 o. N
. j- O- {" z" d& K6 B2 g- i
/*表达式计算器相关函数*/
6 E* S. P( l3 r: J& G, P
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
' u- P1 S1 K) u& K$ t
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
( Q+ j( k; N# m/ X. W9 F$ O: Y
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
: s$ e8 d5 r9 T# f4 `
float compute(); /*表达式结算器主函数*/
2 @1 F G7 C7 h5 e) E) _8 U0 t
char *killzero(float result); /*去掉结果后面的0*/
) s- ^& P2 n$ @$ l
" F4 ^- I, B0 B+ y8 n4 i
int InitStack(Stack &S)
* K! y6 t2 p9 h: |% j8 ]
{
3 `" e! h! v% U2 x
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
8 V! s0 ?+ q+ G- l. k6 X+ C
if(S.base==NULL)
0 B+ k; Z- n) e( C& N% i
{
: P) f" E" \, D: t2 ]( F, e( ?
printf("动态分配内存失败!");
$ G* K' x4 t k( u7 z0 h0 Q1 k) S; p. ^
return -1;
1 u8 H+ f' y/ H9 E
}
+ Q1 E- s( e4 ^; f! y
S.top=S.base;
$ L5 \: F8 X9 L6 `9 ^
S.size=STACK_SIZE;
5 V6 Y) f7 l2 E& l1 `- R7 y4 ?
return 0;
3 e: @% w8 E% O2 Y3 D0 N* Q% D* O
}
8 e0 B4 {+ k+ Q
$ |+ |- U2 F: ~1 X( d+ l% O5 r
int DestroyStack(Stack &S)
0 t. R) o4 v3 ]
{
% s% h2 h/ A7 B( ?& J: X5 [& G
free(S.base);
7 N" ?3 x* ^+ g5 e0 l$ s$ Z# } Q* R
return 0;
: L3 k3 k: ^/ T! @
}
) p) O2 b/ `& }7 F; x" I, J9 q
- F: w2 {4 s- W7 {+ G
int ClearStack(Stack &S)
2 D0 X+ z5 z: z, [% W s
{
- n) b4 w! M7 M6 ~2 R& Y
S.top=S.base;
+ w) u: s' R5 e" e) d2 F; ~; I
return 0;
3 H; k9 P1 M1 K) u' Q
}
9 Y) z4 b& v+ h7 C3 C0 Y
, N& J' t; Y2 S0 o- c" A( K
int GetTop(Stack S,SNode &e)
J& r. x) p& m [; p0 c0 e; ^
{
. e$ A! a, Z4 Y
if(S.top==S.base)
# I5 v7 f/ L" B- j
{
' r, d. `3 l/ `& m* D
printf("栈以为空!");
( ?* D; \9 U- r2 E, M4 w6 ^
return -1;
8 {3 W$ o" q) \- b% b5 ?# w
}
7 m6 ^% t$ p4 U- Q* u
e=*(S.top-1);
! y: k- ?7 L9 ?! Z8 W: x% L
return 0;
) c0 v" K" _5 {4 T A) |
}
k* \6 n) ^5 p' V0 i
- a4 c6 y, g0 d6 Y
int Push(Stack &S,SNode e)
( Y5 W! [ I5 }7 n4 Y
{
4 l1 ?& M! ~- V! s! V) S& D
if(S.top-S.base>=S.size)
+ y' [2 e3 X9 _% G
{
9 v8 z- [7 p g6 |
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
/ G, M" u" z, X2 j
if(S.base==NULL)
3 S1 x! @" X" s
{
7 j7 [7 {2 z2 g
printf("动态分配内存失败!");
+ v. n: k8 S) g+ }# M3 }' _* Q
return -1;
5 @$ ~ B4 \; A. x% n5 _# t; M. T
}
# F. @0 i! K; k6 i+ _2 U* ?% U
S.top=S.base+S.size;
$ m+ z% p, ]) @+ [/ Y
S.size+=APPEND_SIZE;
% Y" {; }. l$ W! k
}
* b1 z: l* v% T( c% \
*S.top=e;
1 p4 G% O8 f7 y; M F
S.top++;
; ^2 o7 t6 B" y% |3 J: a+ b: h
return 0;
) Q3 W% o6 L! m. x1 o( w
}
! f1 S4 y+ [/ ~2 ?7 U: y
. m c; L9 N" ~0 c
int Pop(Stack &S,SNode &e)
) K) y- v( g+ o. g9 t+ B
{
" x% `1 G' z- l
if(S.top==S.base)
+ M3 R/ R" O% K+ x1 a
{
, J; m- {- G! a( L, }" Z
printf("栈为空!");
& @# V8 ?, i9 W% v6 T
return -1;
8 O0 B% g @3 O3 t1 W1 H0 q
}
* p! P1 ~ q* s. `/ I! T k
e=*(S.top-1);
4 [$ `2 m% t. a4 l+ }8 X$ M& Z
S.top--;
7 i/ u3 W: _3 O* A
return 0;
7 }/ c% K1 W4 i! j" l
}
9 e8 ^( \8 {4 S, _5 H% b4 r
' H4 u8 o1 p- l5 a% N
char get_precede(char s,char c)
3 I, q/ |" C4 L/ p2 K* Q; A
{
* [0 e) u3 y9 p# A% g
switch(s)
% c+ h2 R3 Y% ~: t4 o
{
6 O R% s% S1 ]* y4 }
case '+':
; E) M# d8 P8 D @) D# q
case '-':
0 ^) v0 z& _6 C+ |/ g( b8 @8 m
if(c=='+'||c=='-')
9 o. q/ Z& t; Z: k0 C3 I/ ^
return '>';
5 t+ l/ G7 ]. L2 U& {- ^6 B
else if(c=='*'||c=='/')
1 H' a1 A8 y: @8 Q6 ^! k) \! A& O
return '<';
z1 T; T% G/ C4 y7 r
else if(c=='(')
+ s& S- m: r2 {' w, F2 S4 Y
return '<';
, _# F6 n) l& a
else if(c==')')
' R6 [/ u- S$ A' j! u) C2 G
return '>';
. b% \! r9 o6 z1 S8 r4 |6 g- b
else
" n" N7 F+ ~- ], ~2 q2 p
return '>';
K3 _( n% s% g) D
case '*':
( N3 g% [" V# P
case '/':
; L" g0 F6 P# r5 ?' b
if(c=='+'||c=='-')
0 F$ U8 O) h( h+ t8 W6 O
return '>';
( {3 ^& k: A% R6 c- d
else if(c=='*'||c=='/')
- K% T3 h9 z, {3 S5 U3 O( x8 x: W
return '>';
! f. j2 t. ~# w. c& \) D
else if(c=='(')
) M; O% k; {" c3 s4 a- ?
return '<';
) d# q2 u3 i/ A4 k" [$ c
else if(c==')')
4 W, d% V9 j$ z8 H! f3 U+ p2 _' x2 E
return '>';
% N3 Z) d, E- @9 ?/ o
else
: |( d% Z3 a8 ?) x G0 u
return '>';
2 Y9 N4 U6 X/ M2 G
case '(':
; h/ O6 z/ s: S1 r) A
if(c=='+'||c=='-')
) b* Q5 @) o2 a# V t
return '<';
1 q" r+ M8 v7 _
else if(c=='*'||c=='/')
; O7 s& N- H; z
return '<';
; v8 k# q1 G, ]) L
else if(c=='(')
7 @5 j2 y. J( {& V! a
return '<';
1 z( i0 ]4 m3 D- Z4 Y j
else if(c==')')
' Z! e* X2 v' a) }. R
return '=';
* \3 z. C8 D/ Y/ V, ?
else
2 }+ u' J. W3 g' j8 }
return 'E';
& o8 L" b7 q# F+ s; Z
case ')':
6 c1 y# [; k8 F* a5 u* z. v
if(c=='+'||c=='-')
+ |8 ^. d0 R/ t+ I% O c9 y2 A2 H
return '>';
$ \" g) Z# r/ {; B4 y% \# A8 t
else if(c=='*'||c=='/')
4 M5 K9 _+ y3 W& F; {8 X% Y
return '>';
( K3 T' I8 i, @; Z, }% i
else if(c=='(')
% `! k, l8 p9 O5 Z& R
return 'E';
4 N5 L* H r! Z$ ]2 S% W
else if(c==')')
3 ~( C$ Q% X; R1 p( Y
return '>';
7 B+ D4 c0 n& K& X8 @
else
) u' F+ e- `) c; V2 c1 { J
return '>';
" B$ [" U# B- y9 G R- z$ l/ q
case '#':
. ?8 ?+ |' W' G0 p
if(c=='+'||c=='-')
/ ^) s3 o; a- @% T) F7 }
return '<';
! o4 m! x* _3 \% N
else if(c=='*'||c=='/')
3 f3 K4 `- V# ? w
return '<';
- o! J* m( _ a2 O1 x* s1 H
else if(c=='(')
' |) K! Q, b" y5 U) y; p
return '<';
) ~- G$ V* I# H# c' N( X! y1 Z' {
else if(c==')')
6 b; A7 P. l4 e( n6 K7 g9 L
return 'E';
$ {* C, W% y4 i, T3 t% ~
else
- b7 m* o) ]/ j( _) N1 o- k# _
return '=';
2 x" X# I1 L- R4 R9 r
default:
' \9 Y( @$ o; S* G
break;
1 u8 g9 Z2 o$ r" D6 V; X0 @: f. H; B
}
8 `+ m' }, n/ S T+ u( ] O6 P
return 0;
8 ^0 B. d. D+ W+ v
}
$ f/ r# T `) [* B
4 M( {& J, ?. e# h) }% J
int isOpr(char c)
+ e2 k" J- v4 R: ]2 Q, b6 t: D6 ~
{
5 v- K) F# O8 c2 D/ i" T" _- Q* C
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
& ?! M/ |* A2 o5 W# X2 K
return 0;
0 `# l/ E+ _1 V9 l. J" y
else
- `( O& N5 ^ K( E
return 1;
$ E8 n0 I0 L: I2 L1 O( N) \. A3 m
}
4 x# o7 h5 ]' |" [$ M- b% M) }0 c
0 Q+ n! S5 s) X/ r: O/ h
float operate(float x, char opr, float y)
0 j) T& E: X+ j t+ c. m, u+ O
{
( x. r6 |) ~ I: O, n
float result;
) x0 K" f" E3 D( b
switch (opr)
' s8 O7 ]. w( I! D' S
{
( L0 l$ X& w7 t# X8 V9 B, Y) U
case '+':
/ Z7 @' L) x8 |1 x" O
result = x + y;
$ o e9 b! G7 U, f `( Y
break;
& @5 i! H$ ~) w# {( Y: d& a$ h$ c) \% ]
case '-':
5 I' ~; m1 o- J/ f' Z
result = x - y;
0 L* v- \+ l8 W, Q1 M4 _" L
break;
2 F( c3 j# P+ u8 r% m. j+ H5 G
case '*':
7 Z" b$ {# f" y
result = x * y;
# N3 j# h4 Q4 O
break;
3 w6 K8 y7 m8 l" j' k
case '/':
1 f+ v1 _, O4 g( h! D- [' H
if (y == 0)
7 z6 d; m+ o$ G
{
" `$ R5 H+ u2 u; Y
printf("Divided by zero!\n");
1 u+ ]( `" {4 L' ?: Q" W) C
return 0;
5 x, h4 C5 a+ l- J
}
) E' O5 Z! u( f0 D: _$ {9 m
else
* B% H1 Y& k) w; k6 ?* R" ?0 ]
{
* J- Q. n6 k, b
result = x / y;
0 @3 m% }! e( p0 j* O
break;
7 g" n F5 v5 G0 b8 H- Z2 T
}
* I% I& K4 D& J3 ?
default:
2 O: a* q0 P* u' F
printf("Bad Input.\n");
O( P1 f2 b! e; L4 p3 P. B3 f
return 0;
8 f( V2 d8 S) ]' t' s$ m
}
2 V/ ~7 H9 f% m" I6 Q4 B
return result;
8 e0 ]; y6 \) P' A- B; g
}
$ m: P% y7 X0 G0 {" ]
) D4 y5 c" R/ _
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
7 |3 c0 |3 Y- O5 b' |. Q
{
8 E" U$ u6 W( J9 E8 M
Stack optr,opnd;
3 s% @9 r6 w' c+ Q: _7 I! J
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
O' g( ~( z; I, d' E7 `
char c;
7 U" {2 G3 T- D5 `" s# |- |0 C
char buf[16];
7 G% }+ u6 w& W& A3 \
int i=0;
8 z- T2 Y, W7 E b; `; A
& G3 O8 m9 r L8 q( j5 f( Q) `
InitStack(optr); /*用于寄存运算符*/
9 P* R" A) }) }6 V7 g; u# {% T3 }
InitStack(opnd); /*用于寄存操作数和计算结果*/
* {! @: Q8 E2 ^$ Y8 o' H
memset(buf,0,sizeof(buf));
/ K( E5 O4 I, L4 o$ I p
" _; G) l0 M9 X' `6 k
printf("Enter your expression:");
8 ?9 q5 C) v8 z9 u& C* p
3 p) B/ K8 b5 h5 z* U
opr_in.ch='#';
, u7 a r/ C1 g. ~
Push(optr,opr_in); /*'#'入栈*/
+ P/ C5 G% l ^
GetTop(optr,opr_top);
" L" _& J2 {" e: H/ w' [
c=getchar();
- L. r2 x9 {1 c* x C3 o/ m8 B
while(c!='='||opr_top.ch!='#')
0 f" X5 k; _1 E% y; A0 h
{
w# k; w! u2 Q" M# Q/ y' _; u
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
6 D* Y6 a# Z. C7 D
{
7 ^; `" j" Q/ g4 ^) X( v
buf
=c;
- O# k* h5 V* X; o% ~$ ]2 U
i++;
7 C9 E) F' T% y" @' }( [' P
c=getchar();
' L, P) _1 }2 d; @/ q
}
+ U) r5 w# x \3 P+ p/ U- Q
else /*是运算符*/
. v w2 n7 i9 t7 j H
{
6 @+ Q, t- b* z, {
buf
='\0';
0 X" e; J, I+ `- m1 o3 _, A+ Z
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
9 a$ x: E+ y, D) g* n; Y& I2 A6 M
{
' x3 r9 P- E7 A- w
opn_in.data=(float)atof(buf);
1 V7 r) b, p# p! B+ K3 Q$ P
Push(opnd,opn_in);
$ W* R3 Q9 e- @0 ?1 \
printf("opnd入栈:[%f]\n",opn_in.data);
8 s3 q$ D2 |) X+ w# z) I
i=0;
" L6 X* @( \+ d4 u
memset(buf,0,sizeof(buf));
) v; y" B' M8 @1 T6 k& A" o
}
7 L$ U" g7 e! x+ I. T+ f6 X
opr_in.ch=c;
& y% y. [5 E4 d- M: W5 F+ ~/ |& B
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
5 J; l, P; m/ @6 e1 j
{
# B, ?9 T. t ]! ?* t0 F; Z
case '<': /*优先级小于栈顶结点,则运算符入栈*/
" l# m) `9 ~/ w6 r* ]
Push(optr,opr_in);
. n& |& \6 n% u% j% }0 M; D
printf("optr入栈:[%c]\n",opr_in.ch);
8 H3 \! r# D" c7 c9 h
c=getchar();
, u( s" s4 q+ C- n6 n
break;
2 z, |+ S$ _. _% E0 w' k$ `9 N J
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
" V' [0 s3 S4 j
Pop(optr,e);
% U7 H. ~" P. [ W
printf("optr出栈:去掉括号\n");
, k" y1 d9 L/ `: V: \: i/ U' l# {
c=getchar();
9 I4 t% l1 g( @3 \
break;
8 q) H) n/ z+ ^) u( _# K% Z
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
/ X, j. e' Z5 M. H0 s$ h# A/ \: }
Pop(optr,opr_t);
( e. S+ Y3 E8 P( {3 S
printf("optr出栈:[%c]\n",opr_t.ch);
8 p2 z% s: B. d$ R9 r$ F% [
if(Pop(opnd,b)<0)
8 d9 v3 P& ~' I( [5 J( c% a! W
{
& J0 p) ?/ [) W0 ~0 g
printf("Bad Input!\n");
$ P+ f+ \3 U: ]- x4 {7 B
fflush(stdin);
- @1 z2 @$ y1 e% k8 h k; l
return -1;
! _, F$ u6 G& T9 P/ p/ b; y+ ^
}
5 P9 z* z" p0 D' @; S( i+ P' e
printf("opnd出栈:[%f]\n",b.data);
( k8 K4 U0 U8 V2 M: S/ q
if(Pop(opnd,a)<0)
4 P+ Q6 }* @# E: `/ B
{
) k- `% s+ i9 I6 X
printf("Bad Input!\n");
A& D8 K* t6 O- `3 _# I! a' g
fflush(stdin);
- D; e0 \# F( m* s0 }
return -1;
/ {. V( _- d6 b) v* E( K
}
, B5 v& Y" w/ }
printf("opnd出栈:[%f]\n",a.data);
% Q3 x6 L5 l9 t2 ~, w7 N
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
$ Z" U1 c5 i, H: |/ S
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
. y+ D; ^+ o( j4 l8 M& l
printf("结果入栈:[%f]\n",opn_tmp.data);
4 g7 f2 i8 b. S; H# X
break;
0 }8 Z0 d2 }+ F
}
( ` B& }: j0 x6 i y" g' Z
}
6 B6 w; U. j" @% |
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
$ L) w- ~& R! ]8 j1 c
}
8 y; k3 u4 R: }) D1 x
GetTop(opnd,opn_tmp);
. m P& f7 G2 e3 T. i7 o. |4 k4 S/ b( a
DestroyStack(optr);
; C& `$ s& w% y/ @- c
DestroyStack(opnd);
7 ?& f2 {/ J+ `. h8 m8 T; {
return opn_tmp.data;
+ `$ y$ Z& V. G' j
}
6 N# B" y D+ K& S( t# a: Z$ d
8 D7 c* V; V5 H) L
char *killzero(char *res,float result)
, M e( \: Q7 P2 S
{
7 l3 A6 [0 U1 C+ J0 [ `" Z- _3 q
int i;
2 T( R' h! q) e4 n" b1 a
0 w$ i' y+ I6 y' O
sprintf(res,"%f",result);
- G9 n1 \6 z& h2 w. w
i=(int)strlen(res)-1;
" G9 \: Z. f: H" R$ U
while(i&&res
=='0')
& S) B# v3 |1 Y. P
{
6 K# K% w" |: o1 u) R; A( B
res
='\0';
' B5 F) j0 ]3 a$ z
i--;
7 _' ~! A# N. L* ^
}
/ J+ }$ j- c. J3 K# Z
if(res
=='.')
6 c. |0 [' ^/ T+ C& L
res
='\0';
: {7 A) A5 Q( E0 x9 F4 t2 g* ]: {
return res;
5 ?! I9 [$ p: s
}
- y" E" ?- \9 {( D* ]2 P
; o4 E0 C: j2 ~- i* a0 E
int main()
% g, @& M1 X; Z# q6 i: G
{
# s R' Q/ W5 D7 S" |$ [6 I: V
char ch;
! }7 Z9 s/ W7 d& U4 A# ~$ h
char res[64];
3 x3 @7 S+ D( u5 L$ L
float result;
: r; i0 ^6 L3 S( E& ^
while(1)
# R" a" T% F- s. q0 O/ w
{
2 c/ I9 \5 Q6 A, C( q$ F. G
result=compute();
9 w8 n6 W* k7 C, A) h
printf("\nThe result is:%s\n",killzero(res,result));
4 ?) w3 f5 S: e, G3 Z+ ~8 y M, [
printf("Do you want to continue(y/n)?:") ;
/ E9 A1 L& m) @# `- v
ch=getch();
, j% |( { T6 C% f; G. \8 `0 G
putchar(ch);
- R3 @1 ^$ C0 W
if(ch=='n'||ch=='N')
6 k) j3 |- b) W
break;
( j' y# `8 t, T$ c
else
# B, @& k! e' p1 }2 E
system("cls");
; i8 }2 l2 L+ \! \- i+ a# }5 I
}
) j& h. g7 c+ }# s! y
return 0;
* o d# w% T t y& p
}
1 s2 E$ V% ?' }* o- t
: Y5 |5 w H% ]- A+ o$ b: m
[
本帖最后由 zw2004 于 2008-1-21 17:21 编辑
]
欢迎光临 捌玖网络工作室 (http://www.89w.org/)
Powered by Discuz! 7.2