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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
0 D* w" W& W* G程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=3 H* D. {3 Y- D
/**************表达式计算器************/+ c' i) H" b* e5 R) }, y' }) G
#include <stdio.h>8 p" P2 Y; R1 r/ w
#include <stdlib.h>6 I$ V, W* \. K; ^3 J& Z
#include <string.h>* z8 p4 }/ P2 h5 }
#include <conio.h>
5 N* q! T6 x) C7 r: x+ E#include <malloc.h>
9 k. o1 U4 C- }* Q: n% c0 Z9 U. D: u( G
#define STACK_SIZE 100( C, D: d; A& G1 J! {
#define APPEND_SIZE 100 C2 Z6 Y- v7 C" R1 T7 u
* q a, o$ n' Mstruct SNode{
: n$ t! [9 m! W0 M* M3 `. c float data; /*存放操作数或者计算结果*/# ]# |( m0 _. J" R# B# j
char ch; /*存放运算符*/& A/ w7 e, e1 q8 n) f0 e `8 c! o
};
6 o+ g2 g9 ^% Y
2 ]0 M" T* {/ N( ?" F2 X5 qstruct Stack{. r7 @0 l U; i* Q
SNode *top;' `6 ~/ Y2 J/ a& Z7 ]( ?# S
SNode *base;5 {( G# g3 h% e
int size;: H. Q3 t0 F4 B" k. F
};" |2 @9 ~3 c' y) T1 M# w8 }% j1 [
- M; N" F! B, Y0 L t
/*栈操作函数*/& a& g- t7 t* R/ K& U
int InitStack(Stack &S); /*创建栈*/
6 d& `4 ]9 C8 D0 I% ^; X: F: Eint DestroyStack(Stack &S); /*销毁栈*/
; R' H! ^0 z9 ~, }* l. D( tint ClearStack(Stack &S); /*清空栈*/% R0 M% L4 s, n8 F* w
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
) }% M' m0 Q) `0 F/ U0 q* R0 E( o qint Push(Stack &S,SNode e); /*将结点e压入栈*/3 l* N8 ^% n% V- y1 s0 N
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/8 N$ d9 h9 T, [1 c
8 K y& e$ X" F' N `/*表达式计算器相关函数*/ I+ t8 ~: r2 w# K3 L
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
* x5 c! P0 I6 g( pint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
L4 Z" T- r, o( n ?float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/% `% C; U5 @" V$ t7 P" b2 y8 \( o
float compute(); /*表达式结算器主函数*/
+ J) p6 h4 I5 gchar *killzero(float result); /*去掉结果后面的0*/
; [; z; m& b2 ]! Z) a' Z/ M" F9 G4 O' F6 U" e1 c2 q8 }7 K6 d- R1 w
int InitStack(Stack &S)
5 K# K2 X9 H0 p6 A* _{+ u3 Z7 x$ b5 U. [+ b
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));; ^$ B+ X+ R3 d0 z. O% \
if(S.base==NULL)
" m6 [- C0 ~, l x. X {
. w' `3 ^/ j: Z9 @ printf("动态分配内存失败!");
' c* f! N! s! O0 d return -1;- s9 b* U& h' H! D3 U, Y9 D ~
}
- H+ y1 ?$ X- s$ r3 \ e S.top=S.base;
- j! _8 h; c0 f2 a S.size=STACK_SIZE;$ H5 a+ V3 S9 j. w' D$ F8 B
return 0;! T$ O$ _% h0 ?" ^
}/ Y4 K) m& f- f( f, B) i0 o
~3 ?3 ^. ~+ V5 _% |int DestroyStack(Stack &S)
. t: ~- `6 x- t Q{
2 e$ X; _" m- O( u H1 { free(S.base);# _* o+ ^) F+ F$ l* g! b
return 0;0 ?+ g8 d4 D; R" j) {4 Q, K
}
9 d; y: S9 e% N
. Z& [* N6 c* s4 D1 r+ {2 T1 ~int ClearStack(Stack &S)
& O4 ^7 ^% _( i1 R{5 a. ^. o- k$ B* f
S.top=S.base;
* o# H; n C+ u/ i G. ?( q return 0;4 y% b2 L. r' Q3 _5 t4 X1 G
}; m; l5 j- t2 T; V# n9 D& @
# Q; Z# B+ z' [2 X9 J9 v. b
int GetTop(Stack S,SNode &e)
w; B/ `1 Z6 P, E+ f{
( Z+ _7 B4 H$ r$ E1 v4 \2 Z if(S.top==S.base): ]: j( O2 c. f- g9 H
{" Z7 R4 [# T3 G" L3 J# ]
printf("栈以为空!");4 j& M. {( d8 z, r; ~' @; y1 T) p
return -1;, Y$ H z" q; ^
}
. e1 j9 Q& Y3 |( r5 U2 K) J4 T( k e=*(S.top-1);. C1 [! p9 `+ |/ z* V: P9 S- T
return 0;
- ^ x; V: g) n$ @$ {# M}
' ~( x/ o; W0 W- P1 ^' q, O0 F3 U o3 @8 o
int Push(Stack &S,SNode e)
# N/ A' u) P X, ~. }{. } X9 T: r& M7 t3 W, r
if(S.top-S.base>=S.size)
7 J( N, C" C3 U, m" v7 i {( V0 w P# D: Z' u
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));/ w3 q. a6 t, Z0 J
if(S.base==NULL)% b, V: n i% R" r: `1 ^& y
{
; A' i1 q0 r2 M3 j" m o$ u3 y printf("动态分配内存失败!");
) ^ `6 m- I9 r5 k return -1;
: E8 T& x* v4 c2 r# T }
# o N! p, K' N9 G0 {0 r- S2 m S.top=S.base+S.size;% e+ G. t4 P$ X$ c0 e
S.size+=APPEND_SIZE;2 ]( J; e2 }/ N; ^3 J- R0 F
}
# b. |( e1 z" {: y. w4 k7 F: c8 z *S.top=e;- J1 a: u2 p6 O0 v7 y) \* f
S.top++;* u+ x# G, P% c% v
return 0;/ K: \8 F, j, ^2 e4 g, v" O
}
8 S; s9 e: p% E' Q# I2 k
9 j1 M# ]2 A4 p) [3 {9 S. q! eint Pop(Stack &S,SNode &e)% c5 ]/ o) U- L2 D d
{
8 {9 Q& f: k- `. |4 r if(S.top==S.base)
( e6 \7 D5 j* ^8 u. p {6 g* Y* C/ f6 T# L' D# Y9 c
printf("栈为空!");; d+ j5 p2 z2 ]% T" {
return -1;
# b( m( D5 ^4 B }) q7 N$ u: O. y m) T
e=*(S.top-1);
^' m, _, L' g2 e% g ^9 ~, t4 F S.top--;
. x K2 S# x6 e return 0;+ C8 J* \8 v8 J+ D$ V5 D5 K9 y7 E8 D
}, K9 U0 K2 U, F7 x3 `6 b: l% F& l
. [7 `& J4 h% s! f% e/ Rchar get_precede(char s,char c)' W& k" _) G6 L
{
- [; I, l! J# A( s8 k6 y3 g switch(s)
1 G& ^ C, B$ H$ Z6 m: \ {: h- N7 r* \2 t& y! b
case '+':
$ l. k1 _. d* [# B5 A6 H; A case '-':% M1 D. S1 Q7 i- f: l/ ?: F2 X
if(c=='+'||c=='-')2 ~/ Q7 c) @' I( l3 G4 z
return '>';( Q% z! H$ K- q
else if(c=='*'||c=='/')
7 W; \, F4 H* t, M) t return '<';4 S4 z/ ]$ G4 O0 a) D, C
else if(c=='(')
5 C$ Y0 h* z/ K/ U9 [1 e' J( h return '<';
5 Q* D9 x% g1 b: S6 } else if(c==')')6 z5 Z' N6 {( }: ?$ w$ c* ^0 ^
return '>';' |# u, R3 f. e* F9 o+ B, C5 `' G
else 7 E( p8 l; |- e: a
return '>';
8 O4 L5 P7 W/ w case '*':# P# B% g6 H; X+ P) }
case '/':
4 G! ]& V0 f( t) o0 ^+ k if(c=='+'||c=='-')
. b5 k6 E n4 p. H' i return '>';
# T `; {+ Z9 Z( _5 C" b: {7 w else if(c=='*'||c=='/')
: s" d! p3 v" V2 _7 k return '>';
. c7 q: h7 I: K+ ?6 @$ l, q else if(c=='(')+ J2 w# [4 Q9 k, x1 z
return '<';6 W7 i+ O7 K# @$ [4 m. d
else if(c==')')/ d" Z5 D& k, L1 s+ ^: H# N* }1 l
return '>';
3 p9 t- Q$ L, _ S1 T/ q' v5 D else
7 S+ {- V& u) y3 W return '>';% a" A1 Q, N1 H& K
case '(':
5 r' A/ [. u8 Z6 u* z" R if(c=='+'||c=='-')$ x* A7 z9 Q0 j) I( v/ T
return '<';. O5 ]0 L. ~1 }0 R
else if(c=='*'||c=='/')
; a8 r& s" r% j0 j' c8 L) S return '<';
$ ]3 N6 e1 a9 B% i; y0 ~6 O4 _- w, ~ else if(c=='(')% S1 j2 {6 Z8 Z2 F/ ]
return '<';3 ]- W+ F5 O( v1 t+ d Z& x- |& J6 ~: ~
else if(c==')')
7 m8 p& [; \: k9 ]% l9 u return '=';2 x% j+ P: W# d4 H
else
; Y0 M5 D- Q# _ return 'E';% M$ `; Z2 g& B; ~4 B% v
case ')':; G$ K( D& a; U9 W" \# V" l! P
if(c=='+'||c=='-')
e o! o; f: z7 J return '>';
1 k! o a* U9 G4 u$ p else if(c=='*'||c=='/')( X- t& M0 O. e3 F
return '>';: c& M& b4 X* @# i/ d& o6 ]5 V
else if(c=='(')! E2 J+ M6 Q2 F2 }. y `" j
return 'E';
$ K, |6 [# t$ g' X; M' P else if(c==')')8 E) C& }7 b0 `
return '>';/ k% s5 w9 V; P9 m* `" U+ B) u0 N% V( A
else4 E1 X& E& x4 R4 A+ w# D- g
return '>';
5 X) U9 a+ \0 }+ a case '#':' ~, H& `. E7 c4 g) k/ T
if(c=='+'||c=='-')/ H* d& R( M0 K, L
return '<';& ^, }1 A4 q+ f/ O
else if(c=='*'||c=='/')$ P; l0 d* B7 K# {2 ?' M$ h
return '<';
- ~: W" `4 w4 b6 T1 n P( v else if(c=='(')7 E, X0 v4 e4 f; ~) x4 r0 o
return '<';& l5 Z3 G8 F5 e3 m6 o
else if(c==')')( E |) C E, s
return 'E';! p$ d. {- R- o! U! }9 v9 z* Q, [
else, A- G* r8 X, x; s1 u' m
return '=';
7 P- I m3 R& C$ A) \6 @! h6 H default:
' r' \$ L# W6 {* Q5 k' A break;
' @( x; @; a1 I" Q2 F. |1 b }
* F: u! O4 R, h* K9 w return 0; " z# l( e- h8 Z& Z8 ?: O
}
- ~3 B/ b4 s6 | q% I5 Y8 e' p. W
% P1 e9 ~0 B0 M* h1 ?int isOpr(char c)
, N# ^5 b0 `; y( N9 n- a$ E{! W" \9 A0 q b! K$ h
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='): B* k' F, K7 @' z
return 0;
: h N l* ?/ t. [, r else 4 X9 E2 ?7 h5 L3 S/ {6 ?+ L; `
return 1; J, L; O$ Z9 o* G7 K: }
}
; o. a0 X: @: p. B, s1 l" O0 x6 E3 G5 \4 M
float operate(float x, char opr, float y), x2 e7 S5 t8 N9 G7 Z
{. G# \4 k5 }+ }$ p- h0 @
float result;( d) e2 l6 Q* O# |3 K" ?% _
switch (opr)$ }1 [( w! v0 n. ^7 C& ^' v p4 N: I
{2 A# c9 C/ d) x, l, C4 B6 V, X$ B; E
case '+': - t% r( F/ M0 D5 k; E
result = x + y;- R; I6 H y- L& W* |7 u' B, h9 b
break;( g! C6 Q& @5 J5 d
case '-':
, Y/ u2 \/ ]9 g0 J6 \$ `, O9 _ result = x - y;# m9 A0 V5 f9 s" @0 ]
break;# ^6 b3 k: |$ a' a7 G
case '*': 2 Q# @4 u8 g+ B: L+ r: \6 j) B
result = x * y;# I" C3 a d" l+ U0 W9 {+ U
break;
" i* V9 D% ~: U" e case '/':
: t* S/ _7 c3 w. w2 j0 m if (y == 0)& r' m+ i' r( s5 l) i& `' C
{
' K$ u8 d$ A9 P4 `4 w* q3 ? printf("Divided by zero!\n");" X( J6 e. E2 j7 {' t/ z4 i8 o
return 0;% C9 }( T/ v1 M: A \* q v
}
+ s9 T, h- p9 o2 f9 l( o else/ J. x$ n1 o# ?2 ~ y8 O
{2 C7 \' i/ W* {4 o1 ~8 z' j
result = x / y;
. n4 D* X i2 y. l4 K9 F$ } break;& P( n& o1 J3 T+ o3 R0 ?
}
+ t6 S% U( r$ z7 P ]7 T default: 6 r0 x3 u$ n+ u: W' F: r% S
printf("Bad Input.\n"); & C, T9 k' h4 f: t) ~2 ]
return 0;
" t7 V' x6 V; Z* z) Z; P( p B }* S( O: K& ?0 Y( V# c( V9 ^
return result;5 Z# ^. y4 o7 F) T" \2 L
}
* Z4 S0 E; ]- |. i& J
! H# }, j9 f+ T( v* nfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/8 M# W4 x- ^- @ s5 ~
{2 C$ n. l! k6 y4 P# e: [3 @/ p: J& L
Stack optr,opnd;
: g+ @7 b, I! U' L7 L, y$ {# |0 A struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;/ _; q& p$ F4 B" S* W* n! v
char c;5 G- `: q' c0 g" ]
char buf[16];5 l1 R5 g1 L1 p1 S3 s, m7 c( z
int i=0;
. p2 K% c! E' S2 }+ a% D. T5 b
; V% }0 Z! D! r0 G0 N$ R g& V InitStack(optr); /*用于寄存运算符*/: P& i8 N0 G2 s4 {! u$ ~
InitStack(opnd); /*用于寄存操作数和计算结果*/! }- U% p" ~; A- Q; L0 k# A- @
memset(buf,0,sizeof(buf));
. M; ^3 f3 Z* W p& C5 s : \5 M, e/ _/ ?1 R6 I4 |8 V
printf("Enter your expression:");1 f/ ^* U: h6 O
& k1 \' f3 W8 n" C, e2 c
opr_in.ch='#';
|- f1 O6 C U. b# k9 y Push(optr,opr_in); /*'#'入栈*/, u8 i. ^; {0 ^+ Q0 i2 L" g. S
GetTop(optr,opr_top);
?/ O6 w, ~3 z" h+ [+ {+ N, l c=getchar();4 g* g8 D4 `1 F I* e9 i1 k
while(c!='='||opr_top.ch!='#')
9 T% O2 j# L. z. B' ~. r n/ N {, [# m! t" G6 h! @7 [3 U: _
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
' e7 L- Y8 @& E! _: ^1 C {
6 }: Y) h; f. A buf=c;
3 G; r9 B7 K2 k4 y i++;. j+ B* J* s* \3 v. ]" A0 e0 K& }
c=getchar();2 \6 ]% J) \$ c. n* T" g
}
- b, R0 i7 S5 f) g; ? L else /*是运算符*/6 d1 X$ l' f/ f$ O+ Z4 i
{6 v4 @! Y4 f8 R$ a1 y5 N$ D
buf='\0';( }/ j( \5 e* A9 D1 @9 |6 K
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
9 ]' ~% b9 _& \ {
% M; _4 C m% f) a- j opn_in.data=(float)atof(buf);
" i0 t1 C" ~$ T5 {- C Push(opnd,opn_in);" {4 l/ {4 ]- f Q
printf("opnd入栈:[%f]\n",opn_in.data);/ ?3 f! _/ N0 {: u- r8 Z6 U
i=0;4 w( I- [& O+ j$ }0 B% L
memset(buf,0,sizeof(buf));
0 [2 V& s# k+ f- f) w# A }
4 d- Y0 F5 B5 S; C z# \+ c opr_in.ch=c;
0 y X. ~# ?" l7 d switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/5 r$ E/ U. \7 |
{
' ? d0 C& v+ x4 W3 o: h case '<': /*优先级小于栈顶结点,则运算符入栈*/- {" j9 O( H5 a; X
Push(optr,opr_in);
% V8 G: x1 O; o3 W) A1 I5 J) p printf("optr入栈:[%c]\n",opr_in.ch);$ {: w8 ]% D* m. I3 D0 N
c=getchar();4 g; f2 P' ]. X
break;6 o9 t a' B6 F) `5 }
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*// D7 M, N5 [( u* C) T' a9 y3 r
Pop(optr,e); Q+ D W7 M' m) @! V- Z8 z# K) V
printf("optr出栈:去掉括号\n");
. P! r4 [8 W6 k c=getchar();
; i! t9 k1 v& q, s& n4 S4 L break;
' V" E$ T5 ?) Y9 z7 I case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/, w# d6 h- a c1 o
Pop(optr,opr_t);
- L# J5 I& Y7 Y" | printf("optr出栈:[%c]\n",opr_t.ch);' h" o( E& ]7 `7 o6 Z' V( `
if(Pop(opnd,b)<0)5 X" V3 c( T9 A; u+ P7 s$ ]
{$ ^5 Z" \5 I" R6 A' `5 s$ Q4 b
printf("Bad Input!\n");
" H* V7 m, {# g# u fflush(stdin);
g4 ?% g6 @1 n1 ~) k6 k2 O: O return -1;
X! q k/ g# z }1 O F- o2 ~( w* Q
printf("opnd出栈:[%f]\n",b.data);
" D; a) {: \& R( x8 P4 r if(Pop(opnd,a)<0)( O0 b5 [: [4 e( b
{' Q" i- F7 x9 t& x% h9 g
printf("Bad Input!\n");
# [% L8 t2 Q1 K fflush(stdin);
/ u' }' g( N5 j7 e2 g* i: E return -1;" q. R9 \. ~! L
}) i" ~# U# L% o2 m
printf("opnd出栈:[%f]\n",a.data);4 g) g9 l0 R$ D/ o
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
6 f' u7 V0 r( K Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
' A1 `. ~( X! S# b1 S% }# T printf("结果入栈:[%f]\n",opn_tmp.data);
5 @4 n+ L1 R+ B/ q* @* e break;
: R$ I2 z' c6 C+ z, o }3 B3 y' X) r2 Z' y' U8 O
}% u5 h$ u0 N! i% j+ b5 k, J- Y
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
% {1 e6 Q! d! R }
! B& o* Q( [4 W GetTop(opnd,opn_tmp);+ [" |+ s. j9 L2 M
DestroyStack(optr);" b) Z \' v/ h4 p2 g! E
DestroyStack(opnd);
( Y! Z9 U' }0 `6 U9 P return opn_tmp.data;
' }) [" d+ \2 l7 c. n# [}5 P. M9 D, q& W. F( Z/ Q
8 j' W3 s! Q7 O. l; ?! achar *killzero(char *res,float result)7 l" U* p9 L Q6 O
{3 |' a4 {& k/ j8 Y. _9 E
int i;% \% K4 v! G% H# E7 J
" p N1 E, q% y% D, O9 `7 e sprintf(res,"%f",result);
' e$ N0 m9 v R5 q5 N0 @( J6 j5 P i=(int)strlen(res)-1;! f+ J% |8 N3 o/ b& i% f% s
while(i&&res=='0')2 R6 _& T3 y! r. d& C
{
3 G( B6 ?9 U5 O' F2 C* j3 x( I/ v res='\0';
& j- S' ^& Y- {) J" T$ u i--;' Q3 r0 d6 w8 w1 P
}
! u. e. p7 g8 F/ |: h( ~ if(res=='.')' \" D0 g* `0 X ?8 O4 [' J: P# _
res='\0';" b" U6 m3 N8 A1 G
return res;. e6 @; R! c+ ]7 m: a0 T2 h
}! V$ E9 Y. `- @. E; ^( `
7 [" H6 r5 D1 a7 d: e' fint main()
7 B8 [ f6 L8 b5 p+ f. o: p{2 B, [- \1 x: W
char ch;
5 A, E; K. T4 F2 c. y( T) b char res[64];% W' t0 Z& F* {" R/ b% W
float result;" G+ g7 e% c; q9 U4 z% Y8 D, G# t/ W
while(1)
$ `5 o2 x' O0 |$ k% a! e% _" w! U {
1 F6 S/ _1 G# u/ G4 }& S3 a result=compute();( O! F+ S. k6 X6 F/ j
printf("\nThe result is:%s\n",killzero(res,result));8 T9 G( l5 P" E$ ]. M
printf("Do you want to continue(y/n)?:") ;! [2 b/ |- E* l! Q0 L2 O# v. Q
ch=getch();
2 k: J) w# Y) ]4 j" a putchar(ch);& p1 I {5 m0 Q4 a9 Y& F3 E
if(ch=='n'||ch=='N')
2 b- a- z/ j" C1 W; R/ v break;/ @# V+ m) a& [& }
else/ e* s4 h" V8 p7 z8 J
system("cls");
3 Q4 U$ \$ d, ~8 e }3 K2 Q! _$ h5 }$ G
return 0;
; ~. c! @, T' I g; r$ S}! Z% g2 b+ Z$ b* B, p; ^' w
5 u, d- L9 }9 i4 E3 k8 V7 _[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|