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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
]! H- K9 M! n& Q: Z: S程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=. G; D6 x, z, |" n8 \( {
/**************表达式计算器************/9 O. E5 D! m8 d! Y2 P( S
#include <stdio.h>
. H4 ^; ?4 L9 J: z5 Q#include <stdlib.h>/ u! q6 N: Z9 f! S, e6 V/ p6 {1 Z
#include <string.h>
* _" {: R" v' i, d/ [#include <conio.h>
+ N: v" G* R- D4 z B7 A#include <malloc.h>
$ \6 H+ O" n3 l4 \& z, ]
2 |. k4 M5 H5 v7 h' N; L! l#define STACK_SIZE 100: A# B5 x$ t+ F* s1 Y
#define APPEND_SIZE 10
# Z. \. \+ d( g, k. m
7 R4 X& n1 I; {1 [, t+ N: {struct SNode{
/ x2 o) B, H3 p1 e+ J% X. i/ m float data; /*存放操作数或者计算结果*/
& `* i- b0 J# @/ }' o char ch; /*存放运算符*/0 N9 y+ X* M" M$ r! F% t( @+ Z0 A
};" I: R4 \! U$ V6 x! k( ~1 _1 @
1 [: A% R+ x6 n: ~- f6 _
struct Stack{
. l4 D H! V6 H) q$ j SNode *top;
h) A6 w% j; j3 Y6 D SNode *base;
) \% C. p- M4 z9 _. ? int size;: l* }' y4 C9 t9 k
};
! q- @6 _" z& l8 s& y0 ?: k9 Z# o3 r5 ^+ ?% a4 u
/*栈操作函数*/8 z% B+ Q8 ^5 x5 X5 n2 M
int InitStack(Stack &S); /*创建栈*/
! c1 _" B6 ?; O }, P hint DestroyStack(Stack &S); /*销毁栈*/
9 G; g* }2 R5 w |% Nint ClearStack(Stack &S); /*清空栈*/
. s7 z8 P$ j1 C2 m% I cint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
/ n$ F$ k4 t+ d' Eint Push(Stack &S,SNode e); /*将结点e压入栈*/# b' T0 b. |2 F- }" u
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
+ H( _/ u! d. c! A& O& P4 p+ B4 {+ m2 q
/*表达式计算器相关函数*/
U# k# q/ n, E6 z5 Q/ bchar get_precede(char s,char c); /*判断运算符s和c的优先级*/: ^0 W w* q& P4 p7 p0 b
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
% p: ?* H6 N/ _" _6 q" _float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
. v+ [7 e1 ?2 hfloat compute(); /*表达式结算器主函数*// e/ e z8 K9 J2 ?) ?
char *killzero(float result); /*去掉结果后面的0*/
8 ~4 J9 f: w) Y. x$ I
7 }% D( K+ W$ Gint InitStack(Stack &S): S* n. d* g5 {
{
9 |3 A4 |- l" H$ r! _ S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));) [# _* G) m# u1 {0 R- C5 l# n
if(S.base==NULL)
9 J2 L( k0 b! \- ^% K+ T {
- C) ?* z2 a S* | printf("动态分配内存失败!");/ S8 G h* Q" }
return -1;
0 L/ q; w) X( ~4 ?, j% p }1 A* |0 M8 K/ n: p
S.top=S.base;, \& G7 D% Q( d" k: o* j: }* Z
S.size=STACK_SIZE;# } b. U8 F* j8 |
return 0;
' E4 o3 X3 }8 t- U5 T, Z# G}, d6 R/ M+ K" L; O, w6 c; I
) R Z1 G" ]: O% `/ aint DestroyStack(Stack &S). W: U Y% D3 x6 N; T
{# Y9 j; s) j! Z2 U% X5 J
free(S.base);
& K7 _# m4 `% Q! H2 O3 H( B return 0;: i, R! l# V3 ]4 h9 l+ R- t4 r3 Y U2 n
}) ?& B, Y0 }5 Q
- u' F9 d; x' C4 m0 E0 N2 ? M+ ~
int ClearStack(Stack &S)+ N7 ?. p' k4 H, ^3 I3 G8 n9 s
{
6 M! r; H" E' Y7 z9 q S.top=S.base;
; T9 k/ T$ D' j& q- C return 0;
, y- ]$ L, O6 H- c4 N# u; A$ e}
" E% U4 R' W' h4 R
& n2 P' l, W8 Hint GetTop(Stack S,SNode &e)
8 P; K' e. `7 }{/ f6 i) K4 @0 z* V* J
if(S.top==S.base)
2 ~, U" k r; @+ S {
9 J4 h6 g" s% S/ M( g" Y2 q printf("栈以为空!");8 ?: h& ^: V/ ]7 J. ]
return -1;- M2 I8 k' l& o2 C! W+ }# F% K
}
5 k9 ?2 f# ^- K$ x' R e=*(S.top-1);
: z" F. d% D3 g6 y5 L5 D return 0;. t6 V9 c! j: | R+ n2 ]' t6 }9 f
}3 X2 Z* r K# _; d$ i; S
2 M/ E) b8 D" o, n' _# n Sint Push(Stack &S,SNode e)$ x0 v4 Q3 x9 D
{0 n- Q7 ?0 T$ N( r7 V/ \$ Q
if(S.top-S.base>=S.size)
+ X$ v, \, H4 s' q. W8 A+ ]# j, g {
- H9 ~; H1 e) e# Z+ x( v v- m S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));% L" }# `5 r5 R4 p. U. Z n
if(S.base==NULL)( f# G* `8 h8 G. o* G' h
{0 P: e2 V" e6 z5 z$ ~4 a
printf("动态分配内存失败!");0 N9 V, ~1 n# L; ?% g
return -1;
: i% U# ~4 j* o }
5 E4 B8 M/ [6 x0 }- I# x7 ?: D6 r0 R$ x S.top=S.base+S.size;/ B3 @7 [# i5 R- v. K% U1 [" ?
S.size+=APPEND_SIZE;! H' I7 X7 a( H9 O! g
}5 L* Q# b4 O& E: q" ]
*S.top=e;) W' R' V: }" A2 E* A: K8 I
S.top++;( v/ ]0 r" {! o1 C7 I' `+ B. z2 l
return 0;( v# V2 @6 P/ }( A7 W3 I( K+ B
}
$ x2 w9 ]* Y( c- B5 h6 y
* v( w. o9 b) U$ o& r: lint Pop(Stack &S,SNode &e)7 ^8 K J6 Q3 `
{
) v7 K. j+ u/ u2 A if(S.top==S.base)0 H4 Q/ y) [% r# u8 \7 m5 K
{
- ?* S- t: K# }: J( E. ?- F printf("栈为空!");% a/ n- i: D0 y& x, }! J% L
return -1;
: p% I2 m! y# d( x8 v { }( `3 d; h$ c1 z( k
e=*(S.top-1);
; V. `$ E* m' k2 n5 z9 X9 _! L" G S.top--;0 R6 H* S2 v( a% h
return 0;
. G* ~' m2 Q( i}% `' ~. _: }% m. s
8 S3 @( L8 Y s2 @
char get_precede(char s,char c)3 e/ y* N' B1 a6 G8 \0 k
{
8 b. i- u3 J" {; `( y( p switch(s)
$ B8 E; a8 E& U# ~# [+ h {( K) w: w# B- r9 ^7 [6 m
case '+': / m3 C$ D, O" o' d" u d. v
case '-':
6 f( c% T$ h( y/ |8 T. y! d% i1 _ if(c=='+'||c=='-')/ Q/ N& X2 [; d" T7 m' F) _
return '>';
2 ]. A1 I8 X1 p S2 M2 }7 B& ^3 ^ else if(c=='*'||c=='/')6 W3 x+ L p; g
return '<';0 f) N. M% x3 D* m6 s, v6 L
else if(c=='(')6 R B2 I0 p. z" u: [* [
return '<';
* e: N$ R8 n1 v" [7 m4 g1 [" t else if(c==')')4 ^' h, d) o+ {$ L0 }) Y4 [
return '>';
4 M2 V& Q, Y2 l; K else ) p- S& O5 N2 f
return '>';( w5 a. u* n) @% ^" }/ {+ Q
case '*':
$ n" {7 e+ |( G5 L- I5 _: s case '/':
" ~+ o* {7 \: V% |$ B% E5 U if(c=='+'||c=='-')0 R, q) F( ^8 ~4 ]
return '>';3 j5 q* ? ?# m8 p) h( n# T
else if(c=='*'||c=='/')8 R! E9 P2 V1 N4 E
return '>';) d% A8 b, f* u) Q+ [
else if(c=='('): I a2 ~. H) \$ B2 W
return '<';
9 `# l8 Y2 C6 L9 A else if(c==')')
& `! J" K ^7 Q return '>';
: W) k# {$ x7 [/ N* Z else9 ~0 b7 r/ T T5 N$ h: g! W1 b
return '>';3 R- r3 @6 G9 q8 \8 `; I- S# S
case '(':
6 n" m4 R! V% x, Y( t if(c=='+'||c=='-')& R1 h( Z8 J" I' @& ?3 j" x
return '<';
" ~. ]- e( x/ u' ~ else if(c=='*'||c=='/')
$ o( r+ o7 G9 u8 K. \ return '<'; Y5 N7 I! x8 b: Z9 g
else if(c=='(')+ z/ o0 W0 b, s
return '<';
+ f# [* N( m0 Q k$ g0 u5 l! K% T: R else if(c==')')
8 m1 W' n+ l$ u8 O return '=';
4 d6 R# `! j1 J+ q& F else9 T, R/ r0 B. N
return 'E';
; \) |8 o ?* v; D* U6 r case ')':8 q4 Z$ m( M" b6 ]; Y! L" g0 r
if(c=='+'||c=='-')5 u- D6 B4 B/ o. W
return '>';
( B9 S: m+ M* q* E; g else if(c=='*'||c=='/')
0 l& {' x! L7 ?* p5 f return '>';4 Y( b. c: _* \ K4 g5 P7 G9 h
else if(c=='(')% f. w* D' ]' C
return 'E';
0 r0 ]: I4 J, t5 g else if(c==')')4 k& z4 a, r9 U9 m* ^6 R) k
return '>';! h/ @" p* r8 J- j
else
: c6 o" N! y- Y$ G return '>';' ?9 T3 Z2 H: s
case '#':
- @- A9 n) |, y2 q+ Y& X" r; m if(c=='+'||c=='-')
, t7 p/ j7 g* h4 ] return '<';
8 k' ]0 C; ]: n; H3 V% f else if(c=='*'||c=='/')$ v5 C# L+ J0 b6 y2 ^) D- [$ g
return '<';0 u6 Z% Z7 L2 f6 u/ f
else if(c=='(')
2 j$ ]& E& v6 c return '<';! ?3 k3 A% a3 \3 K" X
else if(c==')')
4 M: H5 t: i) E return 'E';6 {& |) y9 r, |1 L
else2 R, C; G. X! K7 ^( r# g( f
return '=';; M; L+ G3 E- o& ~/ t) Q8 \2 m
default:( _9 @% S9 N9 F. @# @' u
break;1 Y" Q+ r8 `7 Q% s
}" Y2 r% q- l8 g# U
return 0;
" L+ O' X" e, V}/ T2 L+ q) ]" C, c3 v- x9 \
+ ?0 b T- g6 x; \% v6 u U( }
int isOpr(char c)& x5 D W) s7 o0 s' E7 M
{
5 q! i% k, v0 X+ b+ G9 Q: [2 w if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')9 c, C' [5 P K' J8 G, a( p& S) |
return 0;
8 } } A# l9 [2 b# A6 K else ' I) Z2 Z1 A$ U9 R7 c6 u1 w
return 1;
$ {$ I* S# G: |' J0 B}1 s2 W4 T1 j$ n% H5 h( x( x+ ?
' l# F' P) Y! g0 qfloat operate(float x, char opr, float y)4 p& B5 e( m9 {1 y
{ o$ D8 Z: j# R5 ?3 w G
float result;
5 k; \6 o1 @0 b# j switch (opr)3 ? Q, s, q: @4 b! K
{
9 Z! P* W% J/ ? case '+':
7 {1 n& \( @: Z7 N0 B g! { result = x + y;4 g- C( Q9 S. [
break;
+ x# c* f% N" {: @ ^8 d case '-':
, h+ S6 I) L* o result = x - y;! T0 m, a6 y5 g" T; ~: x S
break;2 f- u ^3 j7 y
case '*': - G/ a. y; I. M0 j$ o% ~
result = x * y;$ o- w6 a+ X$ K3 \, L$ \
break;" ~, `& C* I+ L5 y/ N* r* V
case '/':
' a2 L. Z% A, ~* H if (y == 0)
. ~( k. o `7 @, c% r- [ {- x2 t; {. B+ Y6 ?
printf("Divided by zero!\n");, ]% A8 z0 _9 [* I2 K6 ]8 X
return 0;
& p! n& B$ Y( X6 g" U1 E }
2 h% R2 O. p. j. s0 M1 A$ ? G else' T- n( M0 E# s% u) H9 r! l) N% ]+ j
{
% e" _1 I- }7 g( w4 j result = x / y;. u5 T6 i$ `) B* B) i7 a* W! s
break;: G5 h" _% Y% l1 h4 Q1 @5 o- v
}0 J9 A/ ~- E1 j& C
default:
`3 W l6 m5 n4 t; V printf("Bad Input.\n"); 9 Z5 ^. k" m3 f5 g, Z2 E$ j% F
return 0;2 Q5 E: N* s% {5 o7 o
}! B5 P4 u8 S) F; i) v/ Q) |
return result;$ K3 ^2 r/ y% W9 e# P, d/ E
}
; w$ @ n! S4 o V/ M) q) N( u% C2 L k+ _5 A r7 S
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
" u: i7 J$ X( L9 [7 Y8 Q8 C" U{9 O& R+ |# i* ]2 F) `
Stack optr,opnd;
1 m) H4 [% x" V3 m struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t; F( x7 R8 q4 _( H: x9 T v
char c;* |' O( v% {! P" Y' h& q
char buf[16];
$ d: N+ G, t8 m2 M* M7 x int i=0;
# ^* @- l4 o2 K4 @* [ P 7 A+ `9 Q4 v2 M" t8 h. R4 F$ d3 t
InitStack(optr); /*用于寄存运算符*/2 l4 V' D) D, z2 R! K' ^
InitStack(opnd); /*用于寄存操作数和计算结果*/+ Y: Z* H, o9 o& x! Z
memset(buf,0,sizeof(buf));; L# N/ E6 ~( {, o
$ a7 `1 \& A6 h% ^" O% p printf("Enter your expression:");# a/ M, F! l4 C# h) t
2 j/ m* l8 ]7 K/ @' v# u6 n( K
opr_in.ch='#'; g @( L. p/ Z6 q }& C. ~' P* X
Push(optr,opr_in); /*'#'入栈*/" R2 Z# ]3 d) |6 b: U( V
GetTop(optr,opr_top);( t; y9 |3 ?$ l: y
c=getchar();4 u9 J, m6 J# ]$ d; P' |/ r
while(c!='='||opr_top.ch!='#'), }* c. l/ v! a
{) d4 w. h" W8 l- J; n9 k- b: p6 @
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/* k$ B$ J+ \! S4 r
{. u2 B$ T/ K8 W K
buf=c;
: x; v% d5 a0 [3 B1 t- [3 N j i++;
! _* [ b3 n( Y: O E c=getchar();
2 O( @ A5 b, _ }
& C, U2 D# E' Q3 E$ N1 j5 v' ^0 E else /*是运算符*/7 u1 O; F; v, J/ w( d/ {! ]! ?
{
2 n- \. l- Q& \: [! @ buf='\0';
H6 T& I, q* j$ V- T if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
# j3 q4 }# d6 ~$ I# X5 w {
2 t& v' M: C6 z5 E opn_in.data=(float)atof(buf);
. c* p# Z y8 K Push(opnd,opn_in);
1 L: c: }$ D3 [$ k printf("opnd入栈:[%f]\n",opn_in.data);
4 p$ {+ M% x* k% t5 b) V i=0;% ?! t# H2 u' c' D/ u( y0 I& k( N
memset(buf,0,sizeof(buf));% y9 y# S- g: w; D, B) N# n7 p
}( Y N! \ {; s
opr_in.ch=c;
+ {, P, Z' M. f4 ~3 o+ H+ v switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
$ A& U% K. N/ t' O' f {
, x9 r& p5 M9 M( f, }# Q case '<': /*优先级小于栈顶结点,则运算符入栈*/, b/ `8 Q0 C7 B" X9 r+ a
Push(optr,opr_in);/ o! N, j$ h ^ I1 P
printf("optr入栈:[%c]\n",opr_in.ch);! t9 V: S0 n, N3 h" ], G, b
c=getchar();
/ g; S! Y2 Z% @; a break;( i& L7 g, K- D4 U; w/ L
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
! k5 z8 m1 H5 s5 ?0 f# g+ y Pop(optr,e);. I3 K0 d" {# ?2 d
printf("optr出栈:去掉括号\n");8 f9 K& y7 @) S, X
c=getchar();$ Z! U- h0 s+ L
break;, I/ f$ o! S1 }5 v: U
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/# h2 h( I: F* `
Pop(optr,opr_t);
' w: [0 ~* R9 N7 y4 B; u$ A& E printf("optr出栈:[%c]\n",opr_t.ch);
: A/ ` g! d3 _4 H3 P+ \ if(Pop(opnd,b)<0)
# S7 k" A" l; E+ k {3 G5 t( p( g, v$ m8 A3 k: [/ a3 H
printf("Bad Input!\n");+ s# O5 s$ o+ q
fflush(stdin);) T$ C1 n# E3 E! S
return -1;
* K' q# I* w$ K5 H' b }# _* B4 i6 `/ f& S
printf("opnd出栈:[%f]\n",b.data);
3 B( p e( K) T if(Pop(opnd,a)<0)
8 `+ Z' z V. ~4 P; ^; E2 G {4 W) G8 _- u, j* n; u. `2 a# V, q
printf("Bad Input!\n");
. `/ _" @0 e$ z4 N+ S5 g( t fflush(stdin);! X# [) v/ [1 |- W5 y9 S+ O* A
return -1;! |" o, |! f+ |' j5 B9 z
}
, E- `& C4 J( k printf("opnd出栈:[%f]\n",a.data);9 }- Y. ]# L* g7 R$ j& W$ j
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1 U/ t5 q S2 h2 `; a Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/& Z/ i9 Y& _: R1 P. i
printf("结果入栈:[%f]\n",opn_tmp.data);
- m2 [+ b5 T5 q3 P" [2 q break;5 \ g! }$ T2 d! P/ a' K, t6 O
}
0 o' u4 [+ Q* N1 v4 u. F8 C }
( j9 D1 E" H6 ?0 u3 e8 U' G% y GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 9 \8 Q% w" b. J: G- Q) l! ^
}/ n+ E0 H1 H x& V2 a
GetTop(opnd,opn_tmp);: {% a/ Z! s' N) a' O2 L
DestroyStack(optr);
9 |9 ]. ^3 z( j% T DestroyStack(opnd);( h# k( H' G7 r5 q
return opn_tmp.data;# O9 R) S# Z) z7 K0 Z
}
$ I, @- B# j/ O* C% H, X! I) C( F8 g) Q& X2 G
char *killzero(char *res,float result)' k1 W b0 K. L& a1 A P3 Y
{# `4 `+ E; M5 `' J* d- f, X9 J8 l
int i;
2 ^+ u7 x, ]5 y4 i# G- { ^
. e I( N$ T( H& q/ s. _ sprintf(res,"%f",result);
/ {3 e8 e$ U/ Y! y- G# k8 m i=(int)strlen(res)-1;
" B0 s0 k( S* m: J2 f4 Y( b- x$ P" f! Q while(i&&res=='0')8 ~7 z! l% x" y; S) R$ j2 `, S
{0 ]9 ^( f# a! u F& z9 N/ @
res='\0';
" r* f1 ^+ o# l: f: g0 O; r i--;
+ w' F. L F8 J% T8 } } g+ d# ~" g- z& \ v2 @- a
if(res=='.')* X1 I2 J1 u; t# [: T" H% Y
res='\0';1 g( L8 o7 h/ o6 D; X
return res;: O! P1 D0 s/ |
}$ G5 N: ?9 ?8 j3 N
! O; D# v/ D) Xint main()+ x' q4 M. d3 W( y$ Z. _5 Z8 `
{* @/ [, l+ d1 {; P
char ch;( X# i' [- b2 V% O* [
char res[64];
! i) Y9 K l9 s5 i float result;
! Y6 C2 F E5 M9 ]3 }+ V9 n while(1)% z' C; l& J0 a% U0 E8 B& @9 W5 G
{4 x. ?2 A# n. C! i
result=compute();
8 j& _/ ?1 K7 O% Q' O: R0 t printf("\nThe result is:%s\n",killzero(res,result));
5 y2 @& B, c- L* B' N. y7 j. Y: z6 j: j printf("Do you want to continue(y/n)?:") ;
. }' Y+ k* y( H. z& u1 Q ch=getch();
4 O! S* q( K* H, a- Y putchar(ch);/ \$ F5 D+ f) M7 ?( j" u- v
if(ch=='n'||ch=='N')
& {2 O: W- Z+ O, Z: s3 F break;& Y, n% `, a: v) s+ [
else. X6 D( {0 y+ l
system("cls");( m& g% {8 {$ @* z: |, Q% G
}
. r Y. Y. e0 J# L! c return 0; D( Q3 Z8 @# Z; X- `% V
}3 J# y" y9 I; m3 B& g% ?+ ` {
+ i4 q" E/ z2 ] [2 M[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|