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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的." D- X2 c! x( |% |) ^, R
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
& B4 S. y& N ]8 O2 {/**************表达式计算器************/. ? `* w4 o8 S( i/ \% c
#include <stdio.h>& N2 |3 b* z5 l! ^
#include <stdlib.h>5 H8 X* d) i) O; \) B V
#include <string.h>9 J u& {6 `* y/ z
#include <conio.h>" @- i# u. [- i% z
#include <malloc.h>
7 U Y- [( o! ?3 P- l8 g
. [1 {% C+ b# g# n4 r! S+ \#define STACK_SIZE 1002 M o* o& d5 _8 P
#define APPEND_SIZE 10& y+ A% ]8 h7 a
; _0 i" I1 c# p( }7 x( Z
struct SNode{3 r, z) _+ h6 S) Y' D
float data; /*存放操作数或者计算结果*/. s2 M/ o* r t( I0 _5 V
char ch; /*存放运算符*/- M3 K: D7 j E% N* T$ x
};
* O: y( i4 c# p& y
4 Q1 L( y5 s& H- T& W$ n8 N2 X$ L& Astruct Stack{
0 `* m8 t+ i1 v5 D4 b SNode *top;
* P! c) _( ~. E SNode *base;
, T; L5 E% j- q) q8 g' A' n6 r int size;
; @9 Z7 r! v+ `4 W; d, ~}; C' M& E6 j, D; G3 i+ }
% C& s% R9 a# H+ W/*栈操作函数*/
3 J# R2 n3 y9 t% O0 nint InitStack(Stack &S); /*创建栈*/
3 o3 P6 w# m1 k+ B+ w" B$ mint DestroyStack(Stack &S); /*销毁栈*/* e6 j1 [9 e- H
int ClearStack(Stack &S); /*清空栈*/
8 { \4 a9 P; F1 E) bint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/9 A2 `' h( F( ], V
int Push(Stack &S,SNode e); /*将结点e压入栈*/
: b3 O. u7 q) W( y8 f bint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
4 N7 v, `. Q% a' {( ~" M2 {" I+ E% ^6 S! D! _9 ^
/*表达式计算器相关函数*/
4 d$ T- n1 [8 r% u6 Pchar get_precede(char s,char c); /*判断运算符s和c的优先级*/6 J% V }4 C7 d0 f
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
3 Y: |4 ?! o( O7 ~8 Q @float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/* @8 Z/ Q' i2 q% c: ^( o
float compute(); /*表达式结算器主函数*/( q4 [8 L) c: G. D: u0 F
char *killzero(float result); /*去掉结果后面的0*/
# }! i; ], I5 Q; L4 V* T$ D* h
7 z. n% E' l" l; I6 z: {( eint InitStack(Stack &S)" _& B" l1 m7 A; X0 Y% c; r
{; R) B2 p: A5 Z5 V/ M3 b
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));, J( |6 h; F7 _/ h2 `
if(S.base==NULL)
: \; p( Y) E. G8 y, K- u" O* d {5 Z) }( K( z, x" ~7 J+ g( s, W
printf("动态分配内存失败!");
1 g6 b5 X$ G+ b+ j. u% O. B6 p return -1;# P! e8 v# k7 b& N6 ~* c- w$ ?
}
% \3 g8 S, {2 b$ H1 `, I O S.top=S.base;# \) X% a) z2 v) N5 Z0 ~
S.size=STACK_SIZE;& S" P* w( t0 B! E
return 0;" t" f8 Z# e& n$ _
}* x$ p5 x# |0 n- r" a3 h
; m# O$ z. w8 V1 q2 O
int DestroyStack(Stack &S)6 \2 J: [8 ]; p+ r: w) }4 C8 r( B$ q
{1 t1 p5 D# I' Y% _# R8 b% u4 W
free(S.base);% a% s9 g6 r3 {7 t
return 0;
6 @7 N' c5 L) S) e; i7 \}
]& s& ` ^1 a. P
- a# r( p. o" x% B+ nint ClearStack(Stack &S)
( P4 s4 }& p/ d4 o$ d! _, v{8 X" W) L( H. c) S, R) B0 G
S.top=S.base;3 D/ j9 @) |2 H4 \
return 0;& ~: E4 z5 N8 X0 ]+ n# A5 D
}' r: y1 t/ J' h7 j; t9 S
3 U! ^3 \6 l5 A% g3 p, m. P, C1 q
int GetTop(Stack S,SNode &e)
3 m: A% s- N. q3 H; X& J5 ~- X4 Z{
) h+ M: P* s9 `# F1 n if(S.top==S.base)6 j I7 k2 h! i. E" b, l9 V( r
{
+ Y# w: ~1 X/ {( O7 }6 { printf("栈以为空!");" e9 I' ?& W/ T' x) h; q
return -1;& z% u# z' |9 K; X2 q1 W
}0 X0 F8 _. k$ P% j- r9 Z
e=*(S.top-1);& F7 f% G$ {" i8 ~% [
return 0;
9 N2 f5 a4 n4 Y. V}
( H" K0 G+ L5 H# i' x9 A! B/ P
, e% t. `* @6 E! Y8 }# eint Push(Stack &S,SNode e)
" y* W! z" \' r/ F4 r; X' Z+ Y{
3 e. J/ D! J! S5 J0 p0 r( v8 c if(S.top-S.base>=S.size)
& ^- k; {$ D3 d! F {
7 Y, ~2 I* P+ _9 [ S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));" c- S" d1 n- q- K6 N
if(S.base==NULL)
4 P* p6 U4 _0 H9 Y0 b& @; } {2 t5 n- l" \# ^
printf("动态分配内存失败!");
- z! H5 n. x2 ~; g6 X& @& o return -1;$ L4 E( B# e1 V' O
}
5 U$ r8 X5 q k- n7 q6 W S.top=S.base+S.size;( E% l- v. I8 L' X$ p' A9 d8 x
S.size+=APPEND_SIZE;/ h5 u$ ?7 N- e% f- T: P6 c
}
0 X2 B8 U; O" {' ?2 R4 y *S.top=e;$ ^# b, v0 M7 D+ P* ?8 `
S.top++;6 G. a/ T. J9 v) c
return 0;
% {" e% N1 G2 V}
* e1 ~. w9 N8 S
- B9 ?; E% D* ~7 W# x7 O# C) eint Pop(Stack &S,SNode &e)/ i, S3 E4 s8 w( g0 V' L
{+ U6 h4 }! d7 Q* Q
if(S.top==S.base)
3 I% T2 G7 E) p {
5 I: N7 [: J2 v t+ _* \; y; J printf("栈为空!");
I! l4 D1 T3 o4 z return -1;: P6 J. X& {; q4 W
}; j2 I7 q% c5 E6 E7 r
e=*(S.top-1);
u$ R9 |0 b& u# W2 Z S.top--;) {( i6 x1 L/ t' p
return 0;
5 s) U; K* S. Q9 ]7 _* I; Q}9 _# L% q7 D6 a8 M7 y6 b
, N5 {& {3 ^: F R- u
char get_precede(char s,char c)
( {. X. T) r7 K5 [1 A. v6 q V{9 N! e* C L' |) I& b$ P
switch(s)
6 F7 r. ]# w8 L2 N1 V {
* D& W' ]! f- t9 V3 O) D5 q case '+':
: H; w/ u: a# t" b- I0 w: ^ case '-':
6 Y/ h4 @6 g8 j5 S, [$ r if(c=='+'||c=='-')
& M5 e8 ]; |* r5 X, ? return '>';
" v5 @0 y: ? T! C$ J0 N else if(c=='*'||c=='/')
; U( k$ @, f2 L* {* w# \$ E0 Y return '<';
W. X Y) Y+ @2 e else if(c=='(')
! w! V/ {# G/ ? return '<'; U" A( R8 x- ]% T, W
else if(c==')')
* x8 {: |5 P( ^" D, P return '>';
% u% F6 e: C$ j! { else
+ y8 S. [/ g( L' c6 X+ }9 Y$ N* k return '>';
* m. ?& B1 H) q& p {9 b case '*':- \3 \0 @: {7 u% |9 i
case '/':# Y4 ^$ H0 j# [7 s: {0 n
if(c=='+'||c=='-')
( A5 u& q. |) E$ \' V5 W1 P return '>';4 T: s% p1 `) G: `! p3 y
else if(c=='*'||c=='/')3 h: H$ R+ ` A4 L
return '>';$ G, M: k _1 R+ v, |5 D
else if(c=='(')
5 E* c4 g( K* p return '<';
# F* B" J0 J) W, }% C( C! z else if(c==')')
- I+ I+ T d, z+ Q2 D2 u$ Q! L return '>';
7 G* w( w4 I. T1 q else
: {) ^# U- R6 M) U- b return '>';
1 w0 b v3 `' i: p- x case '(':9 @# g9 v$ f6 |7 H3 j* ^
if(c=='+'||c=='-')
; e* d7 c+ U& L7 I. t$ w3 [ return '<';" C' g2 c+ _& N: v" L
else if(c=='*'||c=='/')
3 C) M6 t8 h" h4 c; s% G return '<';# k& C, W3 S3 x% U* i, F
else if(c=='(')% Y1 J! x: M; ^0 E$ I6 s
return '<';+ n; H) ^3 z: f8 j V4 ] q
else if(c==')')
6 B5 i0 l8 H! l return '=';
/ k9 u/ Q1 ?1 j6 v6 o else% m, l. y9 R+ ~, r
return 'E';
% Q2 y$ z! ?) n/ F- t9 S( M case ')':/ `: ]8 K( U" j; l( M
if(c=='+'||c=='-')/ `$ K4 Y$ m- @6 M0 V
return '>'; f- J) k+ H2 x/ T
else if(c=='*'||c=='/')
2 w: K" A: w R7 Q return '>';$ r q5 Z' d l& w
else if(c=='(')' P# [5 u, ~! M4 l% R
return 'E';1 i; t. I! n; t+ t7 O
else if(c==')')
3 j: ^2 s& X3 a; P" h return '>';
/ F7 C4 q5 p; X else% ]% ~( E& l3 [
return '>';
: M9 C1 d; t7 Z0 e% n' w case '#':+ h5 O+ H( b1 a; }$ i
if(c=='+'||c=='-')3 ?! R7 j( A: \ q' I0 p
return '<';* x6 B3 z6 d( y; G4 P% i' } N
else if(c=='*'||c=='/')0 `* I0 J7 c) u! r! z5 o) ^$ Q
return '<';) g `9 n! A$ C. T0 ?0 S) S% v
else if(c=='('), k2 V9 _# Y! H7 x" ]4 G* a9 k9 d
return '<';
9 ~% s) X2 E6 o$ Y7 V/ H( o else if(c==')')
b2 {- d9 {- J/ Z' T# P return 'E';
# _, J& D7 `2 p; y2 U% l$ ^ else" N* ~, [& D: r2 |
return '=';
7 X; A. d8 x# k0 U9 M/ {6 x default:$ Z3 s. p* r$ ?. V- z( `7 n8 m
break;7 e/ U4 S( d/ V6 t0 ?" a/ ^
}0 G6 @1 `/ u2 h9 a. [4 C9 G4 O
return 0;
2 T, @ `5 t2 S8 F4 g9 M+ P3 ~}. G; P: ^8 x# E' |
8 {# E b8 c% W7 V3 j
int isOpr(char c)9 | e" T! j1 u6 o8 v! ]
{
8 n5 w$ p3 ^! T( N! y$ R+ F if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='); ~6 F+ E9 f" d5 H" q" p
return 0;
) b! V! z- \6 j+ K+ g else # b X a: F( n4 o" {! m( _3 j
return 1;
; ?( z$ ^7 S) S3 e8 C# J/ }}/ i8 j8 U2 b. m2 d
; D3 ]( R$ I; ~( t; N9 Qfloat operate(float x, char opr, float y)3 G0 l+ q& |& `( e( A
{5 F) g% m1 G1 M! z- E
float result;
) Y( ?" _6 `( @+ @- O0 P$ _ switch (opr)
8 g5 v3 [* y5 Y1 G( w0 i1 \+ o {
+ ]# I( B+ h6 p. ]; c case '+':
; p: c0 A( }/ V% O result = x + y;
! {' ~/ ]$ c: b+ h& Q break;
: g- t- |/ P, p case '-': 2 s0 l: I3 U1 c) c4 G' ~
result = x - y;9 ?4 o& t7 q/ [* T. S
break;$ Q! O; z# _' r4 S7 L7 A
case '*':
7 X) Q: u# v9 ] }" e# k, _5 p# T result = x * y;0 Y3 D3 K1 W" P7 y w7 |0 ]' o
break;
& w5 G7 d9 y( z" p+ F- y5 T case '/': 0 g4 H' ~0 \+ z& \& x
if (y == 0)6 ~% m, _- D( x) J0 Z7 W
{
$ A& W, M# D: y printf("Divided by zero!\n");" b) G+ T$ x* ^
return 0;1 T" z% I7 M5 Y8 I) G
}
. ^# t: m' C) a& z6 z. b; z5 F else) _8 W6 k7 v7 e9 L! d, d
{
8 R5 w |4 |" | result = x / y;9 B2 T v+ }9 }) S6 S+ ~
break;
- m4 T3 K6 K# H# U4 c }! z$ J6 ?! f- V u1 s
default:
! D' \6 @( p6 g. S" A( v printf("Bad Input.\n");
$ S7 V2 N: \. }1 x' W' c" e return 0;
+ V! d6 z( k5 T. V; q }
) V+ _$ P% B$ d+ J/ f' B" l return result;% o, p/ [% ]1 x8 {
}
5 m7 W1 F$ O8 Y5 J) Z* }: l8 N# t3 H, K: c3 o* |* e% d! u
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/+ z4 q$ W. M0 `- v8 ~
{. t, q$ g/ i3 h( Y% D' o4 s
Stack optr,opnd;# z; K t% M& L8 U
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;0 ?. [$ C+ @, @( w% ^6 S
char c;9 x+ ~; {1 M1 g1 o
char buf[16];
. J, D5 y0 T _+ I int i=0;( x- w( d H7 u- {% j; `$ C
5 e2 u6 f# c5 x; Q InitStack(optr); /*用于寄存运算符*/
; o4 h" ~) x6 P% c6 H/ s InitStack(opnd); /*用于寄存操作数和计算结果*/
: ^) o4 }7 Q& r: `% |/ s4 k memset(buf,0,sizeof(buf));
7 J# E% I% H* y9 b! @ - i$ F8 |" \+ y* n0 w; X4 V0 Q
printf("Enter your expression:");
$ E+ a; c, w9 h# R% r U' Z$ g9 g ( L6 ?8 n3 x3 E, K, A
opr_in.ch='#';
. l! Q( B' S. B f$ Z. B Push(optr,opr_in); /*'#'入栈*/
3 Q, r+ q+ ?* f: C2 j GetTop(optr,opr_top);
9 W- v! ]2 i- r" V2 r c=getchar();
4 M, t/ G; J" n while(c!='='||opr_top.ch!='#')& u! V2 i* {( v# ~: g$ `
{$ l% z# |; P5 Q @+ U" e9 k
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
" D: l0 R5 v' T# }. o {1 F2 T7 A, f+ o3 W' ]
buf=c; @1 d. Z& t) E0 s/ K7 S4 N7 P
i++;& Z- w1 d0 o* f6 v) q" n1 V
c=getchar();8 k3 Y$ m7 t6 ~8 Y! i
}2 c/ ]$ S F0 K3 T, p
else /*是运算符*/# t0 R4 a! ]2 }# x9 ]
{
0 ]9 o# U9 j9 ^: ]- ^1 }0 Q buf='\0';
$ _) ^! P, @ l: R% B% S0 t if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/6 J8 \2 S( s& j* {' Y" I2 x+ O
{2 T/ b+ Z3 |" r- x1 ]: l- j* H% H( l
opn_in.data=(float)atof(buf);0 U& f8 D, E: o
Push(opnd,opn_in);
& s0 i) ?9 |( R2 I printf("opnd入栈:[%f]\n",opn_in.data);
$ M) S1 k4 z7 l. R i=0;
' j" l) `. i( _& G. s memset(buf,0,sizeof(buf));
" v" @: i9 U! w* L4 W9 ? }* K8 _2 }: Q9 s
opr_in.ch=c;; Z1 o- d4 D0 D. B& y
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/" y2 i5 H3 J3 R( E0 A* M
{
! |+ r/ A. ^2 a# ]) Z case '<': /*优先级小于栈顶结点,则运算符入栈*/% m0 f {4 y' H. T
Push(optr,opr_in);
W3 `4 Z3 V4 B5 B9 b printf("optr入栈:[%c]\n",opr_in.ch);4 G: |4 K* j& \+ W0 h- u5 E1 G
c=getchar();, D$ B$ z* \/ [
break;
3 M# c. F' y6 P! \3 P/ D case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
. a+ m( G4 v1 y- K: H& h Pop(optr,e);4 c* {6 r3 m5 o' d5 X% k
printf("optr出栈:去掉括号\n");
# B: X4 B9 P, |' r" b/ ~, K( p6 u# ^ c=getchar();
; O, T7 T. z5 W+ B3 J- q break;
0 y. L9 L) N1 c _) l& @7 \ case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
( z/ ]4 a0 I0 [( n Pop(optr,opr_t);) b. N% T0 @9 X* {; ~/ ?
printf("optr出栈:[%c]\n",opr_t.ch);
2 `' C0 u% m$ f2 l1 T9 l8 F8 u! i if(Pop(opnd,b)<0)
1 K6 G `$ R/ f6 o. x# q' N8 A {2 U! X& N& r; M2 p
printf("Bad Input!\n");
- E5 l G$ k' t% E9 b* O( \! o fflush(stdin);
, q' ~2 d( u: m9 a3 u9 x @4 Q7 J B( ] return -1;( o* b) V& w$ ?9 ^) `, S
}
+ F8 ~: P" {% d1 j' p printf("opnd出栈:[%f]\n",b.data);6 l+ i$ u% y/ o4 n9 o
if(Pop(opnd,a)<0)
1 u# R2 N* n* _6 E6 z6 z {
* e$ o! J; q \ printf("Bad Input!\n");* P% F4 a5 `- w/ d8 H' }. Q: _
fflush(stdin);2 x# q" U5 f6 Q
return -1;
* L* m; q" R/ g' ]+ U" o: W }
' P. A$ \. ]9 U. Y8 Z9 c printf("opnd出栈:[%f]\n",a.data);0 y3 @; P1 S) h q
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1 v( @" j' D1 j6 ]8 J7 w- z$ V Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
$ v- b+ S+ V# D! H2 Z( C5 d* e0 E printf("结果入栈:[%f]\n",opn_tmp.data);
+ P- e% Y1 Q z" I# M break;
: P( L$ _* H, F }4 p1 h2 N; S# C0 E2 q: o1 H$ B! m
}
- g% k4 V2 i! e GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
9 X _1 L0 @! r# O$ l }* r. ?% m% x# Q% q' T! B" T3 H
GetTop(opnd,opn_tmp);. R2 w6 Y! z A. t# Y; @
DestroyStack(optr);
, U3 _; U( j: G0 |" K9 N DestroyStack(opnd);3 ~& s: s* i a8 ~% K3 w
return opn_tmp.data;2 V6 o! y' `/ w. C
}9 D: H6 K0 y6 x9 v% y e5 K5 E
6 A% @2 U) @/ Bchar *killzero(char *res,float result)& A* m5 U# C \7 x
{6 {) j+ L7 J! u. y
int i;
' |6 i! u4 C0 M5 Z( P' B. q! r- e; o) m3 Z9 k1 R
sprintf(res,"%f",result);
/ K4 `) }) x0 r7 m1 {# ] i=(int)strlen(res)-1;' C( B$ G4 ~4 n
while(i&&res=='0')& k O% B* }) j& h
{
# {. g3 G* L- \) N F res='\0';
% C+ B" g4 \; J2 [# _ i--;
5 y! M$ O& v' Z T4 w4 T }
2 a6 b7 O J% q( D% v3 j2 { if(res=='.')+ \6 {% s+ ]2 R7 h
res='\0';9 i/ r2 }9 x( o! r1 N- t
return res;
$ c# J7 ~* E: Q! `+ A% S2 t}1 J$ a5 h1 w: p$ ?. A: w1 E
+ U& \5 | N2 D& M4 I
int main()
' j# W& z9 C. S! H r$ w7 `{+ t W& X; L8 {: y
char ch;
9 U( r8 b1 j5 U. c$ t4 ? char res[64];
6 _+ U$ r" K6 B6 D" D float result;
( ?* f% A; a8 t* G: @; W while(1)
$ ~- M8 U; R: @6 K% B* f2 Z' s {6 E# Q- G0 `) p: A* p# [
result=compute();
5 _. s& Q {% N0 N- f E4 O( W) J4 n printf("\nThe result is:%s\n",killzero(res,result));( `' R3 T7 _* s
printf("Do you want to continue(y/n)?:") ;, `% R# j ?1 u4 G! w3 S% e2 a
ch=getch();8 `' R1 F- t3 V- {+ x
putchar(ch);
- W4 \- W# i; U( {& t if(ch=='n'||ch=='N')2 j+ T5 m d+ Q: z* @7 T) s9 X$ O
break;5 j# k+ n# N Y3 l7 P
else
9 }1 b1 W* r' G2 T' n9 _% z4 w system("cls");' Z" C4 N- @7 K" u
}6 o- F2 C2 A3 j% y$ c7 b" \$ U
return 0;
9 i5 I+ Q+ k. x1 a! w}
( O7 M- Q; T0 Q K Z' Q9 p$ V P: D1 ^4 Y/ d
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|