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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.1 Y& e, L, K5 [! v' T
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
+ v6 V! ~: y) q! v# d/**************表达式计算器************/1 d$ _. C6 f6 |
#include <stdio.h>% c$ Z a8 Q# X. k9 ^# t
#include <stdlib.h>2 r. E, s8 I# ]/ ^
#include <string.h>
/ c( \; n# J: {7 F' _# J+ p#include <conio.h>& t2 w) a! u9 c) ?4 \
#include <malloc.h>5 k6 G! |1 l; I, _, s" @* B" J/ ]
+ e% Q: I/ X. l w, j" Q; ]
#define STACK_SIZE 100
# c4 t5 K& M* D1 \- U m0 ~4 F/ W#define APPEND_SIZE 10
" u0 y* t U( k9 m% ~: T
- _& M! }2 A1 d1 [struct SNode{( V/ c6 A9 N) t0 k" r
float data; /*存放操作数或者计算结果*/
" a) \% P! k8 {* k char ch; /*存放运算符*/6 \- L' y t* ^
};
2 A" ^8 r# g6 B2 m% S# T* k8 j/ l5 Q+ k
" J7 t1 b; \4 b* _struct Stack{
0 W. ^+ H: R% ~6 c6 P1 I SNode *top;& w6 J. {& O5 f# ~1 k( ]
SNode *base;* b0 v1 P' v8 X0 w
int size;
7 y/ u' y7 I) A; c1 \};) P# m* e& x: n
1 F( X, R% e4 z% x4 Z2 d) M
/*栈操作函数*/
. _9 e, F# K4 k+ W4 N- [9 Fint InitStack(Stack &S); /*创建栈*/- E- u( K+ j6 ?- N6 n! D& ~6 S
int DestroyStack(Stack &S); /*销毁栈*/" \# F1 U/ M) c% x* d+ Z: O( k
int ClearStack(Stack &S); /*清空栈*/
& y* h6 _" o9 b1 j2 x- a) V2 aint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
2 U, l1 q- M: U$ p* N kint Push(Stack &S,SNode e); /*将结点e压入栈*/
& b9 S/ r ?. H) j% J# Iint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/9 J* _0 P4 b! n8 g8 e& L
7 K& ]3 p+ V# {* Z
/*表达式计算器相关函数*/
" m0 ?1 b4 {5 m6 G! dchar get_precede(char s,char c); /*判断运算符s和c的优先级*/- A& n# j1 ^& t" v/ @% s" V
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/$ J6 T5 j: b4 p. O4 _, E! s
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/7 x4 }! l3 G6 S4 U" [ [
float compute(); /*表达式结算器主函数*/7 K2 J m0 [- R4 L7 C
char *killzero(float result); /*去掉结果后面的0*/
5 w+ Z" N" s8 a V9 y& J7 b
- }8 g; S; u l. ?# o% O% }int InitStack(Stack &S)' j1 s9 R6 y9 ?& [4 M3 } ~2 T
{' a# b2 u3 d) k/ f2 r
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));* x z1 L; n5 ?+ h) L1 v* i
if(S.base==NULL)
4 O6 T$ R, u( d9 T( P' C {& b4 D0 c4 A. z' z! M9 o
printf("动态分配内存失败!");
+ H, s/ ?8 W; u; K4 i/ U( H9 j return -1;
3 E" g' f6 y1 h" y }
/ X2 a- C. M& Y" {9 Y3 |1 q# ^& Q S.top=S.base;
% L1 ?4 ^& O$ O+ z8 Z. ^ S.size=STACK_SIZE;
* f5 t# m3 J3 @3 @ return 0;( H# k l; g( n+ ~& e: M
}4 \9 C! n \+ T' ?8 ?# s
) d) c1 q, `+ gint DestroyStack(Stack &S)
$ `4 L' c! V! Z: ^- ?{
) ?/ `: `1 E: i+ Y0 v free(S.base);
) F6 V/ L/ ?( e return 0;! J* ~7 z! r1 g0 w8 j7 C
}: @5 [. z0 k: N8 K W( n+ H
' c' m( Y4 [5 K( M7 Q Iint ClearStack(Stack &S)" K1 a0 v+ G, h7 @5 R8 k, R+ v& p, d+ j
{1 V( V# P3 }3 s+ n, R# ?# ]
S.top=S.base;
3 E% K* D- R+ G* x4 |4 | return 0;
8 H8 a4 s0 j1 _: B# G5 Z}
/ C2 X: |9 g& e7 K8 E5 L3 `& q0 A3 _: a& B
int GetTop(Stack S,SNode &e)2 }& z( y2 H8 J$ \* k
{
. A5 ~( z0 R, p4 i' a/ `2 r! I if(S.top==S.base)
E1 H4 v& a& E3 Y3 b {/ t' ~. P( G: l! I4 {4 t
printf("栈以为空!");
! D' s \+ I, a2 C6 I4 {# K! A$ [ return -1;
% B2 k' G# O/ @7 e! b }% v5 l% H* l# g8 Z8 s; H6 H* ]
e=*(S.top-1);/ g9 u8 Z( q- d* P' J2 D
return 0;
/ ~1 [' T, U$ B}! K. e1 i$ Z3 R2 _ y: X1 Y
1 L- x4 B& g% `" [( N
int Push(Stack &S,SNode e)
- h; r* q6 N4 X8 b' h; h" e, {{
/ V: C% H9 W# `/ S/ w if(S.top-S.base>=S.size)
! o! m* q7 V$ H l {
8 W# L6 q8 V) L3 K S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));0 G) a6 q- [( z8 Y
if(S.base==NULL)
+ o9 r1 P2 [9 F: L {
( v. {& ]5 U* m2 U" ]1 w v printf("动态分配内存失败!");
6 W: @6 z9 a- p* Q+ n/ ^1 F/ N return -1;- F6 h: X! P% c/ y# A) W4 h. k9 z
}) @1 l) k. C9 Q
S.top=S.base+S.size;2 g/ B6 O+ r1 y7 v
S.size+=APPEND_SIZE;
% E0 U, b) q" @9 E6 g. d }* h1 J$ \* `9 \; |% ~
*S.top=e;
2 y" C* L" m! d S.top++;6 j& s6 t7 Z/ z: L
return 0;
% S# R% A# f* w8 F}
8 C0 J9 d" R- X m ?8 k" t8 I9 X1 v% u# b
int Pop(Stack &S,SNode &e): e3 r7 o# `6 d
{
& e1 |, I. p/ U4 o* Q, e' V ?. Q; ^ if(S.top==S.base)
9 ^& K( x8 n; t) ^/ k W5 M {
2 G$ `1 p& Z. c! s+ Q$ q- D6 ^ printf("栈为空!");8 @0 ?5 e0 s7 }9 a8 D* \: ]; R) o' A
return -1; k2 t! F4 G% K' s. x) \+ [
}. ^( u; r: R3 Y$ |; T L% y
e=*(S.top-1);3 Y, P8 |3 h6 v8 V% z
S.top--;
" @: @/ u& ^: J return 0;6 x: q; M6 P" o% I; w
}( M) p8 ^( {- j' ^2 t- X- \9 t' j: Y
5 I6 T9 _ P- @" q. M9 F( X2 ^* T
char get_precede(char s,char c)3 U8 ?1 |; U, x& o0 x
{/ h1 M4 B' W# |
switch(s)
. s! u+ l2 r4 I! N1 W6 u, h {
/ X% S5 }( ~: s# F/ l case '+': / U- ~% k' X& \, U1 n
case '-':5 L/ K2 \6 E, |+ c! j1 O
if(c=='+'||c=='-')
4 K& i s: B1 }6 r. S. s/ T return '>';
. n' I) k+ P7 R7 R" ` else if(c=='*'||c=='/')3 e' |! u- A# C- N# s$ u
return '<';
( Y {: _! ^9 }+ A/ S else if(c=='(')
3 ^; g. q- c/ Q return '<';
0 A+ V1 T) ?5 ? else if(c==')')
1 J2 S. U( @# Z: [/ U4 | return '>';. s. |% l; C" [9 g+ Y
else ' i. e" }8 |2 V; b7 w" J& C
return '>';& t! N' @9 T8 N: _3 E n% H
case '*':$ u3 Q; _2 k1 O3 o/ b, A
case '/':3 U0 ^$ O* }# \/ S+ n% d
if(c=='+'||c=='-')
4 `+ H& f5 I* ~+ J6 s5 H; G0 | return '>';& j: X; C7 Z0 [8 H
else if(c=='*'||c=='/')9 z( a5 l7 @( X5 ^/ O( s
return '>';5 v7 j3 x! S/ h. H+ C) C
else if(c=='(')
# r) v2 g e- b return '<';, y: F6 g( ]- Y% y6 Z
else if(c==')')2 I. Z6 x) A8 i; B7 J
return '>';* K6 \, I x N t* b
else
3 N& K6 d/ v$ C# q# f+ K2 ^ return '>';& B9 x( _) T' f3 p
case '(':
1 a+ v# O' X5 s# C7 [ if(c=='+'||c=='-')1 c8 k. ?$ l" l! Z+ Y6 [" ~, c
return '<';
4 B; d9 j9 V, u5 \( a0 o else if(c=='*'||c=='/')+ W' P& E9 g6 c& a; V- V' ?8 l
return '<';
4 v# A9 c1 Q1 @0 W else if(c=='(')7 Y) u }# |$ j# j! O
return '<';
- h! b- j) o# x/ F else if(c==')')6 a, M3 X ? X- W: Z+ d, l" G; e
return '=';
0 T( B2 @0 h' i: O5 e else
# ~2 s9 r: c7 ?, G. h# p' R return 'E';
$ p: A" Y9 W" ^" M case ')':# n! }4 ?* U- H" G. o8 Z5 ]9 A
if(c=='+'||c=='-')+ X$ f% E) C4 }, B% Y
return '>';( G% m/ A" Y9 u4 t' v
else if(c=='*'||c=='/')) {9 i: L; S, U! k( G% n
return '>';2 @6 U5 ]" I4 ?( S% U
else if(c=='(')# U, ]9 O9 G, q, o3 _
return 'E';
X' T% O8 J* S6 {5 k else if(c==')')! F B0 L- _" p w: Y5 z$ i, v
return '>';- M2 q5 V, n6 J* z) [6 F0 X7 G3 Q
else# P3 S L; b$ H3 M3 Q) H
return '>';
: m5 j k) }. R; y! { case '#':9 T* B+ I% K: b
if(c=='+'||c=='-')! ^6 E# q5 m5 ^; z) j
return '<';$ R$ k$ N$ K' s2 a8 C
else if(c=='*'||c=='/')
3 `2 m; \ i, H4 J. `5 \0 ?+ B. N9 z return '<';
5 V8 D. E" r9 w) f _8 ~ else if(c=='(')
" b( Y+ O# c1 o0 ?' L4 r return '<';
7 L$ Z6 U5 S# q) v5 i- j else if(c==')') H. [: O# Y, ~5 W
return 'E';
- Y* I: ?. B4 `& w( Y4 R3 J9 A else+ o9 E' H G: `' D+ w! O
return '=';
1 q, `' C6 W w8 s P: O6 p default:
/ t4 Z; |3 u: b break;
1 B! r5 a* i: K3 P4 B }6 N- F& {) A% D- ]7 E1 r
return 0; - P1 Q: H! d) u
}
- q. u6 M! |, ^' Y: ]1 y7 C
" ?) D: D% k5 g O7 H' Yint isOpr(char c)) }6 K; n% a4 g/ G% A4 |
{5 ?- {3 W9 b' C4 }- V
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
+ L3 |3 B) d' l; [ i& p return 0;7 |+ r" V, ]0 [* y* ^
else
0 q, q( ?4 l8 P1 `4 G return 1;
. f. F4 P8 r, J& j+ d, G( R1 V# r}" |1 K, L$ E: X4 c& I2 b
" G2 B6 ^8 B+ S; n1 B1 }4 rfloat operate(float x, char opr, float y)/ i A A+ i" p( P* t- L
{
( \2 Z, r- X. D) x float result;
" Y: R& g6 V; U: y$ o7 i* p* x switch (opr)% q1 F3 T4 }9 a2 l. o
{
$ r' P8 q q9 |! f# ]9 E- n case '+':
% T4 R& K- [2 B1 u( ]4 f3 ? result = x + y;
$ q6 k0 y' L9 M break;
6 o+ {/ J. K: v case '-': 6 ?2 ]' I8 s0 Z7 |9 G
result = x - y;+ `7 `' l) b- b
break;5 E; I2 h, [# X2 H; w6 m
case '*': / B9 H7 \# [1 t Q% i
result = x * y;/ \- a$ d6 n% M' r
break;! }/ O3 h, C/ S. P+ a9 r
case '/':
$ s V! p S! o$ X7 O7 C if (y == 0)
7 D* e ~- m- W& g {9 I2 f9 ^$ i/ o
printf("Divided by zero!\n");
. S1 {6 \5 j7 { return 0;
0 Z7 W; B7 N4 W* {9 _4 j }
. n5 }! X$ @; S5 ` f# B else
# q; m9 s. c4 k5 \% L% G: F {, O8 R% Y l9 d
result = x / y;
$ L& G) O% j$ q4 c- N break;
9 @/ h. i/ a, e) e2 Q' P }+ B3 W( E) J5 `+ U
default:
9 d. X, Z! Q" `0 K5 b printf("Bad Input.\n");
9 L0 C/ M0 p% a4 @4 C# q: S5 W return 0;/ d8 H! ]- |) `2 v/ j4 [% @% Z
} Z6 {& B$ ?$ |' N7 l( `( N. e
return result;
# M1 `% P A/ i6 j+ |}
- V( m: H) }9 `- ~3 l
& t5 g& N/ l5 s% d! n S6 v2 T; A1 e5 [float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/8 V( T3 m+ Z/ i& T
{
% m; j, G# Q6 X7 g4 T Stack optr,opnd;; m' s; u& [1 e. e1 n7 }
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;, M! g: B2 d! L7 n
char c;
% q9 e/ ]- t* m, g: B$ {! O, Q char buf[16];3 ^! u# T" f$ b2 a% _* v" Q5 @' K; F" z
int i=0;/ `6 |" ]4 m/ w+ }& o
( }% X; ^3 s* i# Q4 a
InitStack(optr); /*用于寄存运算符*/
2 g: b3 ^9 a5 S$ E0 {4 @% l InitStack(opnd); /*用于寄存操作数和计算结果*/
/ Z5 J. `7 o8 q) t memset(buf,0,sizeof(buf));
. e2 v; A V* s- \0 T! q/ r! o
2 C6 @! u2 o4 i' I printf("Enter your expression:");( T1 O* D4 q9 z" I7 x; [) S
8 b! b5 G2 t1 o& H: \ opr_in.ch='#';% W; W, o6 x: m5 O: s8 w
Push(optr,opr_in); /*'#'入栈*/
- _# L2 n6 |% p3 ]8 Y; n# I, w GetTop(optr,opr_top);
3 F9 {- T5 M+ G# i. k2 t% a% |& B c=getchar();3 O- |( E" r% Q, i- [1 T
while(c!='='||opr_top.ch!='#')' F8 r! N) Q) ~$ o
{ m0 Q' G& v3 ?0 p* _
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/# l3 o( p: m$ u3 t
{
$ y! S, c+ a, [9 ~ buf=c;
1 K% G# Y' K+ e4 q8 k% E0 E9 P" b$ ?4 l i++;! }" H' k+ [: ^
c=getchar();& n& C( y8 y) I$ }" k
}6 K4 i3 k8 k& d4 ^6 z s
else /*是运算符*/( F) T5 ?1 m4 k1 S, m
{5 j! v; C1 D6 q/ ]2 Z. `! z
buf='\0';/ h$ k0 {- K% Z8 [
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/+ v j5 j W! [5 k6 ]
{ z' d! i! \4 o# w
opn_in.data=(float)atof(buf);( o$ a: |7 Q5 e7 V1 J7 v* b
Push(opnd,opn_in);
( y6 }/ J7 t9 ?% L printf("opnd入栈:[%f]\n",opn_in.data);( l* ~: d) ~7 v6 A" Y M4 V; e* a
i=0;
! s1 i/ X. j) O/ ~ memset(buf,0,sizeof(buf));
' Q5 ~; ]' w! M; ^/ M5 n }
! s3 _1 |( z Q0 A- ^2 [ opr_in.ch=c; X5 L- q+ q( G2 ^. }' p. ]
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
$ j9 ?0 C0 K6 I4 l+ q; J {
( y, a5 F |4 I& A case '<': /*优先级小于栈顶结点,则运算符入栈*/
: `, R7 a6 Q) ^: l. L, s* v Push(optr,opr_in);
4 ^3 A# {7 S* z; N' G, Z; J printf("optr入栈:[%c]\n",opr_in.ch);5 v; \2 U p) H" w. T
c=getchar();7 z5 x; s' k/ M# b( Y: n4 U
break;
6 [/ J* r, v) I7 C case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/& J! @+ Q4 p* V% K# v5 M
Pop(optr,e);5 t. \) Y. n' m! x$ J- Y
printf("optr出栈:去掉括号\n");
( z( a- T' H6 B5 d c=getchar();
; z" k! Y' E8 y: u% Q% G# n: A break;8 c7 t$ d7 r7 _5 t
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/2 P7 S' Z6 ~ O3 {: E
Pop(optr,opr_t);
: n c8 Z% F, U& p5 K printf("optr出栈:[%c]\n",opr_t.ch);
7 q; d" r5 t8 Y& D) ~7 T6 p$ H if(Pop(opnd,b)<0)
/ L, y+ |( A0 @$ R9 e* k- J1 ^ {8 Y9 f' v- B( M0 F/ B, ~% F
printf("Bad Input!\n");
, z: `5 k' R; N6 X( \) f, T1 f fflush(stdin);4 H% K# _! A6 U1 }& ~- J
return -1;& e5 F" f) Y2 X8 X/ ?
}6 Y1 f9 |4 T3 B- U
printf("opnd出栈:[%f]\n",b.data);
7 v$ i" `% F, r# ~0 Q8 ], I! P2 X% G if(Pop(opnd,a)<0)
7 }! m6 O7 J* ?) L1 r1 S X { H; J8 e( I% j4 k
printf("Bad Input!\n");
4 U6 L+ c8 q# I, f% B fflush(stdin);$ W7 s d! U4 u, B& Y
return -1;7 W! r& f1 J2 k o) k
}3 Y9 @' I; b0 `; I, z5 [
printf("opnd出栈:[%f]\n",a.data);
8 i$ @! p' N8 |' h9 A& @ opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
) O8 S6 u5 i5 G; Z+ K9 R# S- z5 x Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/0 r+ Q% k! g$ Q. ?0 O
printf("结果入栈:[%f]\n",opn_tmp.data);7 O( \, ]' ^7 v' x- `( W
break;
2 Z3 |( c9 v. ~2 ^ }
0 J3 r4 m9 y) m, p+ P( K0 y; n }# L& D' h+ D( I3 I
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
$ w6 Q3 H6 K! F O5 G9 ~% Y7 K! A }
$ _, _) `* h q7 ~: g GetTop(opnd,opn_tmp);0 a5 e. d- p* b5 t& N* @/ W
DestroyStack(optr);4 }/ X0 Q- L. U r
DestroyStack(opnd);
c. c4 r* H* y) }; h8 f& Z5 p5 w return opn_tmp.data;9 T3 ]2 G$ X3 T- {2 k! A7 v
}- A/ {+ A" R: _- i# u! L
# Y) l6 z% M6 w! b( cchar *killzero(char *res,float result)
+ g. }4 ~7 _7 c: o3 ] E( q{7 d( ^& |0 I5 e7 X+ y/ L2 f
int i;1 T- Z. ]0 w2 k9 \. X/ x/ M0 b, J
* K4 c. p- U* ]6 c; n2 K5 |+ t sprintf(res,"%f",result);' p* Y- B/ h7 f0 T
i=(int)strlen(res)-1;( D2 x& X4 i# C- v( J' d
while(i&&res=='0')) Z, u9 K$ z6 M2 |8 _7 h5 S$ J" H) K
{. S% L) ?+ i+ C2 O" U
res='\0';
( w- L \, H1 m; L6 n) M i--;
& m: E/ z/ @/ G+ d/ G }6 m4 n* r' d: g" Z8 J! c2 P+ |
if(res=='.')4 ^( B _; V. I7 H
res='\0';
* c# M' b* J+ U3 T2 _ return res;
' k6 |' w, |+ I}2 g) z8 A( M7 j P6 U5 r8 [1 T
! C7 N: d ` d
int main()% V' r, Y. [' y. X! R: M" G
{3 u( U: {0 I- b; S
char ch;! B+ f* o R' C( J3 ^2 ?6 Y7 g6 ~
char res[64];' C; P4 `$ M# V; d
float result;5 g2 F" H+ P9 d$ d7 B% v0 u
while(1)8 I1 l( [3 M- x. u4 d
{
5 g! m3 |) u' S result=compute();
0 O" ]! f) V% u% S% M2 v9 Z4 U printf("\nThe result is:%s\n",killzero(res,result));
. [* Z* ]' H' z. q, S% A printf("Do you want to continue(y/n)?:") ;* @6 q4 `8 ` o+ M
ch=getch();
5 R: N; r; }) I- @$ W putchar(ch);
& G% i% z3 k$ q9 O7 k/ H if(ch=='n'||ch=='N')1 w2 x# ]' W. I- t
break;! S) N# v, ~! L5 O8 l
else
. P$ c+ K+ [& O6 R system("cls");0 {0 H% d, d3 J I/ i/ }
}- N+ H. V/ Q$ L# v/ w1 R
return 0;
/ T! Q( [/ i+ x! b% h$ A4 X}' O( L( y6 v+ Z4 v. [- L
: S: t. r- v& p7 [3 z
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|