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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.0 E9 U8 Y7 \) P. G
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
* n0 r( ]; `9 m, e" Y6 G/**************表达式计算器************/
+ a8 }1 E, F% W& s#include <stdio.h>' s: U) ]) E, }$ z
#include <stdlib.h>3 R( s6 w! a- c6 u* |5 P
#include <string.h>' r X# n1 Z$ B$ y: E# ^
#include <conio.h>
1 p u( A" G. L4 C( `, O W#include <malloc.h>: [- U2 i0 O2 L; k9 k6 t% Z
" x- `8 z9 C, N1 b5 _5 c. }9 E8 D#define STACK_SIZE 100& f0 L' G4 i4 ~4 p
#define APPEND_SIZE 10
, T% F& c, W. F' {0 K8 M- Z0 C) `, C& X+ g& l
struct SNode{
* V# c6 \1 F6 m9 P* ~$ f% m float data; /*存放操作数或者计算结果*/
/ u" v, a" R2 C& @. e" t char ch; /*存放运算符*/
6 m% b$ S8 N) h8 @- T" E};
( n" `1 p) S, K# S1 H8 u8 W# [5 N# g/ P
struct Stack{
9 J0 f% p2 D0 U9 n3 h2 S! K SNode *top;8 h+ U; D; l! V# B
SNode *base;1 V/ N2 q# C- m9 Y) }
int size;! ~! B$ \6 ? X6 U" A8 `: I& U* D% N1 H
};# t$ n& Q6 |" P% j
9 G$ z! T" f8 n: O" r/*栈操作函数*/
( r. A: }+ |: Q6 F F$ d6 n- j4 }: Iint InitStack(Stack &S); /*创建栈*/
# q, M7 m% T% l. \int DestroyStack(Stack &S); /*销毁栈*/; ~( b# m$ ^6 I9 G
int ClearStack(Stack &S); /*清空栈*/
9 z* F% t0 J& S/ |int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/9 A/ m2 @: y" N) Z' O
int Push(Stack &S,SNode e); /*将结点e压入栈*/0 Z) w8 G2 b6 T# s( o
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
V/ q. S! k6 A, d8 G& x8 ~) {
% G# K) K3 Y. t/*表达式计算器相关函数*/$ r; { ], R- P' B0 k
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
) v$ m @9 M" y: O4 ~+ e y/ E9 F$ xint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/+ i5 `. R3 f/ O% C& P% P" _. l
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
; ?& }6 a3 a1 t! M4 ?/ M, w4 Qfloat compute(); /*表达式结算器主函数*/- @# A7 Y$ G+ D* r0 e" a
char *killzero(float result); /*去掉结果后面的0*/ 2 I- n* `* s) T: C6 A" j* f- d) b) Q
* ?9 J6 v& |7 z9 ~# p
int InitStack(Stack &S)
0 R, q9 Y0 b4 y' T4 q# U! R{
$ r( W5 `0 H+ j0 V1 x S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
u3 P3 }. }2 Q6 k$ m if(S.base==NULL)& ]1 d' ]1 |# J2 t
{
~2 c4 R3 x! c+ G3 M# n printf("动态分配内存失败!");& l6 L) H4 [8 y! ^ P+ Y
return -1;
% ~& r: v/ x! }' p2 C3 d, l }
% n3 D3 m. O. |3 b) w; [3 y' q. V1 b S.top=S.base;9 c" l$ R. m6 W
S.size=STACK_SIZE;
9 T, D: H" V) ] S( j) u return 0;
7 E! b( x/ i, r8 `- e4 O}
: `- |% y# t" g
o' o( c9 D/ Q9 z; H, _1 J) Jint DestroyStack(Stack &S)0 c6 e3 Y' G$ A' [, k. w
{& S% e4 a3 v1 r, J
free(S.base);
6 P) Z" M. n6 k return 0;
; a5 y- L& z: G" B}
; y3 V7 L3 p/ y- q j& ~$ ]2 Y% u# |. |
1 {0 E% u- t1 ?% w$ ~int ClearStack(Stack &S)3 e4 p2 w1 S: g( Z4 j2 D
{+ ]( U0 L7 T' `: @1 Q9 W
S.top=S.base;& }+ J5 V$ ]# B) V3 `! K/ \
return 0;' C: ?9 x& r, z1 K$ E I3 @# a
}& t/ c* f" S+ W8 o. T( ?
! A1 ?: J- u5 m0 s( V" t
int GetTop(Stack S,SNode &e)' l0 |8 N V7 Z' A; r2 S1 G& f
{. p6 B8 g. p) I6 V
if(S.top==S.base)$ l0 ] ? Y" ~2 _5 [+ N6 u
{' ?( I6 n& R8 V# A u, s! P
printf("栈以为空!");
; l% N2 W9 [/ a3 C+ U return -1;/ \2 c p' \! t5 Z0 H
}
4 r$ M; v3 e0 Q4 K% u e=*(S.top-1);
: e+ L* B+ L5 E- `5 v A0 @ return 0;
! f+ u+ W% M+ G: H8 s; s}
+ }+ T' s2 R5 C x2 v+ Q
) E) V: W0 f, J9 ~* x+ Oint Push(Stack &S,SNode e)6 b& l0 X% z) J5 X
{
, m: v! v r/ C/ Q& X- c( l8 ~ if(S.top-S.base>=S.size), l$ z$ P4 j" ^: c. j" S) C) M7 w
{
3 T$ W H5 X( O4 x- Z- A$ n# g S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));' s, G' O& k, F. U
if(S.base==NULL)
% z, i0 P: M( ~ q& n# q: g" T* | {8 P0 j8 Y8 x; z; b+ a- C D0 {( P
printf("动态分配内存失败!");
' W0 ^4 o8 N- L! q& G# n return -1;
1 u( L) {0 s+ J: W' A8 B5 l }9 D! n ^- u$ E5 j
S.top=S.base+S.size;
0 ]7 P3 H! Q6 ~ S.size+=APPEND_SIZE;$ v2 _7 P! ]( M; h3 ~- C
}
4 g$ s m. ]" s0 ]8 {' \3 S *S.top=e;3 S: a: f" _% X2 A& |" S u
S.top++;/ k3 F8 q) l* Q! m+ A
return 0;
, x2 X! \5 D6 f/ [}# |) }/ `) k* Q0 \3 F: ~
C% I/ T" E; A2 d i
int Pop(Stack &S,SNode &e)3 Z5 g3 g; ^( _- V& `
{* _5 H) y5 X0 ~, O- X7 c+ T
if(S.top==S.base)2 E R+ X" V" C |4 D( o1 }0 K2 u
{7 [- \- A6 ~) e0 Y* I9 D& X
printf("栈为空!");3 Y. z% j4 @7 s$ `: N9 F" }
return -1;- p# w& A+ }( y, x9 }' H8 M5 q1 Q6 b
}5 m( v2 k; l9 x6 a7 c- M, u
e=*(S.top-1);
[6 Y% I8 z X/ V) r& q3 {* [) T S.top--;
0 h+ j8 f1 g1 Y" ^$ u% K2 B return 0;
& a( Q, E1 ]- [" ^. i6 G3 a) z; L}- s$ ?6 z, Z5 H' Q
' g+ w: C3 I9 O: e: M9 `: l, U8 [- Gchar get_precede(char s,char c)' O- c4 l o( L& C/ p, T q
{* b1 d8 Y+ t/ T. T! r: K5 g. C- h
switch(s)
6 b. C$ a9 j1 n% a+ N) C {( `4 ^ w% a2 c4 g# t- `
case '+': & p, X8 \ ?: z1 l, ~0 ^
case '-':/ ?+ z- y- y3 O0 H, d2 Z
if(c=='+'||c=='-')$ q4 f; p" C; t1 l1 q3 i6 h
return '>';& _ I7 `% c( w) X: F
else if(c=='*'||c=='/')
' P, C+ u# J2 ^+ S' F$ e: P return '<';
6 W+ L9 z" _3 ^4 {& g- X else if(c=='(')* C" l2 ?" R' f7 y u
return '<';
4 a7 o0 @# p9 _4 l8 l, } else if(c==')')
1 L- R, z7 {0 n/ m return '>';
4 L6 t5 H" j' ?7 t6 C: E1 q else 2 o0 c9 x+ @! Z! I% B9 |. m. h
return '>';& f" L: ]- |& c
case '*':
3 _, z7 ?9 ? J0 r( n case '/':
% F# t5 }! x, h4 z/ w0 e if(c=='+'||c=='-')
# k4 G9 W6 Z. V6 ?8 M return '>';( m# Y8 |, D+ }& \+ i/ z" o
else if(c=='*'||c=='/')* I# O1 @% z. u6 l, K- ]( E
return '>';
1 W. p c# s* w' [# d" u else if(c=='(')
9 u K1 f9 L$ }, Y return '<';
9 o6 f0 D+ o5 Z- k% U" E" z else if(c==')')( ~9 d- H. l& p) h0 @8 i Q* r3 {
return '>';
( e$ T' w, F9 f, u7 b else7 L+ j2 z$ O, Z" y( p( X
return '>';/ G j7 G' E: s4 z! E
case '(':
+ B' x/ \# Z f( D if(c=='+'||c=='-')! M; H1 J& t) v/ ]
return '<';" E7 R0 m [, E
else if(c=='*'||c=='/')
$ B3 U4 \$ D& ~$ \ return '<';3 b! m( z( _" T) `5 q
else if(c=='('), q' Z2 f7 F* G; H1 ^
return '<';, g* B) }" E8 u6 G+ z" J
else if(c==')')0 g. g4 H2 j% n2 D+ ]) A4 R y. b
return '=';6 T8 g4 d U1 T# f( \( @
else
+ h2 M+ Q3 d" v3 O4 \' H7 I return 'E';
! A# K$ m, X! F case ')':
+ {) v/ Y) ~. f if(c=='+'||c=='-')- Q4 O$ k2 y W! s" `0 `
return '>';
4 |- B. u/ m0 k& W, j/ L, d( M else if(c=='*'||c=='/')
' G# v. l+ S7 T6 N; n return '>';1 m5 H! I9 ?5 U; y! c; D. }' K
else if(c=='(')
$ l2 ]2 D3 c: f; g( |& @* j return 'E';
! ^! }/ ?2 E4 O& p0 u% I else if(c==')')
( [' ?0 U3 ^; Q2 s( T2 j+ C8 o' h return '>';: W+ f \' H: [- d
else
7 A4 r- X, e. t$ u4 @ return '>';
# c8 ?9 u6 o6 `0 b' Q% g case '#':- a+ ` a6 ]1 E+ r5 U! }& `
if(c=='+'||c=='-')
. e7 W9 \" k4 a. ~' W; t" r return '<';0 r% ]" g+ _- S1 R
else if(c=='*'||c=='/')) h1 e6 l' S, @9 @
return '<';0 }0 W- ]; w* N
else if(c=='(')
, B @/ F5 |6 s& E return '<';2 G+ H% M! T. v. k4 O! I- A
else if(c==')')
8 S5 j( s! v8 ^4 B return 'E';
0 z3 N) J9 l! W- l" e; q else
1 ~. q" W+ t7 T return '=';5 I! W' o+ j8 Z
default:
7 I+ K y3 ?+ { break;; x$ ]- f% C+ s# O
}
/ L6 y' k2 \4 R0 M' m return 0; 3 H. z; P+ M) ^9 L8 {" t
}1 l; L+ H7 g8 d: b
; W; t, }, y0 T# d2 G aint isOpr(char c)
' L/ ]# s! u; D. l) z{
- b$ a0 T5 U) X/ c3 G0 ]3 g if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=') s9 n1 d. U* z9 {( r9 w
return 0;3 i2 |! L h2 y5 D
else
; X$ N3 _$ Q% B. u return 1;1 m$ A$ M0 A7 G* {
}
* ]) _& _7 Q( x7 a5 C9 N3 ~& O; }% q
float operate(float x, char opr, float y)$ ]$ c$ D/ F9 w* y4 z" F
{' x6 A% }* b/ g8 c: r
float result;! [5 i/ Z+ u* a5 ^* B4 M
switch (opr)( {; W7 O& E! [) R, L
{7 Z# v/ }. s. V& C9 q3 H
case '+':
) ?+ ]( n* y q3 Q result = x + y;
' C6 Z; P6 }. n- S% A break;$ h3 C* u# j2 _' H) Z# o
case '-':
! n4 P* f% a7 j/ M( N" B$ n result = x - y;
9 q2 V9 Z* P; ~) b4 y6 O1 L, D8 V break;
" t" F6 B0 I8 r' M1 G case '*': 6 R2 r5 y! h: K
result = x * y;4 `& w% I( K# a2 G3 j2 D' K. i
break;2 P4 j# `6 }! e2 s9 a
case '/': + b: W& P3 w* V
if (y == 0). m7 V2 p9 p2 r) n2 o" i
{( o- _9 w8 _; h
printf("Divided by zero!\n");4 D# j: t& I" J: s
return 0;) L6 v$ n, } m
}( {; T' `4 n, c9 a! U2 d
else
6 ?- M& w$ K: H+ {+ P- M: K: Y2 j {7 g4 q8 V1 [' `) Z j& J( Y
result = x / y;
4 k: r) }; n$ }. s: P* E d' o$ s break;
7 [1 s# l) _7 F2 t }" }9 w r6 A0 Y1 Q5 R0 ^9 U; r
default:
' v$ f& Q3 C7 |4 U$ C printf("Bad Input.\n");
$ b& t, i) A2 f. l+ c5 S% t* q return 0;
: h) J& D9 _. B) A5 q- e1 o5 |: F }
' [5 \, U% [+ A, F0 p return result;
; z% {, V" T4 L( r0 O- I m}
/ q' ?; k8 j3 z% w' o
! r- M! z; w$ g9 |3 {# L& o+ B5 x$ ffloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
8 j7 y* t, U) I( |1 z- X{
# @. ~; p' @, c$ X" ?# U" V$ ` Stack optr,opnd;
/ d2 K; F) \# t) b0 S, E struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
c3 }. O( c) ]8 e2 x9 z# j char c;
5 v$ C# ~$ {+ } char buf[16];
' |8 b- L2 \7 O, B1 {5 |+ J( ^ r int i=0;8 J2 _# N$ s* v6 j& f; ^4 W
p8 f% h! k8 C4 g& { {" k3 d- G9 P
InitStack(optr); /*用于寄存运算符*/
8 Y+ K5 _6 c; `! m& R. u8 r. i InitStack(opnd); /*用于寄存操作数和计算结果*/ P! [3 e" T, J! F1 Y b% M- Z6 d
memset(buf,0,sizeof(buf));- T3 H- m2 ~! p2 b4 i7 K
& d$ n! I3 @5 E: t) C2 N
printf("Enter your expression:");
# M/ g/ | ~2 a8 z7 a8 Q q3 ~3 _1 h
2 i l( ~: A4 o: S% H opr_in.ch='#';7 L( [4 L I/ R" m- E
Push(optr,opr_in); /*'#'入栈*/, N# @; ?( L$ T8 m- A
GetTop(optr,opr_top); F5 [' ^" l3 D# I
c=getchar(); y k6 @: ]$ w1 `1 D
while(c!='='||opr_top.ch!='#')
8 F1 N; K1 \. e8 c. [ {
0 B0 i' u# x) M8 d4 E- s2 x if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
% p* j2 z8 y4 U {& u: a6 ^, e; ]' j1 ?
buf=c;" L" y& W# H$ ]; W! M; W. {7 q' Y: _
i++;7 w d* W8 a" e+ ?. U0 d
c=getchar();
8 M& N" ~8 u4 U' u! i% ` }- b/ v. k! F2 I
else /*是运算符*/
' O( r2 I1 r# x' i$ `6 b4 j {
; m3 h5 n4 T8 z" i) ^" b. } buf='\0';
- \3 m. r3 z5 P7 A* O- J! l& o if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
1 X/ `4 G- K7 g# M. w {' p8 s6 X( d* L0 g7 h9 o& v `! v
opn_in.data=(float)atof(buf);
' u9 _* g4 \8 U7 d Push(opnd,opn_in);
- g# g$ t5 ]# H; I printf("opnd入栈:[%f]\n",opn_in.data);2 d1 c- z5 S7 c4 F! u+ R
i=0;
' \. Q( u0 h; C6 i( l memset(buf,0,sizeof(buf));, w1 X) O1 W8 H7 `- a" P+ a
}
4 t7 W" x- e! j0 m$ L" N opr_in.ch=c;
0 b! P F7 l2 U- O! ~: g switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
" s/ }3 U( w _ {: A) G8 F9 t6 t3 `
case '<': /*优先级小于栈顶结点,则运算符入栈*/
X3 ?: v+ P# r7 ^: g) x Push(optr,opr_in);
0 n" o/ \" P' Y1 S' k printf("optr入栈:[%c]\n",opr_in.ch);
# n7 s5 W. x$ i c=getchar();2 y2 L5 p( D3 T7 c6 c$ d
break;: x3 L# ?* A! ^3 n5 T4 v9 }! {
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
, p% W) X4 _+ G# ` Pop(optr,e);% e2 P, z* l7 {1 N& D
printf("optr出栈:去掉括号\n");% y$ r7 G2 x: d& L8 f( X( I
c=getchar();5 P4 o4 j9 P/ m5 G' B7 e9 a
break;
]5 t0 P7 V' f4 i5 c' ~ case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
2 u0 e }7 L0 N) k/ a4 M7 I. p Pop(optr,opr_t);
( v2 X( V- }: \* ^6 ^9 V" P/ [ printf("optr出栈:[%c]\n",opr_t.ch);; T) @. y1 X: C7 K& O
if(Pop(opnd,b)<0)6 q% i, S. `& s" I& Y9 w% u
{& S# [1 {* N9 ]4 R" U3 C
printf("Bad Input!\n");
( I' A3 `2 M0 B, e( ` fflush(stdin);5 I$ Q: z5 E" R) W# g) A
return -1;. R3 _) x0 l6 L. @' r. c
}
& C+ d9 g& h3 E6 S+ |) N! r0 g9 b printf("opnd出栈:[%f]\n",b.data);
) H, S" K X S1 o0 k- I6 L if(Pop(opnd,a)<0): v K& Q2 [$ k! U* g
{
+ Q6 F7 ]2 K4 W+ Y4 g% @9 M printf("Bad Input!\n");# o: z, r: U$ |* G7 w
fflush(stdin);
3 r# ]; i) r, ]9 s* D! E return -1;. w8 ~* c( h! R. p9 D' y1 H3 h
}
9 O; L" [# `6 h. F! O printf("opnd出栈:[%f]\n",a.data);% M2 r# g: e) W: j1 s* Q
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
; F0 Y: T) U# s# s4 E3 }+ b$ | Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
; h8 I; V# z( a: e printf("结果入栈:[%f]\n",opn_tmp.data);
: o& i B% F+ P break;
1 p% v2 ^, W4 c, c) v }& l- Q6 `! G) q0 i# Q
}+ Y/ b8 V4 ^, G5 P1 T+ a2 w; x
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
5 x) Y: l/ l& b7 c } f6 J' G) p; _0 l: t
GetTop(opnd,opn_tmp);9 [" N5 L. u* x, Z1 m+ G- k7 p$ y
DestroyStack(optr);
3 x7 O7 s [3 X, B! z, T DestroyStack(opnd); `3 O+ [. X# r' X8 o E" |
return opn_tmp.data;0 k. e6 N6 D: S9 f" i+ w% ~
}
( [, }1 Y+ c* m1 p$ Y$ K; r" Q! _" I
- c6 i$ E9 W. g& {! `4 g% n# Ochar *killzero(char *res,float result)
% C; }# `9 j; V B{' E$ }. n8 z$ y3 f. p$ T' d
int i;6 n1 {/ _ u: K6 v
. S0 E* X! T0 ?3 W& O
sprintf(res,"%f",result);
6 s: Q+ C/ O" m: `( d; } i=(int)strlen(res)-1;$ }( v2 m8 T/ D2 A7 ^2 w
while(i&&res=='0')
: a* A3 m- L. I6 j {+ a, S' v) _' r0 t, o
res='\0';9 t3 l5 h( H! U
i--;! }! T7 \4 c8 Q) L6 j8 ~, m
} p5 N2 \ i$ M7 } C
if(res=='.')
) X: b; B* V" g# H( h0 R. ?5 a res='\0';
) L4 l" Y- o* ` return res;; ?1 l1 ^* |. V
}
7 O2 _$ g. p- A8 n# y; R
1 Q7 k2 d/ k$ U C2 Sint main()* l- z, h* u/ H t _5 d, b- H
{
0 f" g5 e& _6 n char ch;
" i' t5 `0 [/ \! }2 {7 R) l char res[64];
/ o2 m8 i; Y/ q9 F float result;) }8 _9 m( _! K1 y" j
while(1)
: `1 h" P. T" Q2 A* C {7 @" S% [5 P! A: F2 P
result=compute();
" C9 {" h; B# n printf("\nThe result is:%s\n",killzero(res,result));0 u8 }- [/ `0 i& i; u- K9 _
printf("Do you want to continue(y/n)?:") ;
( y9 W! j# D7 A* N( x. e- g S7 { ch=getch();
0 S7 K3 G- g$ E4 b7 @: t1 c7 O putchar(ch);
/ E! b* c- G; X( n+ ]) p8 U if(ch=='n'||ch=='N')! u- K6 O1 d4 ]& N% J( t6 g
break;) }- \" K8 f ?6 Y X
else
4 l! b" E) D) e system("cls"); V# \+ Z5 K1 K% n. I0 X
}
& G' N' n6 a. R A return 0;9 A! ^" c' `- t7 d5 v% i3 E
}
/ u/ o8 p$ C2 Y1 L2 {) O
3 e7 @$ h1 M( [# x) M[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|