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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.6 b5 A. C/ x& ^7 i9 [+ D
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=( |) J9 `" }# o: _2 }9 ~; ?) h
/**************表达式计算器************/
6 ^) f j! {' `#include <stdio.h>
+ G E1 w& g p/ i: z, ~+ @3 g/ G, w#include <stdlib.h>
7 w5 x- V s$ Z/ p5 x) O% s2 o9 ]#include <string.h>: E, _" q+ b/ @3 ?% x! p7 E
#include <conio.h>
% ], ]. O% C- K6 [% n#include <malloc.h>
" ~1 t; c% Y) ^5 C3 `/ L
) ~ o8 d2 K; K) t. @7 I. c#define STACK_SIZE 100
# [0 ~ S+ ]. G+ N* R; k) l#define APPEND_SIZE 10
5 _* B9 B, Q, s2 a; ^" v6 E! t" t* G7 E* w
struct SNode{% K; B. \+ L% w
float data; /*存放操作数或者计算结果*/
( `0 N2 {4 e7 l- G; s) Q8 w4 l char ch; /*存放运算符*/! `$ x6 j+ A4 M" d8 d; G' a7 r
};% G& Z( J0 R1 ~. ?
2 N! v% x+ S2 E+ Mstruct Stack{1 T# z6 |$ k0 G5 Q- s7 m, `: Y
SNode *top;
( h$ U- Q3 O! c6 O) O SNode *base;
! n2 `$ J& _/ }: Y; n int size;4 q1 h/ W( s. w
};) i9 e! v! |: Z& ]4 n4 n Y
# |! }: | c' r' v4 S
/*栈操作函数*/% K5 {% {6 b ^8 e3 `
int InitStack(Stack &S); /*创建栈*/
! h% b+ e/ q5 kint DestroyStack(Stack &S); /*销毁栈*/5 c$ z9 H# }" @4 Q7 `
int ClearStack(Stack &S); /*清空栈*/
, C- y% o. |( X2 q6 sint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/0 I9 |2 I1 x- w. q! p
int Push(Stack &S,SNode e); /*将结点e压入栈*/! V$ c3 p0 o) s5 ?" r$ c' b
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
: r2 X/ r, _+ t+ ~2 p% u& n* t) `$ @0 {0 [$ n$ U; V
/*表达式计算器相关函数*/) W' J! k$ ] M k3 W
char get_precede(char s,char c); /*判断运算符s和c的优先级*/' v) K4 A. r* l/ z+ C a' C
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/5 b% e* j4 G$ S( P4 r; M
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
, b! k) x$ j& p0 M7 \- @float compute(); /*表达式结算器主函数*/1 X6 {' p/ M4 ]/ n+ b9 ~+ X% G
char *killzero(float result); /*去掉结果后面的0*/
& @8 Z; q: E+ Y4 v# D+ d* V7 ~# F
; m& P3 e$ t9 u1 r9 O, bint InitStack(Stack &S)& R: G* [0 @( a M# g8 `
{
, e+ |1 f" l8 f1 u. { S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));. ^6 H# W L/ P5 o9 c) O
if(S.base==NULL)
, W' m$ }1 G2 d3 ? u$ y- h: e {& `1 T2 x* X; Y- T2 n1 M
printf("动态分配内存失败!");
5 M" G; M# J; n4 C8 n return -1;" G5 A7 s: q' ?/ B v
}
0 t2 q0 K" P# ^3 f4 \- i, Z7 {! p S.top=S.base;) w: a2 T3 p" M) }
S.size=STACK_SIZE;# x* }+ P1 d- | x, E+ O3 Z
return 0;
& ?- v1 \3 J6 y, h- a2 t. y9 \}) z9 S. q$ W0 m: Z! i
( V$ c) l; i3 u# dint DestroyStack(Stack &S)
& P4 T) g" C. I% S1 X$ G& T1 Z{% |4 e! X( q @. z! b0 c3 v! P1 e
free(S.base);% V' a/ e8 z% a5 T9 c
return 0;# o) O4 p- f& x
}1 x' @5 S# x' v$ L$ s
2 U' ^) o/ m( I0 Z9 v* P$ E
int ClearStack(Stack &S)4 ~9 e2 g, L* M3 c+ K" O3 J/ S
{
+ \5 c2 z4 A W. Q# t1 q& u S.top=S.base;5 x9 W7 T/ J9 ~3 G. X: Q
return 0;
6 L z* Q' a a4 {}0 B/ ?' b! e8 B5 J' v a- S
$ z9 k: \) G9 L6 t) b' b
int GetTop(Stack S,SNode &e)! h" h; ]7 ~6 R& h
{. `' H! w" V8 Z3 G6 _! I
if(S.top==S.base)
R0 f# s0 X7 B' ]0 H& W- Y {- V) u. b; p @3 p/ s: W0 Q E: {
printf("栈以为空!");
+ i% ? T6 L6 g. ` return -1;- o! C+ v: p# Q. }. ^' w Y
}6 _4 ~9 N; e. N0 x3 q. h
e=*(S.top-1);- v' V! J2 }) h0 S1 U4 p" y& `
return 0;
( l6 }2 c) Z7 j) o/ m" F' h3 m}+ @ s/ }/ T% F1 n% h
2 e, }% v" R% c3 |6 z
int Push(Stack &S,SNode e)$ f9 `; ?0 o; p- c4 I! Q
{
- O& b3 V3 I5 u6 @ if(S.top-S.base>=S.size)
( u% e0 x& @) }- O) i2 k {
* N# g2 d3 d1 Z S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));/ w* S5 {! ]) E) D6 s
if(S.base==NULL)
- d- J7 e# k Q! ? {
) A7 T/ [2 T; O/ }3 K printf("动态分配内存失败!");
" D5 }- p1 ^" M4 y3 r! }% r return -1;
, v/ @7 U7 R) L$ t5 c }- u e! H9 ]6 a( o; n
S.top=S.base+S.size;
; r' p+ i! t( c8 d+ v% I S.size+=APPEND_SIZE;
4 }+ }( S* o2 W4 N! T/ ]" q }
/ n" `' C; X- ]1 I e) ^4 k *S.top=e;
( x5 j+ y* x( `$ j" v S.top++;1 x4 O" u% G; i
return 0;9 v( b/ p. O+ F; F
}
+ {4 N6 j1 w6 K, \9 B
. B2 G9 z6 Z% N+ t4 j9 r# b5 |, bint Pop(Stack &S,SNode &e)
8 v9 B! R/ d2 S1 Y8 e{4 g8 P# q J: i# A% `9 c( d) k- U
if(S.top==S.base)4 P/ u# _/ y) q$ l! Y
{
6 d1 C7 r+ ^$ n% s printf("栈为空!");
/ ]0 m! m$ Z9 }/ m5 _$ v return -1;
+ X' Z- s E. N8 q }# F' I6 P4 t% N" w, P
e=*(S.top-1);
/ H4 Y. t1 e' {3 f3 T% t9 S( }# `! e S.top--;
- `1 m5 E: g& F, L, y2 q& R4 B$ K return 0;1 a. @% C7 `- d+ q" A+ u% w
}
p# Y _ ~/ l! W! S/ m
. Y5 f- i4 K8 Xchar get_precede(char s,char c)
3 \7 E& V" w) m( d; s2 Z{
" c; A Y2 O8 ` O8 W! ] switch(s)6 X8 [1 f6 h- ]0 z) N, I% p
{6 ?. D# W% h5 ?2 E0 c8 A0 B( V
case '+':
; r4 M) e( K, U t8 ^# E; I case '-':, h' V7 |, D& _" Q. B0 C
if(c=='+'||c=='-')
! @, d8 i; w2 N5 `) D. l0 L6 Y) k7 j return '>';
; l1 i% G. H5 S6 J2 \ else if(c=='*'||c=='/')
6 M: R7 b" N% q- Z( T. H return '<';
! M/ w) u7 C. Y/ R' s" Y else if(c=='(')( m1 e4 W/ r: l9 F4 L
return '<';
( \9 d7 u3 i+ \3 `5 t# ] else if(c==')')- t2 ^3 f5 y4 Y# P& z! B
return '>';
) }# m% N% D( k' | else
8 F! V- T- w. I* P9 z% [6 t return '>';
! V- k# Y; E4 g! h case '*':4 R4 @5 u9 M: {1 G; z
case '/':
& @. u- f0 w/ K if(c=='+'||c=='-')9 b# I% @9 E: s; @. y; N) E0 k# |/ ]
return '>';
% n, ^+ r N: T! h# r% x else if(c=='*'||c=='/')
4 D- q4 o: Q& ^3 N return '>';
" {; H$ ^4 j# y- ^ else if(c=='(')/ N1 o* s: E& N5 @% P
return '<';
& o8 O& {4 t0 j0 S0 d4 S; X0 ~8 n else if(c==')')
! w% z" |1 o" C {2 L/ f return '>';
/ t* Z; t+ P M$ ]' E else7 Y. O, ]' }( I
return '>';
: Y. i5 q/ t/ L1 [8 ^ case '(':
. m! L5 T( z6 U) m; G( d if(c=='+'||c=='-')9 w. S! B+ r+ b* C7 c! X3 s
return '<';$ w& M! f0 s# R* x
else if(c=='*'||c=='/'); w7 ?! p/ E) s
return '<';
, j0 t; Z# Y* ?" a else if(c=='(')
, U! U8 B# v. M$ o! t; s1 Z return '<';: w, V1 l$ p# P) P1 w0 h; \
else if(c==')')8 l% E5 b- I- J2 A9 {, E
return '=';- y1 C- H! n6 ~: E$ T: c8 t c+ w/ t
else3 o8 Q- S- E! F: e
return 'E';7 U! W6 P" @- h
case ')':
7 g1 m* a0 z8 N u if(c=='+'||c=='-')% [) x( l7 V. e9 B2 [4 l% T
return '>';
/ ^. }! Z& e4 h! c else if(c=='*'||c=='/')2 x0 U! A" q9 q% `
return '>';' E* `7 l0 v' u# A c
else if(c=='(')8 i5 v) B8 x) R0 h, H" o: g
return 'E';
% Q' l U- |9 M/ c0 H. G else if(c==')')- N" N5 O O( m
return '>';; J9 A h. r! C5 X
else& b7 ^4 ~1 v/ H" Y* M
return '>';. t% [8 w4 U/ [9 |% |
case '#':
! s4 ~& J5 M- o; |$ J5 ` if(c=='+'||c=='-') O# B' y6 _/ @4 t. W
return '<';
, D, Z2 ?+ |: j! J& s! P else if(c=='*'||c=='/')/ j( z7 k( M) T- J0 @& m8 i
return '<';
4 R q+ M4 n6 h9 V5 J5 r else if(c=='(')! C5 c8 [$ n( Z
return '<';$ c G( G& m5 Q) g* [& j
else if(c==')')& k" E/ z% d! B
return 'E';# z' c5 m: e! n
else- `) f2 o4 ^0 q. u8 u4 S
return '=';. p8 A& k' O. `* Z: |7 m/ c8 V. R: G
default:
+ w2 T7 h0 c7 Z; d2 p4 p6 ^ break;
3 O# m4 r9 O; ~; [- r }
, ?: ]) _0 C# Y/ s d return 0; - B7 k8 w0 d5 [+ i: \+ }2 Q
}8 g& M$ ^9 a' E9 T7 f/ L3 w3 L
6 T8 h. ~( w$ L# z5 Yint isOpr(char c)" v+ g% G3 C8 ~& ~
{
. Z' d) P. i7 y" C$ B6 r% z& r if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')! l# P! i1 w/ L/ {+ ]% D
return 0;4 U1 B1 q8 a, U0 F p6 D
else 8 V& U' Q* |, P$ j- e
return 1;/ `! S, I+ z E( H1 y5 k6 f9 y% `
}2 R. i7 P: f$ _" L6 W* @
- H! I' x& x% o( `8 M
float operate(float x, char opr, float y)
# l: W5 V5 Q% }/ M9 _1 W5 j* a{2 u7 R( X3 q$ \1 u5 P2 P$ D- y
float result;
$ j+ ]$ ]& I( S switch (opr)
# Z/ N1 {) J4 P' }/ z6 m$ L0 c5 j {
* Y5 Y5 T" N* `1 E case '+': 8 U7 Q5 l0 i) }4 U6 p: K
result = x + y;
0 U. _$ ~4 Q0 h o0 K4 V) w break;
$ c+ u, Z" `3 Z+ c/ w4 q case '-': - z0 B3 |$ b3 K8 C
result = x - y;6 l9 Y. l( l' e; V
break;
! D; z* p) `: }. ]- K case '*':
" p1 j! |% i9 x result = x * y;
( Z+ r3 ^! K. [ G break;
4 ^4 F: b' c# H case '/': a, I! y5 _; I1 K% Y4 V$ b2 a7 {
if (y == 0)9 Y3 v' n2 U/ Y L1 w) D( X9 _" i* ?& i
{
( s/ k% y$ {3 s& g* X5 d0 } printf("Divided by zero!\n");
9 z& D$ {8 g' U( M% T4 e return 0;: g9 c7 G. X' j2 u1 C" a M n
}& p" g6 H/ a* N6 n. B( z* {
else* l9 V4 t8 Q7 i5 g% y* v3 T
{* T' O: S' l8 V; R2 |4 r: U$ A
result = x / y; K0 c& S' h& l3 _8 m, D
break;9 O; C8 [+ k* U: p( m- w v
}9 U6 M& j3 ~& j# ?. L. a& v" ]: q
default: ; }2 R1 h9 v, }+ L
printf("Bad Input.\n"); # G1 o9 a$ `+ m8 X, i5 q
return 0;& A# Q4 k& [( a/ y6 T
}0 z, y& B! \- _& \7 j
return result;
# v: H% e4 X& W$ D5 p5 a} 8 M: g0 f+ n; b+ b, L2 D b# M
|% @- ?4 N7 Q9 h3 j& ^. \
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/, j2 P7 l$ l) i! D$ C- l9 E4 Q
{
6 R8 X# w4 o i/ {6 O Stack optr,opnd;' m. v4 W; \& B: F
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;" L3 x- ^+ _! } [( K7 S2 C
char c;
+ R' S# F- a* T( \( } char buf[16];3 p/ C$ i0 @2 T9 `+ K* L
int i=0;
) P' V2 H0 w( Z( M# V " l6 `- X* P- T( |& ~
InitStack(optr); /*用于寄存运算符*/, Q2 T% l1 c6 i% s, u5 q% e7 X4 ]
InitStack(opnd); /*用于寄存操作数和计算结果*/4 @9 g/ m1 a1 Y
memset(buf,0,sizeof(buf));
) J$ s; Z7 `( T( i; Z) A
" p# x% W+ k* H% a+ v printf("Enter your expression:");
" d# W5 x) }" J- d, X 6 E; {" q7 P- c0 c) D$ B2 Y
opr_in.ch='#';
3 ? v3 v. P% v; p. g- J Push(optr,opr_in); /*'#'入栈*/
2 {$ H) w* P* |, Y0 K9 R7 N' z2 W GetTop(optr,opr_top);
" a5 S( ^3 R. Y8 ?# m1 ^+ k c=getchar();9 g. [ P, }. P3 c/ u S, c4 J8 ^
while(c!='='||opr_top.ch!='#')
! X, [4 ?* F1 P" I {
8 ?1 `/ v2 M8 M! T4 {) a4 g if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
( ?& |& J* G" ~6 k3 c2 s' H/ a: V. r {
@6 W* ~. R5 p r+ W; C8 W1 z0 k4 ` buf=c;
: i2 Z" A6 @* N i++;
& G3 x' e/ q5 q3 K$ ~3 a c=getchar();
* R2 i8 a% Q# }8 F# o }
* |' m7 X; {* w1 K7 s else /*是运算符*/
9 }4 z& A7 ?$ N+ D {' s) b4 x+ @! z
buf='\0';4 t6 ~5 ~9 B8 Q9 q9 E* c
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
/ X/ m* d: j+ z {$ P" s; O; ?% Q0 {2 W
opn_in.data=(float)atof(buf);
3 v" q4 M3 ~) J; A Push(opnd,opn_in);
' W" y" F8 ]* d& X printf("opnd入栈:[%f]\n",opn_in.data);) j. _6 a' b$ W" S4 y' S
i=0;2 Q; p; s& \/ L
memset(buf,0,sizeof(buf));7 C6 d1 U' j, G+ u
}4 u/ i# @8 Q8 \3 ~- m9 K$ e
opr_in.ch=c;
) f5 R: D" h' s$ n switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/& l3 ^. n7 e- F4 S+ P
{
0 C+ G0 B4 S/ Z4 h case '<': /*优先级小于栈顶结点,则运算符入栈*/" G/ Z6 Q6 ]8 ~2 z
Push(optr,opr_in);
/ I, s# ~1 ?' d" O8 e printf("optr入栈:[%c]\n",opr_in.ch);
6 s: U/ |$ p9 w! ]7 c2 X c=getchar();
0 x- X2 G# i4 C1 H break;* E% D; _5 u- T8 {
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
2 V- \" V$ x; u) a/ s Pop(optr,e);8 v0 ^ s8 L, t0 z( \7 H
printf("optr出栈:去掉括号\n");
7 K7 a; W O7 b. x$ D* M c=getchar();1 Y0 h3 f; J! ]; a5 @
break;
1 \8 {# Q' P9 V9 d! a: m. W) q case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
; X0 B) \8 C! c$ Y' f) B Pop(optr,opr_t);
" W' }" {$ i# { R! g$ E+ ~8 \ x printf("optr出栈:[%c]\n",opr_t.ch);
. i$ R6 b% u2 V5 L E5 ]( w1 K" Q if(Pop(opnd,b)<0)2 X/ Q, [$ L8 X4 @8 N
{5 P/ i& d0 A4 i( d* N* j" e
printf("Bad Input!\n");
2 ?% c7 Q/ W% g2 f; q! P! ]& E fflush(stdin);
; r% M0 m# J. U2 e4 C# d7 B return -1;
2 W2 t/ \# I" E5 C }
# l `7 k6 M0 C: q printf("opnd出栈:[%f]\n",b.data);# [7 G- W# m3 V3 l
if(Pop(opnd,a)<0)- }' d% M! c4 D' z
{
1 D* J8 I4 W3 d printf("Bad Input!\n");" c7 U( R) \5 ]9 B& b! K! D
fflush(stdin);
6 }! C$ F0 t( g0 k3 f return -1;; C7 V5 Y# b# @9 w' {4 i# y
}
; G! H& q4 g! N$ f printf("opnd出栈:[%f]\n",a.data);6 X; H; ^2 T9 m2 \
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/3 Y$ t6 R# e5 x
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
1 B$ r7 m% R, x) O) R$ S printf("结果入栈:[%f]\n",opn_tmp.data);) u% \$ j+ T+ _# S% T% Y
break;
; O5 h5 u1 v$ [6 q* K- \9 R9 d }
- ?4 Y8 Y' v6 K8 y, R9 R' m6 v }! y& G2 D. I( _0 ]* a1 I
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
' K: X2 }+ i1 X# R6 _ }, x1 w# B% L; I5 l2 o2 V
GetTop(opnd,opn_tmp);( r& K9 I- X, s# @$ p/ o3 G
DestroyStack(optr);
: a* j: U% W) O1 X DestroyStack(opnd);
, \8 U5 a) m; Q! D return opn_tmp.data;1 R1 |) t5 u5 g3 n k: q
}5 D2 |! T) @7 a3 W4 L
f) R- [3 V# r9 xchar *killzero(char *res,float result)
+ [8 E- X4 F5 ^7 Q/ f4 l{) s- r* d9 O6 n Q
int i;
1 n F2 y5 V0 j( L
9 T2 B$ R1 W* ~, b s. w sprintf(res,"%f",result);0 o) c8 N6 H2 L8 S! x
i=(int)strlen(res)-1;
- e7 o$ Q6 D! a: c7 |% c while(i&&res=='0')+ y. g6 H% r$ o3 l. {6 u( u
{) M- w( V) H4 M2 l( `
res='\0';
$ U% M! W" D6 N i--; r2 Q& l. L L6 z, [/ D9 `
}
9 u8 X7 Q% A9 Y' h$ z x' y. k if(res=='.')3 O7 K! Z+ @: G$ u, B5 W% Z/ Y
res='\0';6 F' R, b- w6 W5 Q$ c
return res;
/ \9 N4 J) U. q% k}( j! `: ~* c- r
7 m4 U! P# U8 @3 i
int main()
; A4 I! P. O' n3 f' j! ?0 E+ R5 r{# p+ r9 ^; y0 m. ~( e# S6 x2 c
char ch;$ {, @; t7 e, N+ n! w8 \5 D7 c
char res[64];
# ?2 z! Q& y- P+ O( @6 ?* G float result;5 C* m* L/ n( C/ u g
while(1)& F, n2 Q+ S' w; M4 R" Y
{
& g( c$ Q- A' r0 f result=compute();" x% D, |3 q3 s, Z& C
printf("\nThe result is:%s\n",killzero(res,result));
$ s/ {/ c% W* l4 W5 d6 e1 K4 c printf("Do you want to continue(y/n)?:") ;# D% i; n f! u; h* Z& o
ch=getch();
: V& J6 V8 X; _' h putchar(ch);* y1 i; S" P9 z. L
if(ch=='n'||ch=='N')" j/ z$ w- j" V$ \$ {: |
break;1 m7 P6 G8 E3 I9 c
else
9 q) H1 _" j3 r4 T system("cls");
5 G( q/ t. E8 a( p2 ^6 j }
4 Y# Y6 k$ n' x" B2 L# `% |9 { return 0;
5 ~% k0 @5 a) U& `}
# x8 `- a% j7 x+ m l! n+ T1 F/ l/ _& S' ^; t$ {; k+ M& U" q
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|