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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.- x, _6 @/ v. U s* `% J) y
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=" q6 o4 Z" d# a7 e. R* h
/**************表达式计算器************/
1 y6 A4 h4 c# x: {! P#include <stdio.h>
1 a# s# T" e% E0 f0 K#include <stdlib.h>
4 x; f! T/ w/ D1 m8 d#include <string.h>; S. X- m; ?0 T# r9 L) P3 Y
#include <conio.h>: ]: s- B% Q1 X2 N
#include <malloc.h>7 l2 |- U) q! n
s( ^! n+ l5 V, q; I2 D
#define STACK_SIZE 100
% O4 E4 Q" a Z3 ~% [, s. }1 f. c#define APPEND_SIZE 10
& }) ^3 L* `1 y3 O
5 u. V- R" O2 T4 _struct SNode{! I- c' o+ Z3 K) Q, l# Q( S. D$ O
float data; /*存放操作数或者计算结果*/ E0 P, G w$ l
char ch; /*存放运算符*/
/ U. E9 f3 P4 S- {1 x% g2 A};2 u2 ~& J2 Q4 O/ Z9 N$ g7 z# d
: g0 ?7 I. a8 j: h
struct Stack{
B$ i/ y# D: F6 \; }: W SNode *top;8 ^; p3 c) K6 H! e
SNode *base;
: k, x2 X3 S$ O+ S. |1 l: a int size;
. G8 i0 a) H+ b& r9 q9 X, t! b4 g};1 M! c9 f6 A" |9 Y9 q" O
7 }, S, C. [- O: i4 }
/*栈操作函数*/* u {2 k O# _1 }
int InitStack(Stack &S); /*创建栈*/, Q) k0 K; I! d( Z( }9 T* D
int DestroyStack(Stack &S); /*销毁栈*/
7 s# W& ` x) [! N' ^int ClearStack(Stack &S); /*清空栈*/4 D4 H4 X- L/ C. R$ e2 r; M
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/1 o s: W; i, ]( F5 ~6 o& h
int Push(Stack &S,SNode e); /*将结点e压入栈*/& b' p: q) U9 R, \- k/ A Q
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ D+ m' H3 v P5 v0 U+ V# {
6 H5 ^7 }9 _# n5 G* d, @' D* P
/*表达式计算器相关函数*// H: k: [$ X0 M: e! P' R
char get_precede(char s,char c); /*判断运算符s和c的优先级*/* i& A {6 G) r
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
+ `0 n& V6 k: ]8 r& @5 pfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
. H4 y+ O: U* m9 s8 Q& A1 Ufloat compute(); /*表达式结算器主函数*/$ H z# ?- V' G* @, A
char *killzero(float result); /*去掉结果后面的0*/ 9 N. z' t0 n1 _% W! j l
9 \# u+ S/ J! G! A1 w+ e/ _int InitStack(Stack &S)( ], K" y; D9 C* j. C6 P
{3 X7 e6 u. {# Y& D) ~# p* _5 l2 X
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
, p1 w( |% g( P5 z X( B7 ?4 ~ if(S.base==NULL). X# q4 E) J7 r3 q' K+ F
{
( v& i& X3 S1 \& K' L7 n8 y) W printf("动态分配内存失败!");
$ s2 y, p6 m: J2 x D4 @ return -1;* h& v9 I9 L) c! S
}& ?, }+ n. ?1 ?) P3 C% j% v: g
S.top=S.base;9 V9 [0 J# z7 ~. T0 x% Q" S
S.size=STACK_SIZE;
" O6 E% x% v! k5 `! t return 0;
: `9 @; K; p. A$ d" ~4 J}
/ d. E) D1 H: w; X8 Q8 m, D
, u0 }( v' Z$ \( x3 d2 `int DestroyStack(Stack &S)
" L8 b& O6 U) O+ ]+ X3 ^{- L* v# K* f* f1 V
free(S.base);
' S$ T# b x1 h+ S4 S return 0;
* n m' A; D% `: m" r}7 V5 q& c# V: L7 R- o" f! c
) }9 T8 ~2 x; J& u+ I! s: T3 ?int ClearStack(Stack &S)! \/ [2 V$ o$ b8 ~
{; p" i* r% n0 q# E( q
S.top=S.base;
' C; Y( k) C& |4 D, V( [% A$ O return 0;
s9 V! w, [: ~) t0 E. Q}! m. m$ s* F5 r% r/ ]
) J6 V4 J2 B1 B, Vint GetTop(Stack S,SNode &e)
/ a5 h$ V+ Y; }4 e{
0 n& s" U: r! x if(S.top==S.base)
7 m5 Z* [) m$ D: t: y! [8 C! i! t {2 ~1 {. A2 G) s- X1 ~
printf("栈以为空!");
5 U: A4 a! r6 m+ ^- Y- f# Y2 w return -1;5 r2 ]0 W1 T" c5 R. f. t! ]
}6 b' J9 [( Q9 M' l0 \8 ^
e=*(S.top-1);
% ~3 M. q) w3 m, h$ a" T' ? return 0;2 x4 I' e* t2 r5 H5 R
}% k1 L) g' {' c4 {- q
$ v. U" x2 _ n
int Push(Stack &S,SNode e)/ A: ~ K# r7 J2 k. r) e
{
$ @& \/ B; v2 h; N if(S.top-S.base>=S.size)0 A! s+ L$ G. m7 @
{$ I4 U9 I0 M @4 V4 i$ w* R
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));* O$ I. V/ P/ L
if(S.base==NULL)# f1 r/ ]! U- N3 s8 l+ f1 d8 `
{# E- |, N, H- t1 w# W, r
printf("动态分配内存失败!");
$ e* n7 L0 |% y7 g return -1;9 E5 J) ^1 N# w3 k( C1 F
}
R: }+ W7 m2 C% _ S.top=S.base+S.size;
! M$ X8 F9 P. n+ d S.size+=APPEND_SIZE;
5 e! d& A2 e1 u }( y6 |9 {+ ?' N6 @1 t# D
*S.top=e;
* ^5 x, k! j, k9 n8 U) x- i S.top++;& ^1 J0 x, k7 y( k' B" d& ~4 W
return 0;. [3 `; C( \, v
}" a3 `8 V. T9 n! H2 D3 k& W- b
( G; t' c" c/ f3 ]! {int Pop(Stack &S,SNode &e)* g" d* P+ p; E
{
' v# z2 l# D2 C- Z$ |) _ if(S.top==S.base)& |% O; j( }, W# J8 h
{9 F7 x) R: A8 q7 g8 C0 h2 M
printf("栈为空!");
: B. D8 ^7 t: |0 Z( Q. N1 o return -1;2 ]+ c! p+ t" z) O% h" `0 f
}
2 h: ?' K! c6 W% R8 Z) S9 ~! x e=*(S.top-1);; g0 ]) \: l8 ^- x+ v
S.top--;. |/ `9 p7 H: O8 Q
return 0;
% P5 n8 M( `4 C7 [}0 _4 G9 `5 n% Q# F1 F/ @, u
: a. `4 p3 D: O* T1 g _' y
char get_precede(char s,char c)
z4 y s5 h( u& |6 {! ]{) f; G1 J3 O0 p" P3 |( \' ?# a
switch(s)3 Z0 _+ D( {3 B1 ^
{
+ i! u2 _) }; A! \ case '+': F6 t7 ?2 s% @( S) l- r& q
case '-':
$ P( ^& s$ O, f3 @+ K; E- M; C if(c=='+'||c=='-')% \& Y% j2 g6 _& H# C" o
return '>'; f6 N9 L+ h* q- j" Z$ N; Z7 T1 N |
else if(c=='*'||c=='/')
6 ?6 j" c+ r9 u! a6 W/ A return '<';; \* S* b! u$ ?" [1 x$ j( T
else if(c=='(')
. ` u: B- }# V& Y1 Y return '<';# d: b1 A( l- l$ @! ?! B4 O+ A* r
else if(c==')')) y# f. Z4 [3 Y1 g6 h
return '>';
. o0 }5 Z" T# r" u; E2 y: {8 | else
, r" k9 s- c _/ T0 f: |+ d return '>';4 B' X' H& t6 B& p: y8 @
case '*':: e8 d/ @# N2 c/ h, p' v
case '/':# n: Z5 i. {, {9 W
if(c=='+'||c=='-')( _' g0 p! s1 z; F& z: y2 y- K0 |' b8 ^
return '>';
1 Z& Z* x6 [7 b" v8 o else if(c=='*'||c=='/'): O; W9 I1 m2 W% V( w7 }0 ~
return '>';
( w: b% S1 W& t5 n7 { else if(c=='(')
& Y2 n" e. H2 P* H. ~: r return '<';" O$ Q# l" E" Y! X g
else if(c==')')
, ]" O2 Y! r" U% Y return '>';$ S# ]4 C4 J2 a# ^
else/ o# P. _4 c. {$ l5 |% k
return '>';
2 `' F, h# ?; V4 N+ X case '(':2 D( m2 n* p/ |, O' O0 P9 N: ^
if(c=='+'||c=='-')- b" S, y6 i" e. R
return '<';$ U: p1 {! e& d1 y3 \
else if(c=='*'||c=='/')
$ C E8 @ @ `# g& k return '<';1 G# h9 k; Z3 l1 L6 I( {
else if(c=='(')/ o% N3 b0 ~& C: o8 {9 k) o
return '<';
) u5 E# v" D' Q$ O) X, h else if(c==')')8 f1 w- @+ H7 U; U, M# N2 r
return '=';
( C% C! d- R. J | else
( e( t- R; _1 q1 `2 p0 x. e! ~ a) S% Z return 'E';$ l) W1 D* J9 ~0 k/ H; Z( d$ w
case ')':( p$ U6 u1 w, ?; F( V6 Q! C5 O
if(c=='+'||c=='-')4 g( o k% k2 k7 u. `+ X. z
return '>';
+ o2 `& n4 T B8 l) Q else if(c=='*'||c=='/')
% A' }' L3 o6 S: e. r/ ?; j return '>';
' N! k7 S$ P3 X4 J else if(c=='(')
2 \9 J2 M I2 z( A V/ x/ n7 o return 'E';& U8 C" O2 T, b% j& n. x
else if(c==')')1 ]' R# p0 F2 | R' G6 N/ G
return '>';+ \4 u2 d* F" \( ]! u8 {& U3 a
else
$ W* g5 x# T1 k7 C( E return '>';5 x6 v9 z8 C1 d
case '#':
* ]) `; }2 W5 f/ ` n if(c=='+'||c=='-')
+ r5 _; L( R0 D2 h% n( B' R return '<';& R7 m g. O9 e- c0 p9 S
else if(c=='*'||c=='/')
9 O+ N8 }1 e) w5 x. e0 N" q7 ~ return '<';% ]8 ~3 b( A4 S
else if(c=='(')7 s% f* _( e; f. c3 S& z2 I
return '<';0 ~) `4 Q$ P$ o* X3 Y0 `, i9 S
else if(c==')')
$ U' ]1 `, N% `, A return 'E';
, S; l/ A) H* ]$ L9 D3 B: o( k else
) s- H! A ? i2 ~ return '=';
4 f) U" |) {& l" b# q) S5 u default:
. t0 Q6 h" i7 Z3 U2 M; u$ A break;# {5 v' P- i+ u5 R$ S& G3 i# r
}# A) R' k( X z, i
return 0; ! f) W5 M! T8 u7 f! D9 D# S- O6 T
}
3 Z; f; E% E" c3 ~4 {: j
: z _3 c1 o- Y, |: Iint isOpr(char c): }6 ]6 N: z4 a' A
{: {. w$ I- Z9 Z* Y
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')! a/ ]( \9 F; b a: H
return 0;3 ?8 a9 G$ O1 ^; D: f
else
+ P; @2 W3 j- Z* G2 O. d, I return 1;
9 c3 G- E8 Y& V. C' Z}
0 l- \: o! m# A! V0 [& ?
# e0 h$ f8 ^8 x- n0 Xfloat operate(float x, char opr, float y), p2 c' S$ {8 p+ p6 u/ C) m. R; X% A
{
. i2 i( Z9 k. ^ float result; y8 C& U9 K3 Q' ^
switch (opr)
$ q7 x* S" _9 C- @) o0 Y" M! c {
) t: c+ @% T3 d6 I$ g: d2 d case '+':
( x+ m. ~% n- t& x G- W- r8 h) Q result = x + y;( }! D6 z& \0 _' W* X, a
break;
5 ?; N9 g& f, r. V1 |5 z0 @' z case '-':
0 H5 m$ w$ u9 o8 Q result = x - y;
8 `' ? L8 l: T2 d6 m# W1 d break;( H6 C$ G6 t4 n* P7 U, C
case '*':
6 F8 Z4 ?* W" Q6 M- T' e result = x * y;4 j! Y2 F j) g3 _. |# D
break;
" Z- t, P% s1 a2 ]# d case '/':
6 i Z+ E! i% j* e& I; n* {/ |# ? if (y == 0)1 r" ~8 r6 T$ L, m$ @/ M
{" Q# d9 w/ ?- {, ?
printf("Divided by zero!\n");
I6 `. e* d/ e: \0 d; a" } return 0;
& s- ~! Y2 Y& `2 F( l2 O }
! A1 Y* F2 F/ d& y A: D4 L8 A! K else
- @8 C* s a6 w% g1 P+ C {
/ Z Q% h0 C X$ m0 n# }' k8 o result = x / y;3 S9 s0 T2 L4 O0 N0 q
break;
/ A3 v4 r+ ~# g" ?$ f7 ? c+ w }2 H* w, {, |$ z" K% `7 k3 l
default:
% X; O6 q5 i8 V# T6 h printf("Bad Input.\n");
% u, T! ]1 ?4 v- K return 0;
5 v% P8 V' P# q3 U( V: ]) d2 E }' ~. @# ?& Q% W% R# v. p5 ]
return result;* G2 ?0 ^7 \. e- X/ f5 X) u% y. r- [! A
} % s" C1 S" }9 Y$ S, a" Z1 y; U' k
4 R2 O7 C2 R+ h) D! b
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/% f1 u2 b4 @" t( w% z
{
8 w3 ~* Y6 O* o8 | Stack optr,opnd;: K4 q2 z- y# z8 j
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
4 x8 ~) E# ?" Q char c;
' Q& B. B# `. { char buf[16];
; e b! K6 ^" I9 |0 T/ m int i=0;
4 C7 o( o0 _# }2 L. y# }
; ~1 v- R3 u8 h7 T+ h: n+ F$ B InitStack(optr); /*用于寄存运算符*/4 c, }+ s) b, C5 |/ g* D! R
InitStack(opnd); /*用于寄存操作数和计算结果*/; _; v! t) U2 o" z6 P2 w
memset(buf,0,sizeof(buf));
4 J) @+ c# x) C, s _- {$ f+ ?& x
2 C, p% D$ N+ @2 u0 ?& u- @ printf("Enter your expression:");
) o7 ]0 A1 C" X8 K8 V 0 ]( k; |- E* n3 J% c
opr_in.ch='#';- U# {3 ~6 g) d; M
Push(optr,opr_in); /*'#'入栈*/$ C$ H$ d+ z, ?0 C4 c( q
GetTop(optr,opr_top);
( `) a9 {4 [4 Q: b$ n c=getchar();# p I# g8 G2 U# H* Y( \1 C* |
while(c!='='||opr_top.ch!='#')
4 b, K3 b* ~6 k7 R. P {9 M6 t; ?* D8 E
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
' s P6 ]' W8 N" K" `9 i {
) ^, R6 R/ l: j0 N" }0 {+ K buf=c;
( {9 u' m7 m# z$ T* w+ D" F i++;$ |2 J- L8 {* n' Q i
c=getchar();9 O; d; ~8 P7 _
}
7 s" u. [8 f6 h& K else /*是运算符*/4 ], i0 S( _5 C( g
{
$ _: n) O, l5 d- O; n* y4 M buf='\0';
* Q, t( W- W4 X" T$ T8 G if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
4 z' N, Q5 u3 N8 T: y& {- D {
& J `7 a. K. ~% c( c- f( D opn_in.data=(float)atof(buf);( ?8 l7 [) i, L8 a
Push(opnd,opn_in);
+ ?1 F, m9 \& o6 U, L1 I* h printf("opnd入栈:[%f]\n",opn_in.data);6 n$ P6 g2 B Q0 u! C q& b
i=0;5 S6 T7 m) U& U
memset(buf,0,sizeof(buf));4 ^4 C: }2 {0 X+ a o# `
}9 p" R6 r H8 }0 ^/ C9 k
opr_in.ch=c;
0 T) h1 y: p. E4 _* @+ B switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/( ~* n7 n! R* y, N) u
{
9 K5 K; N8 ~3 O- o case '<': /*优先级小于栈顶结点,则运算符入栈*/8 X0 }% j1 u8 r8 p/ d
Push(optr,opr_in);
. V) @! Z; w9 I: d( v printf("optr入栈:[%c]\n",opr_in.ch);% b3 K- p" r6 b
c=getchar();
7 p7 [: [+ F: n8 C7 a break;
- u) h. X/ M; a5 s case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/8 F" }9 b) ]& d6 t: l* x7 A
Pop(optr,e);" {2 P# }$ i+ Z0 i( T! K; e) ^+ d4 T0 u
printf("optr出栈:去掉括号\n");
* F2 c# x: e* a; @" K$ X+ @ c=getchar();+ v& {2 ]( q" K
break;6 E/ P: N w# z5 E
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*// k: a2 n; @6 C
Pop(optr,opr_t);, t' c# S; K$ }% ?
printf("optr出栈:[%c]\n",opr_t.ch);7 k, r2 A. ]: ]7 V4 F! E5 E
if(Pop(opnd,b)<0)
0 i- L! p' U6 r/ w7 R {
/ \( A; W2 f5 e; `5 e printf("Bad Input!\n");1 E6 H: k% t* t8 p" f
fflush(stdin);
( `# D5 |: O2 p& R- | return -1;, G" [" y2 }" D' I
}
/ Q- X N: ]- L; K8 W printf("opnd出栈:[%f]\n",b.data);1 J2 \: ~4 D2 ?# B; U1 ~% i1 t4 R
if(Pop(opnd,a)<0)
. S- @! e: Y: t2 \ {7 b q5 |7 u, ^/ c6 d7 Y% u8 F! I
printf("Bad Input!\n");
# C! ]: r# R2 w5 \) a fflush(stdin);
; [ x$ s6 b& S# M6 e, j( ] return -1;4 y# V- z; F' w6 Z7 M3 N6 B2 t
}
- @/ P" L6 L5 }3 v3 B6 Q* L" H! ` printf("opnd出栈:[%f]\n",a.data);1 t \. U# E+ ?& p
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
2 j4 p/ `. a8 w& N M' F& | Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
3 p0 f( K3 e/ f5 z# O: _ printf("结果入栈:[%f]\n",opn_tmp.data);
3 Z' G( N2 o9 f5 @ break;; D$ |% S( W* H# x% H4 K2 o, T
}
3 u7 g! X1 L6 V( m9 \* N6 T }
" E" h8 }, [1 u$ q, y9 e GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
6 h# K5 |. o+ x7 V }
6 N& P' _+ b5 V1 F GetTop(opnd,opn_tmp);( L4 S, {3 R6 s* R5 k
DestroyStack(optr);
% H, \8 W. h/ V; M$ C: d DestroyStack(opnd);
( x& J2 z1 Q/ d4 F4 ]; [7 v return opn_tmp.data;
$ d9 e" x: v1 o" w N& v; y}" j; K! j* ~- c3 \+ Z+ X @+ }& p
6 e# d" _9 { L8 h" I) |char *killzero(char *res,float result)5 z. z* V; x# [2 V) P
{
! @7 N) l7 {$ H+ }* o/ E1 K int i;
% E" J, |5 p% z6 A0 f
" b! W4 a; h& v/ J sprintf(res,"%f",result);
1 l: ?4 {3 o& p \7 l7 R2 I i=(int)strlen(res)-1;
/ b' ^5 h$ T2 c+ h" s8 E. j while(i&&res=='0')3 Q% s' S1 E1 o* D
{: H1 Y4 H7 o2 d Z3 l
res='\0';9 ?8 f- W9 X, [* W9 d1 g5 D% }
i--;% ]1 S# P* g% m: b! P* f
}
$ Z2 P* a2 m2 u& s if(res=='.')
& s# J: |; t' F# w4 e res='\0';# t1 i5 F9 K, Q3 W# r# K1 O0 f
return res;
# A$ P. [+ n& [1 P; L, b) I. f; |4 N}0 p5 F: X0 w8 F; K2 v0 n1 K7 O
, ^4 u* i$ W* ?) p* t1 @: [" \3 | xint main()
0 J/ s/ I& V# S; W% T) ]0 m. V{
: `+ @4 l1 K6 h/ T6 m6 } char ch;2 H- z, ^( h! L2 n
char res[64];8 @, A/ |- \1 [, z# ?3 b& f
float result;1 R( _. d! m6 P! J, z2 e
while(1)
) u3 w p( o$ D' B {
9 q3 P1 o% N* _6 j9 {( E z( Q J result=compute();9 P9 {, C/ ~! @: D+ R% ?% v
printf("\nThe result is:%s\n",killzero(res,result));7 c$ P8 s9 I; f# W8 H& q
printf("Do you want to continue(y/n)?:") ;
0 q) h1 q1 u7 F3 d4 m6 u ch=getch();5 T; _8 R- }# N1 D7 U) u; X
putchar(ch);
" t6 C/ x' C+ g* Z) M9 U% s% T if(ch=='n'||ch=='N')
+ p1 e; v+ E8 R. t, z break;3 v7 m" i t+ g
else
4 c2 A6 W% _/ b4 w9 a/ F& R2 ~7 g system("cls");, \0 X$ H9 H: Z( F: H ^
}) J7 h' Y/ k6 ?! B* U4 U) V
return 0;
6 ^4 m% t+ U" M& y3 q* w: W} Z9 I+ a# U% w0 z2 u& D
% ~& P5 O& ]' [
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|