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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.4 F1 V2 g, j3 R! }# r" y" g n
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
. r* N, ^( {- M' B3 J3 x/**************表达式计算器************/4 a9 t! L6 x% u/ e, h
#include <stdio.h>3 \5 o P0 ?6 k; T l- u0 q
#include <stdlib.h>
1 O$ Z! n1 O/ I% F#include <string.h>
0 X$ @/ X$ T4 A4 {7 M: h#include <conio.h>6 N( y) D; D. l! \
#include <malloc.h>: F) Z9 L7 u @# k, b. m& o ^
8 Y! |: ]; c; W! u9 O#define STACK_SIZE 100
3 ? |' X* ^, V: W" d#define APPEND_SIZE 10( G/ Q C0 m6 X2 @/ Q9 s7 l
! o% S! R& ]# ^" J3 Qstruct SNode{
1 a- ^+ U' P) `8 c/ _ float data; /*存放操作数或者计算结果*/. I- `& P9 I& V! x9 t+ U7 x
char ch; /*存放运算符*// c- y5 S5 h# P& H4 p; ~
};
, Z+ n3 v0 x; r/ k
1 Q- [1 j2 W0 _4 v) T3 \5 \4 pstruct Stack{
" X: E- i1 ?/ ?" @4 Q SNode *top;
* ^: A K! F( n" D/ z0 Q& | SNode *base;
) n* k' N1 q8 ? int size;" O8 `6 f4 R6 p6 @# }: |( [( K
};/ _ E/ r, ^* E4 n0 f
! V F6 B2 z6 r! G* |0 U, { m$ i
/*栈操作函数*/
/ n: I" [2 `* l, U7 Q- Nint InitStack(Stack &S); /*创建栈*/! z" r# D/ j3 A2 Y o6 @
int DestroyStack(Stack &S); /*销毁栈*/4 P: c" r& U+ x/ b' |% C# M; c
int ClearStack(Stack &S); /*清空栈*/
5 ?& _; W& K. ^int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/% M9 d2 E1 i& F+ X" m4 u" G
int Push(Stack &S,SNode e); /*将结点e压入栈*/- t0 h7 i; u) C& Y# K [+ g6 |
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
5 `& w8 i. _: x# w1 t- u0 x0 ]: B3 g0 ~) a7 z: S7 U* i- L$ P3 F; [
/*表达式计算器相关函数*/
; N( ]3 t+ L! a: lchar get_precede(char s,char c); /*判断运算符s和c的优先级*/+ v) i8 A0 _, T$ z7 E4 a
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
. _" D1 }( j" S& d1 U+ p' K4 ?float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/8 e, J# Q7 B) o+ @/ E7 L
float compute(); /*表达式结算器主函数*/" J; e6 Z5 C* S
char *killzero(float result); /*去掉结果后面的0*/ 9 `9 z" g2 `0 e. `, `( Y( b
. C# A, N o5 d Y! V) y/ Jint InitStack(Stack &S)# I: U; F! L4 x
{- u" O$ e6 C8 [3 a4 ?
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
8 o$ C K v# A% ?( l" S' J' |* ?" m' D% ^ if(S.base==NULL); l3 {: J) m+ L9 _' `# a$ e0 m
{' h, @0 T0 N3 @* p7 g) n8 }1 \
printf("动态分配内存失败!");
& ]$ A2 `/ m4 D7 g) s0 p' R& Q return -1;
/ Q* c" a5 p0 M) h0 N }
& L3 U+ Z' ]! N: d& C S.top=S.base;
7 N: M; m0 o* g0 e0 ~8 c$ P9 t S.size=STACK_SIZE;
& k' n6 F s* ~" P return 0;$ {3 {6 b1 q6 A9 L$ z, {
}
+ d6 u8 _/ k0 S3 @: s% k% \' E& h7 B( T' [
int DestroyStack(Stack &S)- y- }5 o% z9 ^; u8 p- E: Y* q
{
4 {0 J, [) K! K' n M free(S.base);6 L5 ^6 h: p M
return 0;$ u Z/ ?7 v7 E. h9 a2 l
}& E/ c$ A1 `% b1 _7 n
8 t0 P' U9 G1 Y
int ClearStack(Stack &S)3 i; V( }7 R; d
{2 z! }/ l+ H1 e' L: H6 p4 ?
S.top=S.base;& D( l+ ?4 J8 k/ c. G5 w
return 0;
$ S% }( z( n0 L}
4 Y% H9 p' a& m' j
7 f' X( q$ z3 rint GetTop(Stack S,SNode &e)
: [+ |( P: o7 G5 J- a3 X0 ^/ L{
& M7 F) _: ~) y1 N2 b if(S.top==S.base)" M( P m- |9 z, S+ T; Z e
{& e, ]+ K) i, [2 Y9 ]! g
printf("栈以为空!");
% w, T- y1 A2 X7 \+ Y' A return -1;7 B) E5 @9 J2 f9 J
}
4 x" ], B; d* L1 p; q3 i9 k' ~3 p e=*(S.top-1);
9 c" M& r" w+ {; u! D; d' X4 } return 0;) h+ [) v: r: l' c" U
}/ l3 g& Q; |+ w* {# G% h$ e0 ?
$ x; [1 l( b4 w
int Push(Stack &S,SNode e)
: S! K* V( N* [0 V{
- [ Z* @' {; S7 G9 p" e: m if(S.top-S.base>=S.size), r( [2 E: ` [
{ Z* D4 S0 ~" B6 h6 c5 q' ^% i3 W
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
8 E* l/ v3 \" V; K$ l# u4 Q& B! m4 Q if(S.base==NULL)
& Q( a' ~+ |7 u: A* y0 O {
% B' b8 a' z8 ^! i7 A0 O8 z/ ~4 [8 O printf("动态分配内存失败!");
: V; p& X' w. r; ?3 \4 X0 ` return -1;
. X" O, Z/ s! H5 A$ | }9 z E/ z7 P9 T1 y9 m3 L3 a
S.top=S.base+S.size;
1 x1 l" q3 R; I S.size+=APPEND_SIZE;* F- C6 F0 v; U6 N0 G( z
}
2 i* \9 T/ V8 v5 N7 b/ c. m( c *S.top=e;
4 ?! {$ t5 y: K8 w5 L& I S.top++;
, ~" S0 r1 s7 y/ E return 0;
# m( G9 p7 N, P' K}
$ c" r! w" L# x; e0 W8 I0 s% L- j' S: q5 D
int Pop(Stack &S,SNode &e)
2 I* }% v5 U N{
# {! l2 i9 l# F0 B; u$ K1 Q if(S.top==S.base)
- j& w$ g4 n3 O {* O1 s$ b I2 o j) G
printf("栈为空!");) z! y9 @2 I8 `
return -1;
* P! s+ ^! J/ v5 B; P" v7 z- n }
2 G+ ?& f' L; _ e=*(S.top-1);$ V) ]1 n6 l. _' S+ P% y2 Q( k' D, M
S.top--;- t! v% ~: W9 X& l* O+ c
return 0;0 E. x7 |1 N- E) h0 s
}. g& i+ C* k% k0 s% R
+ K* M) T* a( K$ z) `$ Q/ Lchar get_precede(char s,char c)
# S2 X6 d' H5 F9 F% V$ m{
9 w8 v w. H& G3 ]- {# {6 V# U* f switch(s)
' ~5 B* X9 |8 J; K' e3 n! I! }. K {8 t9 F! ?9 ] x- Z! g m
case '+':
8 Y. `" D* A/ h- n# L" o { case '-':5 X6 ?& E6 {6 o$ Q1 i7 T, N
if(c=='+'||c=='-')
2 {3 g9 M) Z4 g* ~8 j+ ~5 e, E _ return '>';2 Q$ f% ^5 A2 i6 `" f
else if(c=='*'||c=='/')( I! h, N/ j1 L" o3 @# Z6 R+ n$ n' U, W
return '<';
# i' z9 b7 ?# x3 y" p& |9 { else if(c=='(')0 z3 {5 L* ~4 S
return '<';
9 y; D: i. w, E+ A) F: b# J8 `9 } else if(c==')')
" h1 f, j# p$ b. K4 I* J Z$ E4 b return '>';- K" l% m1 u, A6 x9 b' x2 y* @# M
else
# i# x! b8 o7 ^ N, Z" _ return '>';
, D0 X% H2 K8 J$ M& i case '*':
' ^* K. z$ V( x9 u case '/':" ~1 ^1 Z' u7 k" P6 m- A
if(c=='+'||c=='-')" j( @7 D; n% n1 w. k& x! p2 ~6 E' ` j5 R
return '>';
* ~% j& M' n6 R! o0 ? else if(c=='*'||c=='/')1 M7 w% ~, t& r7 @1 X
return '>';
& U3 ?& w6 s W else if(c=='(')
0 U' f3 v5 x1 `& ]! V% k return '<';
' D# s$ J; s1 g7 ^9 C0 [6 | else if(c==')')
' e* ~( R' O3 J" B return '>';
! U: }# t1 c- b! u- V else
& M" ?* {5 m& X return '>';8 O! _: p5 ?- E5 e/ W$ w" C
case '(':& k9 J2 _) N% D! K! j* P
if(c=='+'||c=='-')
4 E. g) _6 p" y; G9 Q2 q, C return '<';
: \; W1 y9 w/ h" x: m0 k; S else if(c=='*'||c=='/')8 e+ }( L" a$ h- }
return '<';
( E' p3 W5 J! @# B5 h$ J else if(c=='(')* ]) U$ H' \4 _% O! @2 [
return '<';
- T+ D8 z/ a5 V! d6 B+ n; z$ p else if(c==')')) A7 X5 H. C5 R& Y' n
return '=';
" [2 l. I' \; a% F' p$ i e9 C6 p else! ^2 E: Z: W1 ~6 f( _
return 'E';4 I/ ~* U k; B6 O& D7 s/ \: S9 }
case ')':
8 s* G+ \5 [( O* j% } if(c=='+'||c=='-')
, ]; w/ p; T) v: t O8 \& w5 m1 Z return '>';/ @& |. C* Y, \3 s% ~
else if(c=='*'||c=='/')
" G- h: _/ T7 c return '>';. k1 X" D/ E; D0 j7 l; g
else if(c=='(')
3 M. e w2 Z0 ^5 b3 O; M: r return 'E';
$ [3 g3 p2 y b9 Q else if(c==')')# D' r$ _6 V7 ^; E8 [! s2 a+ p% x0 t
return '>';/ \, Y* x& Q, [, v7 L/ q
else
/ s/ k0 s! |3 H% R8 a- S4 m. N return '>';( Z; d B' p5 y. a& p
case '#':
2 o! I- ~- ]4 H# z if(c=='+'||c=='-')" q P! c) z! q$ o
return '<';7 y. t: o1 P! L p, b( G
else if(c=='*'||c=='/')0 o1 n8 H" ]" p) R" Q
return '<';
/ f; q+ l& @& p; ?- g& m- K! r; k else if(c=='('): Z( a" h3 ^- P
return '<';; ?+ z" D& z5 s/ s% n+ ~/ P! B
else if(c==')')
R1 G w: v6 G' p" D9 h return 'E';
" j, z% Y$ V- B3 p$ q else8 p% ?$ V Y5 i; Z
return '=';
2 Y" O$ O# b2 }$ I0 B% ] default:
6 E! b! @4 E. X6 w C break;) p. u: Z' p4 O* j! M
}
9 V* [6 p/ d2 w5 J return 0;
& q% w2 |. Y* }, K7 F2 |}: a: M$ S2 z0 u1 ^
2 L$ h, h% J, N# [
int isOpr(char c)
: C- u+ ^: N- @ F) ?9 X3 _' g{
2 F" Y- t: i# w$ ?6 @2 E3 v if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')2 p4 Y$ o) T. G/ Y# v; v
return 0;
* Z n& v. k/ |4 h else & }5 q; [) }6 |
return 1;
9 t0 W5 X1 Q+ C2 n- T1 {}
9 |. A/ u& B1 s
% t( @2 a! L. _- I/ ]float operate(float x, char opr, float y)
+ f0 b8 v& T' L4 g1 M1 K/ M{
4 o! v+ m$ `3 I. t6 h! L' z- p5 I" {/ r float result;: z) b7 Q; N; C0 K( B* F; a) \
switch (opr)
; b$ Y; j2 k4 _2 i. N7 G4 k0 s {
u6 k0 U4 K, C+ k( u case '+': % w+ r. p0 M+ Q, L+ d
result = x + y;1 C+ c/ Y: I* P3 b* }6 |0 ^/ D
break;
2 I0 ~, g, o# x- z5 I case '-': + M; R, i9 i6 Z/ ?+ u
result = x - y;: K7 Y4 G7 n' M7 S3 l3 Z% v0 V
break;
/ |6 u) D6 _& D9 h7 ], U( D case '*': % }2 Z S9 P( h' X- R$ g
result = x * y;
4 E* n- `5 ~% i X break;
! e! s8 X1 Q6 \$ [* h a8 R case '/': 4 w$ o4 z2 M5 X
if (y == 0)# z" W. P1 I1 A
{
3 B& ^/ }2 e( Y v. `/ h& E6 W/ c printf("Divided by zero!\n");7 ?- u+ ]; V E
return 0; X8 m2 f& a; P$ `
}8 S: v; e9 L, ]6 s. Z/ Q
else
) ]% v6 {% i& N( J2 s {# J3 H) A7 y6 c4 k/ n% w; v
result = x / y;
* T3 W- a7 P" y" n- F break;
3 a! }+ b) N! i }
% I' f! A' b. t default: 2 x9 R& e* @0 ]
printf("Bad Input.\n"); $ H/ `% R z, g% j
return 0;8 u) T+ O f! h8 K- s' j
}$ P* O: N* ]9 V" [9 L, E
return result;
3 u3 t5 w, p+ |+ P6 a5 {$ T& W. {}
, g% x3 c6 K+ y) V* m3 ?
1 H( h% J- W9 m4 kfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
# n8 Y. g# l! `& }' W: u{
: T8 [9 s, V6 L% D$ ^ Stack optr,opnd;
4 `1 H/ \. ]" X+ l# C3 R% M struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
$ q0 Z+ ^0 w0 D! i3 H char c;! i/ B7 S4 f" T* O
char buf[16];
1 I5 w8 G3 A! n) j1 Q int i=0;
) G: e! y- m+ j0 Q5 H% m7 L2 l; E # P7 E p7 w. u& O
InitStack(optr); /*用于寄存运算符*/
5 w/ t8 j `5 \7 `, n; p InitStack(opnd); /*用于寄存操作数和计算结果*/
) q/ W2 F5 P+ n$ r memset(buf,0,sizeof(buf));
3 E3 q; C+ f6 p: y) i ) {" [# p+ h k! l( N8 P
printf("Enter your expression:");
7 ?" ]5 G$ [5 K, r( N7 [% ^$ ^ 6 F+ _" d t; H: f$ X; o5 a& x
opr_in.ch='#';# e ?/ b5 } k+ J$ u; G
Push(optr,opr_in); /*'#'入栈*/
+ Y$ y$ h7 K; \7 [" n GetTop(optr,opr_top);" M0 K) z- H8 \ _ `. W
c=getchar();" l ? E( Q6 j3 H8 g: V
while(c!='='||opr_top.ch!='#')8 e0 |# K! U1 h! q( t' Z
{
# ]2 D8 s6 ?8 t) @8 S if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/$ A& k: `1 r+ J8 W# h9 T
{
2 R# |$ S0 T9 d. U buf=c;
; h2 `+ g% d2 ]" ?, B& W# G9 E' S! @ i++;
; h4 g6 }; H: i" ?- d c=getchar();
& t* j0 B- h+ S" O }
U4 C4 h0 P- ?( v else /*是运算符*/$ M; U0 h$ V6 F* b
{0 @2 G5 k* o( F, ]7 ]
buf='\0';
* O& }2 q" o; n+ \) F if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
; G3 K! Y+ q/ a, l {: F/ N& i: ^# a, R) r
opn_in.data=(float)atof(buf);. t) ?" c/ {5 T) j6 a
Push(opnd,opn_in);6 i9 f1 `# g L7 L2 q* x
printf("opnd入栈:[%f]\n",opn_in.data);# x9 \% x# a' W( g1 w: y
i=0;
- C" A( O. Q: l- k2 r! Y memset(buf,0,sizeof(buf));
' w1 m% S1 x) B/ x, o3 W2 R }; c3 X: y! D3 h
opr_in.ch=c;
2 W! L; o& ^# t% R3 a& @) _ switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
+ `! }" n( s; U& U/ ^4 b3 ` {) m0 a( m- k2 T' @3 [
case '<': /*优先级小于栈顶结点,则运算符入栈*/
/ R" M4 p7 f: f Push(optr,opr_in);6 w; b7 {6 Q0 B, T. v7 ]# z
printf("optr入栈:[%c]\n",opr_in.ch);
2 c5 p3 l8 u( T c=getchar();3 O0 q; F' }' S5 E' \7 T. n
break;
( Y" c3 {) h2 E" {' H# _ case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/+ R; n1 O* J6 l2 O+ h
Pop(optr,e);
K& w5 l2 Q+ X) c: ^0 `! A9 d printf("optr出栈:去掉括号\n");3 {" A+ k8 c; z. E' S- S. e5 d
c=getchar();5 g, d) e+ B8 l0 S) E
break;, R3 l2 Q0 i5 r" l# X
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/: P* n! I1 D n$ p* g
Pop(optr,opr_t);
4 j3 ]; S$ b- k# S% n2 L0 m( j printf("optr出栈:[%c]\n",opr_t.ch);0 b+ C$ Z4 g' H2 R4 @% r& G
if(Pop(opnd,b)<0)% W7 y8 _8 ~7 L7 f; V, j3 `
{
7 u( G0 T; Y8 S6 g& a: ` G* ` printf("Bad Input!\n");: k# \2 q3 W+ ?4 x1 v& R' w
fflush(stdin);
7 ?) w9 k# p0 `6 w return -1;2 |1 y: J" p1 W1 F! |* T" C3 r
}
( P8 W0 s) j0 H U% @) f printf("opnd出栈:[%f]\n",b.data);) k: ^* v5 x% ?/ }# Q7 k% ^8 t3 F
if(Pop(opnd,a)<0)0 y4 j" O6 e( i; V0 O; Y
{) y; [- e: G& b/ T9 G i1 k
printf("Bad Input!\n");
1 K5 ~) c3 c. U. v6 G6 R fflush(stdin);% U4 n/ K! t% a/ u
return -1;
$ o2 k# [- X! V/ z }
! `& k0 q u6 }( t+ o printf("opnd出栈:[%f]\n",a.data);
3 L" ]8 Q5 Q; G: @) g* O opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/1 x1 b9 L* B- s9 o F; u+ K3 j3 ~
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
( l/ W% w7 h* u6 w/ C printf("结果入栈:[%f]\n",opn_tmp.data);6 J. c# ~" t. W8 a. l9 K$ l
break;
" ~7 k: ^' [" H5 G* j+ C }
9 p. s/ F4 N5 J8 b8 w, o5 `1 ~; ` }* ]1 u- b( K1 O/ O
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
0 A' D5 s8 }0 W }0 u$ ~/ a8 S% t: m% M$ d1 r# I2 x
GetTop(opnd,opn_tmp);
7 @% X+ _: C; C2 c DestroyStack(optr);
4 _: H4 W1 h, {$ o DestroyStack(opnd);) o. u1 @+ ^- u( U4 p2 H
return opn_tmp.data;6 Y6 d% |9 X% G6 N& K+ S: O, z
}
* t- T' v4 X5 E0 E- B# D8 N
3 |3 V1 J* @- \% L3 i8 `char *killzero(char *res,float result)
0 Q" ?" {. O$ w4 ^{% ]1 O- ]5 f, H4 v* d
int i;, k5 _# g2 f% Z9 O3 h
) K) c5 I+ a5 ~: e3 P k sprintf(res,"%f",result);
' `% `7 k. y- h i=(int)strlen(res)-1;$ w& n9 p0 ?$ L! D3 A3 S' Q9 \: }
while(i&&res=='0')
) M" r3 t( U/ i) b. T {
' g0 p4 r! X" u$ M7 X' X res='\0'; A/ R8 J0 Y; D+ `1 o8 S; o
i--;
- h$ V, V- V" `7 k, h }
; I% Y% w" C7 i6 t' e7 h: v if(res=='.')
8 V8 j8 ?# r- l0 Y% c8 K res='\0';; @% x1 D8 _: Y$ }$ ~4 t$ i4 K, z0 r! z
return res;, J+ M7 i8 i& M( ?
}7 L+ m! {( o5 h$ ?: G4 |7 p8 Q t: W+ y* u
6 P3 \8 b& l8 q( T! q2 \int main()- W( G% a1 z E4 f4 O+ x1 Z
{$ D0 u: @- f. K4 ?; s
char ch;
6 [/ {! l, f$ a5 l" I char res[64];1 L b# f. D# K- K, P' x" A! U
float result;2 e" Y+ n. k# w) a* V
while(1)
0 @/ K" r0 ] x1 ]; } {1 O2 [9 M2 Y3 |! m9 f" z+ I
result=compute();5 R0 ]1 u5 @+ M! v
printf("\nThe result is:%s\n",killzero(res,result));
1 T: [2 `: A; J3 g- @' L printf("Do you want to continue(y/n)?:") ;" b: }* e6 L& s- W5 ^; k
ch=getch();
: f! f' p# y3 Z4 L+ T0 E7 }5 k9 V putchar(ch);
" V o: U* H- K- P if(ch=='n'||ch=='N')
6 Z- n# W% k7 M. L2 B1 I break;! b( ^1 |. S w
else0 }+ L0 u( K/ [
system("cls");
0 t0 Y+ J: l5 A) Q9 p }5 v+ b* {8 W% M. d9 a5 P8 A! o1 e2 \
return 0;
! b) s; H% |! Z% V% H$ D5 G}
1 e; i5 m/ H" K. J! u# U: ~3 c; Z% k
5 ]8 q& G4 a6 B[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|