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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.( S2 H' D' C, v$ o
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=1 [4 {) _, K6 F5 G6 p
/**************表达式计算器************/
. H& c1 U# b7 l) n! {' f#include <stdio.h>/ f) Z" e' R3 w4 \! g4 ], z' C
#include <stdlib.h>6 Q+ H1 K6 x: ~0 q
#include <string.h>. I0 Y8 J7 r( V3 S# o+ D
#include <conio.h>
8 O: W% r+ j5 Z: ^. `; L5 E#include <malloc.h>/ R5 y$ G+ T4 d0 E* F
, D% W* O4 K1 j#define STACK_SIZE 100
: E9 h& A Q0 V3 {#define APPEND_SIZE 10$ G8 B0 b8 R% E8 z* [) A
8 y9 \0 r) Z/ `4 w( H9 H4 m
struct SNode{
% e3 O& j1 s; ]% b3 Y float data; /*存放操作数或者计算结果*/2 Z- t7 F& k: p- W7 X2 l
char ch; /*存放运算符*/ r9 \) w# L: t% t, v
};. R0 f, ]' P$ b' m! q& A
1 r2 W& }9 K8 W0 J1 _* k5 A
struct Stack{" U( U# ?: ` S; {1 ]
SNode *top;! U0 T8 ]0 a& R7 `5 P6 g( b
SNode *base;+ j' A' W/ z @6 ?. H
int size;
+ e# }, f& L4 v8 f# J. m c! q};
' p8 y9 |' [- u% X8 O0 d: z
9 f6 F% }$ q" s7 I/ H; p/*栈操作函数*/
~' P: n5 O) _4 A' A" C- }int InitStack(Stack &S); /*创建栈*/
; B, R7 r+ l4 bint DestroyStack(Stack &S); /*销毁栈*/% a0 U2 O7 X* W
int ClearStack(Stack &S); /*清空栈*/ n$ r7 Q+ P1 w: {* @
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/. d$ m8 U/ g3 d+ |. G$ ]* ?* b
int Push(Stack &S,SNode e); /*将结点e压入栈*/; `1 o0 T, t, C+ D7 N$ W
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
# [" l8 B0 q& F: j% m4 L4 \1 x6 @. k1 r. W; L1 d" A
/*表达式计算器相关函数*/
9 i6 z3 C) Z( |( \$ d+ @" Ychar get_precede(char s,char c); /*判断运算符s和c的优先级*/
j6 Y* p' s" l/ _' x) zint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
& s3 i* h3 n8 a0 b7 k! E% K5 }float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
! m" P( [! @4 |( @8 L) u. zfloat compute(); /*表达式结算器主函数*/
+ r; y W# y0 ]% uchar *killzero(float result); /*去掉结果后面的0*/
- D C- B# q) T( g6 E4 @: j5 m& z* N+ Y( d. A6 s' {
int InitStack(Stack &S)6 o1 o8 s( _6 F$ c4 g: I
{
! d% A5 ]- Z& m* d7 X S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));/ y- d2 J, a- G: N
if(S.base==NULL)
, h8 P* U8 Z7 { { o4 t6 x5 X$ Q
printf("动态分配内存失败!");1 ?) Q1 H$ |; s& O. ?
return -1;
8 K4 O/ W$ O, F) {# Q }4 ?9 N1 \2 U1 u/ W# K
S.top=S.base;
% H1 d! b+ s! E. N S.size=STACK_SIZE;
9 @( w- J1 Q( O5 s j. t- ]; h return 0;+ m; r$ Y- B1 k! x v
}/ i1 ]9 Q. d) O6 e' M" W8 r: X9 h
# A: S; p! S( |8 K( s1 l
int DestroyStack(Stack &S)6 d9 W9 N. c, n4 k
{0 T- ?" k* e( Z; @
free(S.base);
9 K) H1 s# z0 C# F return 0;& a4 R$ }: M c$ D/ y/ x$ }
}
$ b+ t1 x6 a" {% j! n) g* _" w1 }) u6 {' k- E
int ClearStack(Stack &S)" f7 ~9 v) M- C! t2 Q
{. ~/ e5 ^! z8 \. T: D
S.top=S.base;, t0 c' S: \+ c- Z1 n
return 0;
' o% w, G2 ?4 l}
/ w* l! b8 U. a7 K/ N. S. x U/ K4 E5 n
int GetTop(Stack S,SNode &e); w: ^. q% C: I* i0 }/ {3 ~
{0 v7 G( I# U6 r: s9 X0 g8 E+ t( A
if(S.top==S.base)# K. ^$ V9 r% r+ G% B$ j. j. C# x
{
' Q0 N! ]# j8 T2 _9 O printf("栈以为空!");3 u) V" j# k7 {+ R8 a( b. c2 d0 W0 z
return -1;
! t2 N/ @5 s* N0 m8 f/ Y; @5 t }* C& X$ N3 K* ? g# @
e=*(S.top-1);
5 P q% v$ i8 t7 `( q: R1 u return 0;
- ~$ g4 Q: k6 I; j6 Q& @5 k& l}6 |7 \; X0 |; j* ]8 Z5 u: U3 l8 f
: j: w) [' @" P5 F+ e) k! }
int Push(Stack &S,SNode e)
: @0 U. D: S# M7 `{
+ u) D3 ]$ u; k/ D5 }( h- l if(S.top-S.base>=S.size)% T5 f: I- b/ S; e) r
{
% q. [8 V' [7 e4 V8 [8 P5 } S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));* b4 [& K: ?+ s4 Z! B3 Y& [1 Q
if(S.base==NULL)
$ l$ _0 D" }5 |7 z7 C {
: [& D1 G$ ^$ j( y$ r printf("动态分配内存失败!");
# O3 T5 N0 A) D; d; N return -1;
/ S2 {% c+ T6 l7 c' J U+ h4 C' I }% i, f# C% S. B, U. B0 W
S.top=S.base+S.size;
6 p: C0 W" M, R5 Q/ h+ B& } S.size+=APPEND_SIZE;* {+ y5 g" q/ x' j6 h
}
! R8 X! ~5 Z% a7 g) b; v( @ *S.top=e;
/ w$ r' e* k* g) } S.top++;
# v0 B+ a# c- T" { return 0;
# q8 w8 c2 w1 Z}6 ?# @$ z7 |+ N( ~: T
( X! F1 U5 b' G: Z- xint Pop(Stack &S,SNode &e)
- O$ l% n$ @ n{
; O0 n D% Z5 f# F3 E! p! N- H/ Z if(S.top==S.base)
?+ b7 q$ O0 |/ a D- f {# ^, U$ |0 |- ]
printf("栈为空!");
+ j, ]9 Z& `+ E. ?) n return -1;" u$ F% I1 b0 _# v6 u/ Y
}! ]% G$ A& ?4 a7 X8 Q
e=*(S.top-1);) u3 B3 b2 ?1 S6 V7 l8 ?) [4 [: h
S.top--;
3 m; |, t4 ]" S) e% O return 0;
; B: c3 ~, o7 d}3 ]8 h% p$ Q2 v; u5 \
% }# b# L, v" Q; N& P2 }
char get_precede(char s,char c)
% H! ^2 j' H4 x) P3 Q! I0 u4 y, \{: T/ P8 Q8 u3 ~2 ~3 @
switch(s), I, Q1 W, C: s0 w
{: h# p& h" \( C$ _1 ~$ f
case '+': ) ]7 H( X5 j1 A) {9 c* e
case '-':( |+ y" G( z6 G6 `0 S* |
if(c=='+'||c=='-')1 _# e \7 G4 `: R3 n
return '>';' o) W# b4 s8 X+ C' S
else if(c=='*'||c=='/')
# E+ R, Q: R, H% B- R/ B return '<';
) u. ~% O6 S( _' _ else if(c=='(')
; o. f2 q% |+ Q5 d; q return '<';0 X$ O& T) C% e. Q$ T6 y" e
else if(c==')'). [4 U6 P% ^' P
return '>';0 ~; {! f: s5 d) e4 ?# s
else
E W: N) n' x, k7 J return '>';
6 k/ R6 m: l% S2 q& z; B( S: ] case '*':
, [, Q5 I5 M9 Q0 `6 L4 M case '/':9 V+ o+ K6 _: z J/ W" m# _
if(c=='+'||c=='-')
' H) `! X6 `8 p, n4 W3 E- b return '>';
# u8 E% N) P. G! S% x+ Q else if(c=='*'||c=='/')
6 Q8 }- _6 H7 {( S) j2 z, F return '>';
' y9 v* M& p+ m1 u: s" K: q# c else if(c=='(')9 K8 M+ K0 I) X/ F2 e( N" {8 H' j
return '<';
" {+ G( c! v4 Q" F, V+ Q# B else if(c==')'); _4 o7 X1 ?% Q) I: i! P; E
return '>';
: K1 g. \8 C% W( r3 p else
# |0 q. q+ g* `: W" t return '>';
5 p" u, a+ }1 ?8 a. l$ b/ o2 [ case '(':
! e- W2 a/ O2 t+ C9 } if(c=='+'||c=='-')9 ]* C6 `% b2 a: Y3 s$ A7 i
return '<';
$ I$ |" J7 i: B* T! R else if(c=='*'||c=='/')
9 y9 _ W( {$ ~8 E: W! W return '<';
! W' ^0 p3 ]0 _ else if(c=='(')
5 B. ]" I4 j+ q6 }+ d) _0 Q+ | return '<';
! _4 r; c4 x* f4 f' m else if(c==')')
$ n' B/ q8 d% ^, T* X% m return '=';
( z9 j' g' `* y; {% ~+ X else9 U+ P! X. Y0 T2 J- {9 m
return 'E';$ J, T8 ~& Y2 l, t
case ')':( i* q+ p/ s& j0 ?! {
if(c=='+'||c=='-')3 o2 F1 J7 v$ \2 e" J7 L- n% y+ r4 v
return '>';
3 n# k* `2 g5 V H4 Q! h: O4 Y, @ else if(c=='*'||c=='/')( h/ O' y4 E$ H
return '>';1 z& B4 R% ]6 ?- v
else if(c=='(')
7 a' n6 _4 Q, X; h7 S! E& }6 E return 'E';" }: o% _; @9 A& `& V) Z- ?4 L. T, _
else if(c==')')' F; F, i( u! ]. i+ j# h
return '>';
4 L J# ?4 T Q- b5 G t else% O/ F3 h# x. [: z( M5 m2 D
return '>';
7 G+ ^0 v5 v" H e- P( Z( _ case '#':
; _0 C& a }! K% y if(c=='+'||c=='-')+ `4 P9 J+ _5 E
return '<';% n6 O1 C5 J, M7 c) ^- G& `
else if(c=='*'||c=='/')
. z+ O2 K) N1 a0 e2 q return '<';
! b# A3 X" y& o: p7 V5 s) m2 P+ } else if(c=='(')# C1 [# p& w) a* w! w
return '<';4 m% m: p/ b: [7 [) M p) z
else if(c==')')
6 {. i5 a. [! a$ m return 'E';
0 ]8 N9 s( N# {+ c' @1 R else: l, b5 a3 X$ b8 I" d5 k
return '=';; L1 o3 j9 x/ a: O
default:
+ W6 P3 i- ]: G1 I% ~; S* a break;# N, a% }. V# q
}
% Y5 m2 Q( }1 ` return 0; / m) H8 h; ^! b# B
}! p1 s8 q L) z, N. k
C* [# I; A4 w' {$ k+ O6 W
int isOpr(char c)0 {5 p4 U1 x& W) u
{2 W- f) M4 Y4 i' ^
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')- V* C7 {& M% K! n6 q5 }4 A
return 0;
: N0 K* d5 G8 P) H# v# ^. h" J; e else
r- [: x& M5 a return 1;
, g: d8 w7 |1 |7 S}
0 P4 B$ _) d/ z9 @) p
' b+ l! [) j; W, S: ]float operate(float x, char opr, float y)
/ _7 l; Y! I* W) f% D; x" P{
, ~- c2 ^4 B( c! m" U float result;- G6 G# b% Z4 s" \+ x# H
switch (opr)
' y4 f6 W. g2 \9 g {
0 e4 d- V3 G6 r1 u4 A- p% [0 N case '+':
% K0 d: } Z: \3 A/ W result = x + y;
, E% x% t2 l3 h/ p4 |9 T2 J. I break;. W4 @+ v: M* j r: g
case '-': : Y0 z. o" h) K& V
result = x - y;- w0 A+ o% G$ e' z' M& x
break;5 d- H: v3 u2 k7 n; S* l
case '*': " o- T+ @! |1 i( \* C' y, ^
result = x * y;8 ~* ^) ^1 |- ~* R) X! C
break;4 ~1 e+ p# W. b& ^2 u* u8 k: h
case '/': . m* g& m" W* r/ D3 ^9 v
if (y == 0)8 j, y+ f) U; ~7 W$ [5 l
{
5 I2 a3 ]( a$ A) A. m printf("Divided by zero!\n");
7 w5 m! y3 `* ]4 z( Y! s, Z return 0;
, m, y! ]4 b/ M5 x* K( { }9 E0 e1 r* w2 x, [3 ^- u' I
else
1 i- f" V' d. Z0 _9 n) m {6 r$ n! S3 j% S
result = x / y;
$ N, c2 y q, e. i- [ break;* |, [0 E' B8 ? s1 i- S- Y
}
2 L# }3 j {7 E8 M; n default:
9 z+ w. d* n# P3 b4 W printf("Bad Input.\n"); " x) G2 _9 F" ^; _: O0 s! }1 g
return 0;
0 G: ]7 I8 _1 q& T8 ], P5 @' Y }% f4 y4 m/ @8 f
return result;
5 @0 A" V9 Y, s$ T$ Z3 B" }# ]* u} 1 t( j9 E6 l: B% R% R$ Q4 i. y
& r/ y2 f7 J I wfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
+ J& i" W9 a1 c1 v{4 R2 y) P' B/ K1 `& T9 _) A
Stack optr,opnd;1 N8 d! L1 F+ H/ d: V
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
* {5 g3 W' l) E) g- y1 ~ char c;
/ Y6 A5 X6 ]+ _; b$ d char buf[16];
D) D! g1 ]- H L2 s int i=0;
% j: c' `6 M8 H K4 K
6 m8 B1 j W$ b2 n InitStack(optr); /*用于寄存运算符*/0 E" u0 s/ o: \4 N# u6 ]
InitStack(opnd); /*用于寄存操作数和计算结果*/" d0 e3 C1 D1 U: l. U$ v
memset(buf,0,sizeof(buf));
$ H7 ?. Z. B; E; F( V% s$ } 7 g) ?- R1 x* _' T9 b$ g" i
printf("Enter your expression:");
& t5 c, J" ~1 u, V) K1 O! |. p
0 w) r5 ~0 M+ {/ k- s7 A opr_in.ch='#';0 e. ~1 k" J; G+ r, C
Push(optr,opr_in); /*'#'入栈*/2 X7 j+ Q6 c1 p
GetTop(optr,opr_top); P2 V1 g- h1 Z5 S e
c=getchar(); |+ Z6 F* g& x' g, b
while(c!='='||opr_top.ch!='#')
8 c, g) g+ h# ^ {
2 C# W+ G# w9 z if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/2 V1 \7 v" t+ R2 _( Q+ K/ D
{! Z0 n4 Y* D6 h; o
buf=c;: ^2 M" p R$ z- Q
i++;* @7 z' D' M: h5 j, [
c=getchar();: d: @: `; `; I8 q" m
} O( x( y( ]. i$ r1 O
else /*是运算符*/
- \. w3 M; h. Q5 p {
: H3 j& h0 U- `4 |6 i buf='\0';8 h& ~; Y5 m( V. W) k7 _# q
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
7 D2 m @/ B5 N* v9 p* F H$ U {
1 g5 | {: S W0 N M opn_in.data=(float)atof(buf);
; s0 `) _$ B: w# V# K Push(opnd,opn_in);
# O5 w7 J8 I% i8 ?, g! R" o, z$ G# ` printf("opnd入栈:[%f]\n",opn_in.data);
/ s) R4 t) S# q4 f5 j i=0;- z: Y" P4 N, Q- o6 q6 C# N! T
memset(buf,0,sizeof(buf));! S* D+ {4 \2 z: S% a+ L3 W2 w
}
2 k5 w; Y0 |: }" G! D) s; x opr_in.ch=c;
/ B4 Q- Y, n7 C# n+ v: F' v% ] switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
9 L+ D: S* _$ N {
3 Q N: m7 U# X) v3 [1 O0 | I case '<': /*优先级小于栈顶结点,则运算符入栈*/; \) ?+ H! |3 \! |
Push(optr,opr_in);
( A' P' J; P5 u7 A: ~ printf("optr入栈:[%c]\n",opr_in.ch);
- P# a9 v. u7 z; U% M6 G c=getchar();0 `( @# T8 V% Q$ O
break;0 k+ ]6 S4 N; ^ v$ Y. {
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
) Q9 I7 a7 K. C1 l2 q9 u" \: u Pop(optr,e);6 e1 e+ Y; E: z0 ~9 A- _! e, x! W0 \
printf("optr出栈:去掉括号\n");
1 H; f) c) _& b+ Z1 U9 C# T c=getchar();1 f8 F6 Z5 q/ Z7 c( ]' ^. X
break;
& }% h; K; h2 Y. ^7 v8 U case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/( a9 q3 F8 ^$ i6 m+ S% N
Pop(optr,opr_t);
" K0 L6 N& h0 z5 [ printf("optr出栈:[%c]\n",opr_t.ch);/ e) n5 I {. ~9 r+ C# J
if(Pop(opnd,b)<0)3 _8 j& B: Y& Q$ i/ N6 ]
{' h- p+ s: X0 W: S* q
printf("Bad Input!\n");
# m& |3 u! F* X0 n fflush(stdin);3 x* H% P5 n& c$ @5 g( d7 n
return -1;' l# B5 e1 m4 A# q& t3 a( [: j4 c
}4 k0 ]1 u; b" K D
printf("opnd出栈:[%f]\n",b.data);; S5 `% W/ M3 w$ C. N. Y
if(Pop(opnd,a)<0)! U* N1 ^7 C& R- Q' Y
{! G8 I0 Y5 Z* ?# o: o2 U; J+ g
printf("Bad Input!\n");2 K8 H+ y- G6 ?! x- O: e* L
fflush(stdin);+ h7 z4 m% b; l5 k5 {
return -1;% F2 d5 R& ~ @, T0 D
}
7 o) w5 l8 A& t0 J, S# `! a printf("opnd出栈:[%f]\n",a.data);0 Q4 a V( S' e2 x# b0 E+ ~
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/" B: I* l- p1 G: h- L: f% |
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
: G: c( _7 ~" [9 S! f* i2 Y8 p printf("结果入栈:[%f]\n",opn_tmp.data);
7 g% K* i7 z* N& j* [ break;
. B4 u) V; Z1 _2 R7 F }7 V1 ^3 S* ^0 _% J5 F7 L P8 ^
}
! ` R8 l0 V; D4 G" k% { GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 1 @4 X" ?1 x4 V& K, }
}
: l+ O% @7 f7 ^ C0 o GetTop(opnd,opn_tmp);
8 \, A! r' P9 f" h! O DestroyStack(optr);
$ o* U( p0 y7 a# V j: o4 l7 F ~ DestroyStack(opnd);
8 O) g/ u; u! m6 Q% P return opn_tmp.data;
H# o9 P+ C' S) y) E5 W}
: E( I) I& D. S1 ~! P$ ]' j* _$ ]8 E P
char *killzero(char *res,float result) l- J8 A. ?; p' z
{ p$ Q& ]4 r H) {9 [
int i;
* _+ D& l% p- B, p/ n" {
l( t6 G. w3 l, \' w1 [! [* [ sprintf(res,"%f",result);
# N8 L7 ?: v% Z' t, `, |8 F' M$ X i=(int)strlen(res)-1;
( p$ g9 _ t! x while(i&&res=='0')
9 F& r D/ `- I; M2 G {2 I' _4 R7 f: y/ h
res='\0';
' t# X8 ?. V, y3 i- l i--;9 i$ c2 X0 _# U5 ?
}
O7 E+ H6 I3 O- g0 f5 W if(res=='.')
- i: R* h0 J- d' |5 v/ [% S; [ res='\0';$ X, w3 h0 m B+ i1 G& _; N8 ]
return res;
' v- J/ j+ [# H' O$ g7 O9 m6 X}4 B' L4 F2 j" k# ~4 S
1 P, y/ k4 m# F3 a' Aint main()
; P. n1 S6 b) h$ y: Q; c% K: h+ I{
2 N3 T. Z/ h4 A; [ char ch;9 Y3 b" x( V K
char res[64];7 o0 K/ c9 d7 @& H0 _, O6 p
float result;
" I/ }; r4 x; R( ^3 z9 W while(1)
. F$ `9 M1 P$ N$ m& P { B1 E. l' j( i% t! O6 |" V& N
result=compute();
8 c3 Q* k( K9 j- [" A' e4 }4 n; Z printf("\nThe result is:%s\n",killzero(res,result));
& G2 X3 a$ ~1 C& J( k: H* s: v8 c+ I printf("Do you want to continue(y/n)?:") ;
9 h$ t: C- K4 r' c: I ch=getch();
) K5 b7 Z* v) _ putchar(ch);1 @6 r6 G! O& C0 J; }& f
if(ch=='n'||ch=='N')2 v: A0 y! }- W0 b
break;
e8 L( e1 f% n1 w else
& [' _/ c. @0 U5 w! A) g system("cls");7 ^2 q1 Z3 ^/ V2 e6 ]3 W
}
" T$ @: V1 }4 E, L: ^ return 0;: }* s7 U7 S; V$ F" s3 f$ s2 Y7 W- O
}
0 q' _2 F4 H. s# J: X9 C) W* z* A* P g
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|