|
  
- UID
- 133
- 帖子
- 51
- 精华
- 1
- 积分
- 186
- 金币
- 55
- 威望
- 2
- 贡献
- 0

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.' e! f5 h( Y) l c& f0 {
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=2 l: _9 ^) v/ w, ]
/**************表达式计算器************/
4 p/ V' A+ [" A# ?3 S#include <stdio.h>
5 \, k" Q' A1 T#include <stdlib.h>* C4 ?) ?) Z$ j0 |& a
#include <string.h>
! X/ r2 {6 y& A#include <conio.h>
; ^, W9 h5 n3 O6 T$ |#include <malloc.h>
$ Y3 S5 q* R* m% N' _& H' x6 Q/ y$ L
#define STACK_SIZE 100& I+ L2 h$ y; X* B( x
#define APPEND_SIZE 10
, ~% N! o1 h# ]& Y, b+ p/ N
" ]! k! N- W4 g w" `3 c+ ]# f+ ystruct SNode{, S0 G# F* V: a5 ?: n1 r/ o8 K
float data; /*存放操作数或者计算结果*/
4 p: I" d6 G* W char ch; /*存放运算符*/ s( Y9 t/ J V1 n7 A* X
};& r7 F: E( n4 v
( x" W. ]2 k% z( Q3 A' G( [struct Stack{4 S! ^" m o! u$ Q5 a* t l
SNode *top;
+ h" e3 j3 c, T" [4 L0 m: S' Z SNode *base;% H7 V" y, u8 U9 @
int size;
4 t( O# \. h+ v" `- ]! l+ i};9 j8 U2 R# s% p1 C" t
3 L& }6 P/ x/ L. r3 T. ?; \/*栈操作函数*/# k2 ~6 G2 c. e+ T& z
int InitStack(Stack &S); /*创建栈*/4 E9 V5 l' R' r- q5 g0 ]
int DestroyStack(Stack &S); /*销毁栈*/
4 r; E% F+ d" o6 F0 A2 Xint ClearStack(Stack &S); /*清空栈*/ O% e' y \8 {1 X
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/' c3 F" v6 f1 S" K( _$ v4 x6 Y
int Push(Stack &S,SNode e); /*将结点e压入栈*/
0 U9 s- n$ d6 A! e) |, ^% I" T. _int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
( B# ?0 W: r" V# o2 F/ w
" _3 G( p2 W) _& U2 i7 z3 C/*表达式计算器相关函数*/
) b7 w3 ~& V# t) }7 m8 {) @/ Rchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
" e* ~4 N; s- ^int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/( L7 L9 }8 |$ o! c. R* x
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
% e0 o0 N/ K9 ?float compute(); /*表达式结算器主函数*/
6 I! e) B2 a" |8 ?8 _char *killzero(float result); /*去掉结果后面的0*/ ) o7 B, c3 i) K- c& U& x) s
! f+ E0 a% R' P- Yint InitStack(Stack &S)
0 [- y; P# Q3 S: ]- Y{3 k' P! m0 R$ K: b- D# H
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
% L% r, e8 w7 k if(S.base==NULL)
3 l+ y" i+ B/ x# N {! a1 K" D6 ]) X
printf("动态分配内存失败!");" Q3 W* R! Y3 I* s. l Q% A( s
return -1;
/ t% u0 A+ ^. \8 E& p }
( D# {" Z* f' w* {$ s# s6 ^$ q- H- | S.top=S.base;( a8 {$ P2 z0 b% p2 N: c
S.size=STACK_SIZE;
8 H& F1 ^) e; h$ ^$ ^5 E: p return 0;
. p. v) A/ }* M}
" t/ O' X* |" s2 S* Q/ E, t
3 S E9 h3 D; K7 H+ \7 r. Vint DestroyStack(Stack &S)8 ?) w! j% }( Z" P1 ?1 ], o. m
{# o" S* i- u" K6 o3 h6 l0 k
free(S.base);
3 E& H6 |7 Y& s$ G% H' K6 d- \ return 0;
& ^7 t- G6 v5 L2 A7 J5 z}
& g8 I6 g, `$ ?; H) Z8 |
, y$ Z- m, b4 g' R; ~; Nint ClearStack(Stack &S)
* v; v* |0 [0 r, B- j{- F. D. Y k+ E4 K* ^/ |; S/ d' a
S.top=S.base;
9 m* @1 _3 N- N ~" p. ]. b return 0;
! R0 l, n. Y( r3 }0 m- r5 z$ U}
, m G6 j7 v1 _9 T0 R
1 X* q) {! i7 n7 @2 oint GetTop(Stack S,SNode &e)7 [! [0 U' O* _3 b
{
5 N1 I" s5 _6 z2 ` if(S.top==S.base)
2 x' F' ~6 N( V( c. i {# B: J" _ X- \8 C1 r; F8 j
printf("栈以为空!");
7 T! Q0 i6 m/ Y- V" s return -1;7 M/ g- k6 z9 g5 n* q+ V! x
}
' H& p( u' E1 K# X; ]+ w3 P e=*(S.top-1); S; }! ~9 N2 U
return 0;
# Q7 l7 a4 _8 S" e}
# ]; s5 ?0 P4 X) O3 @. ?8 s# y
, m m" @; l s/ N3 d* Mint Push(Stack &S,SNode e)
* l* A3 t" Z6 W: b8 J0 v6 c. W{7 a5 V2 V! i5 ~$ r& Q4 _
if(S.top-S.base>=S.size)
6 q( x& V, j7 p6 G {- B6 N: D( E7 F/ O$ Y
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));: X& a* z. ]' O) A$ p. G1 b
if(S.base==NULL)$ Q4 M$ p- K8 Q
{
8 T. r6 \, a/ E! C4 B$ R% }& X printf("动态分配内存失败!");
7 Y" X( @2 Z! m+ }/ r4 n# y! ~ return -1;1 `; W! Z3 N5 o g0 ^ c
}
# w: \: H1 Y1 ]+ o* e9 v* ? S.top=S.base+S.size;# ^7 N* Z4 u9 P* ^* c( U, `
S.size+=APPEND_SIZE;5 j; O, `) ^* g, f! l# Z
}8 @) |9 e; A# A0 w
*S.top=e;
" C' g$ T( W% h S.top++;
/ j4 f+ a, J {8 c) v( u return 0;/ T) r, _( u' P3 L1 j- {' {
}
: f5 R' E- Q' g# R* w6 t! U- `. Y3 A$ r6 z0 E
int Pop(Stack &S,SNode &e); f7 |" f: Y) `+ g3 L- ]
{' |" O5 d2 N; r- z" z
if(S.top==S.base)
3 b/ v2 k+ Z* _- c( E {
/ L' b0 ^3 @! L% C6 [& s printf("栈为空!");
- a3 G& H! F2 Y* N" G7 S2 T return -1;
; H3 A2 J) v5 m: T+ R: e2 ? }& Q+ D0 k* D- ]- f6 w1 M- y$ [, c' w! j
e=*(S.top-1);; e& K2 R& _ L- Z% m( r
S.top--;
% k/ o* i8 ?4 p$ u$ c return 0;
# j; \- v$ C: N! Q, k1 r9 [}
; J3 E) _0 v8 b+ ?: }& v5 `, W1 @/ ^# D6 r% t2 V
char get_precede(char s,char c)% b+ h+ c' L! T# H
{
2 ^5 v6 n; |: N; ] K' R switch(s)- i/ z/ J& s- b! {$ w" t, e
{, _2 e5 P# V! Y0 { J- x
case '+': 2 O4 l% y5 [& Z% r2 m! s! T3 ^7 }
case '-':; a/ ]) R$ t7 k, X' ?
if(c=='+'||c=='-'). w3 n' s. {4 D/ B: L4 w
return '>';2 i _" U/ B) V9 J
else if(c=='*'||c=='/')0 o U w4 \7 h
return '<';8 s! N! { u G6 A3 n# |
else if(c=='(')
" `4 S3 {8 l* p return '<';' D, E* ?- L7 L- E6 b
else if(c==')')
+ p( ^/ T( c% r return '>';
9 t7 M. k- |* m- C2 x( v% b. N# e else 9 [! ^) N; {8 q
return '>';
- C# w; Y' E2 u+ j0 [4 u6 m case '*':
9 ~4 L) A& s( y case '/':
# F2 Q2 |/ k8 v! R) R if(c=='+'||c=='-'); W' S" _: U* `2 M9 ~, Z% Y( R: r
return '>';& Y0 l6 w9 g) U5 u
else if(c=='*'||c=='/')9 e& j9 f/ `! }0 F1 q9 l v
return '>';" B+ m' f/ F! h* c. [& T! ~
else if(c=='(')0 N$ Z: M# ]1 Z1 i8 R
return '<';9 O+ x, U/ I# {2 k6 s8 V0 ]
else if(c==')')
$ G! M7 S2 R, x9 N# c: X return '>';
5 n3 k/ j9 a1 Q else. K r( R7 ^( _. I# G
return '>';
! R- L& k+ }, H" H" k, } case '(':" F4 f; @$ x6 k, }& u
if(c=='+'||c=='-')
( a- h3 M1 i2 W' w9 K; G0 B+ q return '<';) C0 U; d6 Z$ H3 p$ K, `
else if(c=='*'||c=='/')
: p- b7 x( u& _! ~3 E) ?% y8 k2 T return '<';
, ?3 @5 d5 s; S* B! Q5 a# L2 T9 W) N else if(c=='(')
- [! t& Q @) | return '<';4 D" R# m7 e+ a# p Y. j2 y
else if(c==')')+ g( Z) j1 J3 s! B
return '=';
0 Y2 D/ {# a8 Q K% _6 o4 u2 h else% p- ?7 O; I0 D
return 'E';
( T' d* w8 m) \7 b+ T6 |. R case ')':
( ]$ w0 C& w) @: S" V2 Y- Z if(c=='+'||c=='-')" p0 i9 x, C& G9 Y8 _
return '>';
V9 B m' e- Q* R0 \, b' K else if(c=='*'||c=='/')
. H( j3 @* I; u- a6 f return '>';1 {- ~/ a# m8 q4 m3 A/ O
else if(c=='('); f6 p' Y" K9 }- z
return 'E';
5 D: [+ l9 p5 P+ J+ o* l9 y2 i else if(c==')')& ]7 S/ p4 T* n7 l6 H1 q
return '>';
7 S9 p" m/ ]8 C" F J0 `" [$ }0 I else
! t6 X1 A0 c' K0 z return '>';; r, z& s- {7 N; n
case '#':
6 L2 w6 ^; I/ l: P J if(c=='+'||c=='-'); k. p5 R8 [/ V# X- ]* l9 W
return '<';
4 N1 Z! u" u1 c" h else if(c=='*'||c=='/')
2 D. k8 z! x3 T return '<';' P; [) p" s& |4 Z# _, Y
else if(c=='('), G+ S$ ]1 m, W& U
return '<';5 g1 O) Q* k' H# x' a
else if(c==')')! L- M+ k! _9 X- C2 h8 M
return 'E';, _: V4 o3 T# h( W# n1 r( q
else: y$ s I$ s6 H1 q' ?6 U
return '=';
- L, d- [1 Z. F' N) z$ ^+ y default:
# K' [! y7 U1 Z5 }) e! @ break;
+ \; S H% L- Z }
, @2 S! X+ r/ x% Q7 M+ c% _9 } return 0;
7 ]/ a9 f+ f* D b) O Q& ~}
- f* c, l1 j! J0 y
( x. B l5 K# X- F; s/ m( yint isOpr(char c)
% e8 p$ ?$ O3 i( ~$ y, c{! @$ v( g) a B |7 E! T6 O
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
5 k2 b1 H( s, y return 0;
: H z- i5 ], I8 ~) o3 o! H& I else " M: y0 R" M1 b. d( J% ]! K5 r' U
return 1;
% }4 E( W, A3 _5 w s}
7 R9 `, x C( h' a) i; c% O, a0 Z+ g4 `5 i& h
float operate(float x, char opr, float y)
9 w& y% I# A" |2 ]{$ b' k- ~- B4 Y4 l. e% u A% \" v( c- j
float result;
% {# X! i& w- @( W* T switch (opr)" f& ^' ^# |; M. q2 C% K
{
0 O4 v) ]$ e( V$ K4 Q4 z9 G case '+':
4 Z2 t/ s- M) ?' @8 [3 x: l) Q; b result = x + y;
1 c6 @- w- ~3 b) k/ O! a& o+ A( i7 X/ G break;
2 y( c& W6 K$ L1 I. U# [* ?: K case '-':
6 r7 I( |2 I4 |/ ~9 a" o' ?$ l/ E result = x - y;) L3 R6 @6 L% w. B
break;+ ^; N3 X! _4 D6 L6 ?0 o
case '*': $ ~) @. Z+ i9 V( G1 @
result = x * y;3 @8 o+ O P& Z
break;
* W) x2 ?0 X4 x0 a x. G7 H case '/': ; D) b" t, i0 H8 |4 {+ P
if (y == 0)
5 d, S* ?- f; o2 G5 A {
1 Q2 H3 V( r2 E1 ^4 ~ printf("Divided by zero!\n");
8 S" W7 \; j J) c! {+ Z, ] return 0;
, q) e. x/ t! j4 |! O1 @ }
5 S4 B1 X! \9 w5 D3 j" K* c else
A( T) y+ d6 B; e2 y; g {
# C* p- i4 D& W# n4 C6 D result = x / y;
/ G+ t8 K, b* ^8 M break;
$ k$ y g/ O0 `4 \ }
4 z+ w- [% e0 ^9 y default: 2 i$ ]! c l4 G# `
printf("Bad Input.\n");
& F6 |6 f+ o6 c, ?5 l; x return 0;/ r; }* M- Q- P: W) F9 C+ {
}
. r) D, f- l, N return result;
# j) c s3 F _, J6 C} ) T1 O+ A O4 v7 s9 d; o2 l
0 @* T6 _: e% X
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/" f% v7 D/ }! D" O& q. f! o/ X$ O
{
3 h$ A7 C) M) s9 P3 P/ g& a Stack optr,opnd;. `$ z3 u- [% }3 d {. m
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;: J6 g' x& B. B5 x
char c;
! y- i1 c5 `5 q. b char buf[16];* l5 D! l }- \% z! O _6 k
int i=0;1 a* d* ?" a1 t
' _1 F2 @4 N- g5 a' Y) n- ~' o7 Z3 l
InitStack(optr); /*用于寄存运算符*/5 [5 { f+ e$ X1 k
InitStack(opnd); /*用于寄存操作数和计算结果*/
8 b7 K& \& S+ ^% a% O, E R8 C memset(buf,0,sizeof(buf));. D; B! D7 a, N% T- w
" e/ j" v x: ~3 @2 p' |
printf("Enter your expression:");( W2 L3 N, H" x$ P+ K' I% ~8 H! V
: g- h2 W& s: m, [4 j3 `3 Q4 J2 f opr_in.ch='#';
2 {7 r3 a$ z% |. c1 j; g* i Push(optr,opr_in); /*'#'入栈*/
2 a8 D6 \4 n' w+ t8 [ GetTop(optr,opr_top);. s8 F# p$ ^2 x- f" v2 Y& \
c=getchar();
- p- e8 D( f5 o. w' e$ p; A" G while(c!='='||opr_top.ch!='#')$ U1 e& P2 A6 D+ L2 P, e R
{1 t& }6 N5 r3 I; a v- `) T) D
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/( P7 g; k% Y0 ^
{
! g. s6 s* Z9 X6 b buf=c;
) n- q" M p. p" e- m* y& z i++;
, H* P; j, N: ` c=getchar();
# N6 w8 g4 ]% p% ]1 z }
2 m* V( z; r8 {+ H else /*是运算符*/6 Y1 @) g* N6 y& I }6 a- H
{
: z1 n9 A& S R9 J" ?. x buf='\0';
7 A J9 w# ?4 O* m- u' z/ h if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
2 \, g! W' p/ j) T {# d" H1 _1 F* `4 J
opn_in.data=(float)atof(buf);
2 T/ M2 ^5 h# i, S, K; k Push(opnd,opn_in);/ s/ P8 z) k4 H1 g- d
printf("opnd入栈:[%f]\n",opn_in.data);6 k; ^: m/ p( C) b
i=0;2 z m" U8 o0 f0 I8 j8 q, i
memset(buf,0,sizeof(buf));
4 t9 A$ r! g* u7 H2 u7 b x6 S }' c1 r9 W/ i: ~8 ]7 E# ]
opr_in.ch=c;. J& M7 u% K0 p+ |, @/ P" u) g
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
& E$ J! B6 z1 ~& K+ ]6 A% i; p {
3 }% w5 y3 O) R0 e9 H2 E case '<': /*优先级小于栈顶结点,则运算符入栈*/
; [+ `& u: C% ]. Q$ v$ b% [, B$ m Push(optr,opr_in);
& W; B" y7 X' `( ?( [. G2 b printf("optr入栈:[%c]\n",opr_in.ch);% ~, X: K( s' t h; Y
c=getchar();5 m) Y0 X! _1 d
break;6 L4 W# F# d, s4 }! a
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
( v0 D& X) u: N( B* [+ O Pop(optr,e);
5 C# T3 |& X$ ~: }# P printf("optr出栈:去掉括号\n");. F# b6 g Y4 N
c=getchar();
0 t. ]2 @" U5 k+ x, E7 V6 B break;9 V. y) q" C0 e# O: I, [/ I8 g3 E
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
3 Y2 P N* Z4 j5 ]! J& b. W Pop(optr,opr_t);
- v6 [4 V5 }& \ printf("optr出栈:[%c]\n",opr_t.ch);
. D1 R; d8 f1 e2 i! K. m+ H x if(Pop(opnd,b)<0)
% Z- b4 _' ]6 E7 ` {9 j5 k" [9 h: V s& W1 h1 l5 u
printf("Bad Input!\n");
; W. }* z; }, T' j' k0 l( l fflush(stdin);
5 Y' {" t; w; J! |' ?( n: {( Z: S return -1;4 [: t* v- o( J& I9 a
}, c8 P" \8 P F% ?4 c: Z
printf("opnd出栈:[%f]\n",b.data);
9 v1 c3 C" E+ y* j) ~5 O! P if(Pop(opnd,a)<0)
6 A( x! V& i3 h* w { o3 n0 P3 i, |- g( w5 b% g6 H$ [
printf("Bad Input!\n");, X- z" r% c' r- v0 v) B7 U
fflush(stdin);- z$ ?/ ~( ?% T! s
return -1;
" K3 m$ Q! ]$ z; q; W4 P/ ` }+ R2 }+ |% L- F* M2 w- e
printf("opnd出栈:[%f]\n",a.data);. [! i3 w, Z- f5 G; _
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/ i% U4 t) v+ R, I' S1 G0 r
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/% J; E3 ^6 M- |9 i9 y2 {8 }1 Q
printf("结果入栈:[%f]\n",opn_tmp.data);0 H* ~3 Q: K ?, k g
break;5 S* }* ~* Z3 \1 U) k4 {0 e
}
+ x) F' n* o9 L# {4 d }1 N+ ]4 \1 x" E0 C) V# T5 i* X# U2 [
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
7 _4 L9 _+ g6 K8 _9 e( E" b }
" {8 _5 |1 ?3 ~& q, N* } GetTop(opnd,opn_tmp);
) c6 h: ?4 R( `, }- @4 R2 R% U DestroyStack(optr);. I8 w0 u8 _, i
DestroyStack(opnd);
& i: w% \9 F- H3 X9 w return opn_tmp.data;
+ I: C' `% U5 X6 ]- A}7 ]; I7 n" z$ N7 }, h: _( I0 d5 x
$ I& N8 w8 u% i$ e
char *killzero(char *res,float result)/ E/ {' x9 S( m9 ?) B* q
{+ M# l& q. y6 Z9 ]' e. g+ [
int i;
; \; y8 i* ~' Z8 }9 j
, W0 X4 N* q5 }! U sprintf(res,"%f",result);4 O* a! w3 [6 j8 R1 l# i; W
i=(int)strlen(res)-1;
/ ~+ D9 d* y) H* d while(i&&res=='0')% g7 H) X& P" d' ^
{
6 D& D% N# G1 [; } res='\0';6 i5 C- h r: x7 i- W: w7 r
i--;1 n8 v' [) ?4 }+ k1 Q( p4 I( c
}$ p# m" m) P; ]0 S
if(res=='.')
. G3 A5 \. c7 P6 f( a2 [& Z res='\0';! {- l9 h9 X: j" G& w G7 h' R
return res;
: J7 o) }9 ]8 s4 n. w}
0 h" K- S/ w" d
: v8 R+ c9 k# I% g& m# M* M* Qint main()
! x# |1 w% }' ]+ @. X) O{9 R" o; P( O ?% J4 [
char ch;
4 v& L* C4 ]2 |5 \: b char res[64];
. `9 G: [% Y& F. @ float result;5 i+ l1 ^5 j( j* W! p4 z
while(1)0 d8 j4 j& ~; [' `0 i1 {
{7 I( z' ~7 y4 J% t# y0 ]8 b
result=compute();& |- \9 N6 g7 A* ^ L
printf("\nThe result is:%s\n",killzero(res,result));
1 w- O6 f Y1 h* B6 {' p printf("Do you want to continue(y/n)?:") ;
8 X' |# e* R" Y+ P: g1 y ch=getch();
& p, x2 F3 ~' P/ e( | G; [ putchar(ch);4 k6 Y `: \ C5 N! o j6 N) {
if(ch=='n'||ch=='N')3 `, ~2 c& D6 H% o: Z* n. c b
break;) t9 @# n& ^- ], ^4 H
else( {+ |5 z/ M. X7 K, C7 W0 R
system("cls");' Y( F' F7 H7 C
}: B* D% f. k: t3 @ r
return 0;
& J& m G R- t/ y0 ^+ j4 ?0 o- L}: v1 Z1 n" g7 D4 x+ i" v2 B( o8 d) h& ~$ N
; c# Q$ ~1 H$ T6 P
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|