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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.4 { ? q8 x3 }
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=8 @5 t, m( [" t5 ^7 @
/**************表达式计算器************/) n1 b: x6 S$ W* j8 W, M' T( @3 a& ?, H
#include <stdio.h>
2 }* `* A4 d# E/ @#include <stdlib.h>8 _- W) l5 }6 \; I
#include <string.h>) i! N" L2 @) _- p$ r( ]$ x1 A
#include <conio.h>
; u5 C' C. y! ^# ?3 r#include <malloc.h>
. ]1 T v4 A" T. k4 ^
6 k* K- s! k! I) m' y$ b#define STACK_SIZE 100; Q8 r1 p+ k4 g2 Y
#define APPEND_SIZE 10% t- z+ t# G6 ~8 D
. i; ~( Q' F2 ~, {4 c! V
struct SNode{
/ j& x W7 \6 U4 C. M7 @ float data; /*存放操作数或者计算结果*/
( O8 ?/ R0 i0 |- U& M char ch; /*存放运算符*/
7 b; z5 W4 f9 x! i. R ^};
* K. S: `- {5 D
% E8 f, h% x, Zstruct Stack{
( E) L1 p2 D% C& W& v* B8 s- Y SNode *top;6 [5 P0 H, |- x8 q" K9 @+ ?
SNode *base;: w. b O, n& e
int size;% f5 v- D! y! T3 S
};
. |2 L. \, ]# n$ m0 E/ i4 q$ n8 e, U' u9 Q* x, d3 G$ z
/*栈操作函数*/) J% U% O- V! G( c8 Q* \
int InitStack(Stack &S); /*创建栈*/$ l1 c) d5 _! R/ f" h) A4 F
int DestroyStack(Stack &S); /*销毁栈*/
& C3 t' E; k1 N e/ j5 a5 Yint ClearStack(Stack &S); /*清空栈*/
0 H' ]6 J7 G5 }. vint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
* W' Z6 N7 K: b9 G, X+ Q6 Qint Push(Stack &S,SNode e); /*将结点e压入栈*/
: e7 h" e/ D% a9 X. w* Y+ Gint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/5 N" m5 [# ^# ~" I: g3 A
+ j' `, [" p# n* `* h/*表达式计算器相关函数*/ h) n* w5 U* o) {; k# U' P" Y
char get_precede(char s,char c); /*判断运算符s和c的优先级*/7 {( v0 [$ q8 o9 G
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
& w& j7 T1 B, K* x* a Qfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/: }; Y5 E6 J f" A: |$ Z+ L* b
float compute(); /*表达式结算器主函数*/6 J$ o3 V" \3 X; N/ i# l$ ~; R
char *killzero(float result); /*去掉结果后面的0*/ 1 C3 ?! t0 w3 _8 j8 n. L
( j9 B3 \" i$ C' W! w# m4 i
int InitStack(Stack &S)
2 g) I1 d) n8 H& W! Z{ w5 Q. k+ y, I; V( u
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
( h2 y* i2 t0 J" T" Y+ d' g1 R if(S.base==NULL)5 Z+ M: ]( D3 w; `
{0 C4 u0 x6 ~* ^/ w
printf("动态分配内存失败!");
9 i& i+ @, T0 C* e3 f1 C! I, S- Z: l return -1;
9 u/ G/ x- y; \$ x$ y }
/ g/ b# V' X1 t8 ~, h' p S.top=S.base;2 _+ X1 o# \. e" m" U
S.size=STACK_SIZE;7 e; J$ o1 C' t! f
return 0;. I* Y ~2 j' b7 o2 v
}
3 a5 @, s1 [2 ?2 Q% c
# L" L1 B, j5 J pint DestroyStack(Stack &S)
# W6 U/ j+ R/ Q" t+ _{
. F x+ Q% n7 Z* { free(S.base);
1 L3 G/ _$ Z* ?0 \ return 0;
9 g$ Y" R; D- |6 I% |; K" v/ d}% _2 x( H; |% p+ E. D- G
, L3 H* H( E3 z( p% O& v( x# z9 A- p
int ClearStack(Stack &S) R) ?0 h: B t& r( l
{0 m% z$ T. p$ x* A: O, u2 A
S.top=S.base;% t/ U2 ]( D8 H+ S
return 0;+ w& Y2 k1 }- D0 R9 j! X+ h
}: q( Z' x* {! I4 W+ j
* @# v+ K$ n, D& a: i# Q. M
int GetTop(Stack S,SNode &e)
+ M. N! g% D' P# _8 o3 W' ^( u5 j{
& f- Y2 v4 q- [6 |* H4 s; V9 W( Q if(S.top==S.base)- z- ^- H! _* ~% H& Y
{
5 J* s' N7 a; O- L' X% O+ j printf("栈以为空!");
( T9 G$ l4 g' v% @" g5 w+ d return -1;4 _; [; @, }; {! J2 G5 V6 W: H
}
# x: `- C9 N6 [" y) w' q" e8 R e=*(S.top-1);; D: u1 K& m- l: `: V/ F
return 0;
) Z" Y- E% n, o) I/ \}* I2 e5 ~* u0 R- F
9 y" t' u' R; J, y& C
int Push(Stack &S,SNode e); s8 N- B+ _& G0 m2 e
{* a; N+ {" ?0 F F+ T
if(S.top-S.base>=S.size)
4 O0 n+ f4 f2 a {- d' b1 ^2 p9 c" M0 k9 j9 z
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));( C: l1 n4 D( T. j0 @) L; t
if(S.base==NULL)
3 w$ [' o+ q9 ~$ D) ? {
: Y5 I, {( ]( L5 N printf("动态分配内存失败!");
* ^8 j& i! V0 Y4 P0 t! h return -1;$ [& C% N, q( _ {+ ^- M; h7 z
}
: x# Y; h& q& O S.top=S.base+S.size; w0 y( \( K' a& |/ p
S.size+=APPEND_SIZE;
( N' {( l% B) n; @; i9 } }& A, p" i* ~+ X* D, _, P
*S.top=e;# N0 z: S7 }; V3 N" D
S.top++;
9 L, F8 a( u2 g# |, { return 0;
, X' r& y0 }8 b1 t}
, M/ G1 ^. n7 I" X( p& ~. N2 s1 b! M7 Y
int Pop(Stack &S,SNode &e)$ P8 Q; u1 I2 l- n8 ~
{6 F Y4 }' A* I
if(S.top==S.base)2 [! G) N7 M' N1 W' Z- L
{; J) Z/ C! Y( E3 r" E& S3 c* C
printf("栈为空!");
" H+ E2 N. I. T1 T; B k' w return -1;/ y9 l* O R2 a- s, R
}
- w$ i) t/ F; ]+ E7 t e=*(S.top-1);$ k" G5 s* f" H8 t5 T9 z$ C
S.top--;! L5 f8 l" H- f0 O
return 0;% O4 y9 r! B( G& o6 H
}
! A' D+ ]6 @4 Z: d3 ~6 g- ?% j3 y% |3 ?( c x4 x0 q; d( b/ X
char get_precede(char s,char c)+ O% n7 M+ m8 n) i+ k8 D5 H* {
{2 z- ^& G4 s0 S% V/ w& H. d
switch(s)
' c0 X" Z3 I+ a9 `3 l+ z {8 D4 L4 J- L: c
case '+': * y1 X6 ~+ `, x2 y7 J, x
case '-':
# \) K) ~5 @0 K if(c=='+'||c=='-')+ N4 y: ?! I, ]/ }6 g- `
return '>';
$ ~; n0 \4 Q( g+ f, E7 C else if(c=='*'||c=='/')/ n; ~, d$ {# n( ~2 P6 A3 i
return '<';
8 A; F0 Q' o, `1 N& C& R4 S else if(c=='(')
: R) r+ P9 B9 f/ k1 o* [# Y) K return '<';
7 _- ?% x( r. \1 p6 c3 @4 l else if(c==')')
?$ R# V: A# z3 q return '>';9 _0 m2 h# E7 t' A
else
2 [; w" N5 `) L7 e return '>';
X2 @, N, G6 w. l# Q- O& _ case '*':
- \1 m/ x6 M* r# J. t( m @ case '/':
. R9 i7 P+ j0 {. x2 d6 h) [1 k if(c=='+'||c=='-')
$ `( \# ^1 c* M- i$ v$ O- o return '>';
; ?, x6 r0 l3 c; E else if(c=='*'||c=='/')7 W1 C( z' T/ x1 R3 t
return '>';. M, U- Y+ l" t' w
else if(c=='(')7 n/ w) A8 d- l0 w
return '<';
$ I7 S( A: Y: I3 R6 q$ g else if(c==')')
( p2 N+ y, v6 T return '>';4 H/ J: X* N* [
else2 |) S5 t: G5 g: ^* O" ]- U
return '>';; E' M% v! v8 ~- k) ?1 X, W0 M K, n
case '(':, ~( t+ }' z8 ?, C, V, N( y- o+ `5 Q
if(c=='+'||c=='-')
8 G7 W+ L. {3 t( t$ W return '<';3 z2 G$ }9 Y: S0 t" y
else if(c=='*'||c=='/')6 D% q4 {) i9 G6 X! y- v8 \
return '<';
3 L; M' C$ w6 D/ |+ k& l" ]* g& F else if(c=='(')
$ p5 X( y; ~" q2 Z6 V return '<';" [% d( @$ T8 _+ H
else if(c==')')2 P/ ~+ R Q: @$ [
return '=';
2 o( ?, N7 D0 \. `* ]# X$ {. a else
& S3 R7 p8 K8 V; R8 y7 G0 s2 R+ p return 'E';3 F2 s0 d0 i3 b( c) ]( R" Y
case ')':
7 R! {' W9 Y$ ?) B: O. ]* f$ L if(c=='+'||c=='-'); {' I% Y8 U0 _$ i% N# y1 E
return '>';4 G7 Z3 v0 k! ?' E0 c+ j% x
else if(c=='*'||c=='/')+ l3 g, m5 P. E' n
return '>';9 p9 E9 W% q( N/ ~% ]' T& \
else if(c=='(')
' Y% E% N7 t$ X7 o/ D return 'E';
7 y$ D, @ w; B) K0 H0 ]* I else if(c==')')
$ t t3 ^' `. L8 j* w4 X' T return '>';
/ S3 f: A! Q O( E$ r* X/ h8 i/ @) Y- r2 C else
s& r3 d. I8 j- X( s' P) b. k return '>';, K4 _) F& ^( n
case '#':$ ]' M- `$ p3 x) R, ~
if(c=='+'||c=='-')8 R. x$ m1 z. r' u* {3 l
return '<';
& Q- I. g: z6 Y- F! E else if(c=='*'||c=='/')
: U0 W9 S2 C# A, t4 @; F5 `# i7 z7 E return '<';6 F3 t2 ]. s3 y/ Q8 v
else if(c=='(')
# Z( K' G3 }4 F$ [( v* O# P5 [ G return '<';
4 ^# |: g! @ m4 C1 `+ ? else if(c==')')3 H: ]1 c9 A4 j( }
return 'E';
# N, W2 N3 K7 A- l7 R Z else5 J1 O! k9 C O5 O/ z6 J. g
return '=';
1 ~0 Y7 x9 U" s default:6 }6 E" _1 H% _ t: `
break;; I4 _3 h4 g6 R9 Q
}, B$ p7 o5 N5 J& l. f, J
return 0;
" z- C' a+ P3 p8 x* M}. M5 q9 A, l n2 y9 y. U i3 w
8 N9 `3 V$ {$ [' Hint isOpr(char c)
Y3 x6 s! N# ~$ t5 U; @3 Z{
6 o8 _. z8 f$ |0 [ if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='), s0 _ W7 A. J# @0 g% j0 A
return 0;6 g: d9 d) {$ R. j. g8 {9 j( X
else " j" x' g7 q4 r: Z! A
return 1;* @- e9 s3 M* {" ^/ a
}# a4 R2 V6 N$ H- a5 A
* P/ l6 j$ \, W. H% i" ]float operate(float x, char opr, float y)
* T2 n: t( [( _: r; T{7 l1 X7 _9 E+ i# i9 s! [ b; u
float result;! d% U( S" q1 g+ x. s2 l3 N
switch (opr)
5 c1 \$ U7 X: n- }' x0 n) | {
# @. b6 t5 t: f8 h/ V s case '+':
Q8 _* \3 t% ]* f9 }7 u* l: J9 a result = x + y;8 w) p* d0 e5 |5 }# n
break;4 w* {5 t% G9 F& P$ y, j* ^
case '-': ! W1 Y2 P5 @9 l7 b8 G/ o
result = x - y;
9 ^& [8 q* w4 `; j! \ break;
/ A6 H8 X# p$ O case '*':
6 e$ w! ?+ t; `4 v. o' k2 p9 N result = x * y;
% h2 u8 Z7 k2 {/ @ break;
. s: @+ D6 i7 R8 p0 T) _( F' Z case '/':
F- [1 w7 g/ m' Q if (y == 0)3 L7 A8 ~5 c8 `7 r% W! l
{
. j! Y- j- D( b2 G) K printf("Divided by zero!\n");5 b g+ r0 N9 @! P1 \% d! t5 H
return 0; K5 H7 J. k- u* f6 F
}
2 A& Q ~( Z% \; q# O9 ^ else
0 |9 w1 L# U$ ]" ^# @8 g {
5 g7 o( _4 I" D6 c. l1 { result = x / y;
# a4 M2 S6 J/ w( e' U9 l break;
3 R- u) s$ x. s/ y% O, M h }
% z+ X n8 I! \" @7 A1 F0 C. T default: 6 `, a0 ~* ]0 Y, H! H8 l) y2 ?
printf("Bad Input.\n");
0 F T9 L8 f# S8 I" L: w return 0;. y5 K8 o, X3 a }
}
4 N* Z$ v. V$ O% X% m) W4 h( ~3 f7 j w return result;
3 o1 T9 N% i" b' J$ p- T; ]}
( | H P1 n: a4 v/ o' r( _, P2 ]! q% N% i( w
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
9 r% @1 I" v$ E- ~{
2 B K- C( T1 M Stack optr,opnd;" x2 f9 v1 E+ ^4 k1 l
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;. H9 W8 y: U! z; y' Q! N
char c;/ o/ Q6 A3 x) r* ?9 @
char buf[16];/ L; F: F3 k; @4 ]* X
int i=0;
# `* v7 d( y0 z. }( V ^" O7 f3 d4 s
C6 u# a9 C7 \6 X+ j InitStack(optr); /*用于寄存运算符*/
2 ~; F. H* t2 H! T- Y InitStack(opnd); /*用于寄存操作数和计算结果*/
1 w0 o: ~, t# S s! J2 U; ?* [ memset(buf,0,sizeof(buf));; }( l8 ]' ~- n# d7 q
K9 D+ m* q! h3 D/ `( h+ c printf("Enter your expression:");
e; N& A4 @$ k d# d9 u+ W
* h& m: u' |% h/ o0 ? k- t0 `, | opr_in.ch='#';% H5 k& [, _& v7 I7 L R$ L: U" I! j
Push(optr,opr_in); /*'#'入栈*/
6 C% B* L* j4 Q, p( a7 _ GetTop(optr,opr_top);- c8 v* {% T" N' s; ^0 W. @
c=getchar();- y# B+ e# w. U$ I. f5 A3 M! C
while(c!='='||opr_top.ch!='#')
! q4 @# B: `- _5 ]1 d8 T$ o% C' s {
- k4 g: \: |) B) ]: }9 i r" J; ~ if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
' H( J& |6 Q/ z. M {7 z* f+ q9 P4 m# e7 C7 Y
buf=c;
2 s. l$ r( ^( J3 U- P1 ^, |( [2 } i++;9 x5 F4 l% X8 X1 \% {$ ]
c=getchar();$ q# i* T/ z; ]# t5 Q! D
}
! j4 a* w+ f4 b/ |$ F; w else /*是运算符*/
! O5 r0 M# j P% I/ |+ ^ {6 P- R2 {* ]( ^1 a
buf='\0';+ x4 ]/ M) Z3 v% h' `
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/3 c5 Q- M7 f7 J# g% q
{/ ]( C3 {% E) {/ f& ]
opn_in.data=(float)atof(buf);; D" @& o, U( z( _6 ^ ], Q
Push(opnd,opn_in);* T4 Q* K' Y4 L! C2 x5 u! J
printf("opnd入栈:[%f]\n",opn_in.data);: K4 V; u9 I6 g" A: R
i=0;# i/ h, z) z1 }$ A# } r( o$ ]
memset(buf,0,sizeof(buf));9 v0 Y5 R ^( l; B5 M" p
}
8 V C- X! g" U/ [0 Y' x& W2 _" D$ W opr_in.ch=c;- _% ^: p* j, X5 c; m# q
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
# ` Q. ?- k' a( f K2 B& ?8 n {9 H' S; Q6 n+ Q# P0 b% z
case '<': /*优先级小于栈顶结点,则运算符入栈*/
* z! Y. x6 R, q0 I. b5 K( ~ Push(optr,opr_in);
% q7 n9 b: Z, r9 C* U0 j, T printf("optr入栈:[%c]\n",opr_in.ch);2 I7 O2 A; }- `+ h
c=getchar();
- O$ u2 S$ ~0 y# ] break;4 j0 b4 g: A8 g3 S
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
) A6 r) P7 f8 y" Z. N% Z& T Pop(optr,e);
+ u% J, r8 D7 S1 E printf("optr出栈:去掉括号\n");
+ }- E& W t$ P# w5 b/ _ c=getchar();- l' M" T. k' u$ R
break;
0 g: d+ Y4 Q$ v6 k+ I2 V case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/5 }3 _0 i8 k: I4 N; `- ~
Pop(optr,opr_t);
9 j% ^8 }- W; B2 w) x, Q printf("optr出栈:[%c]\n",opr_t.ch);
6 t; E% b& M) }0 L' z if(Pop(opnd,b)<0)
& C8 R F. t' _( h {5 r/ y9 Y; Q3 Z/ V, M
printf("Bad Input!\n");
" v, ]- O4 K5 A& [6 Y fflush(stdin);
5 _1 e5 j& D9 N- O v return -1;5 t0 `$ {4 J/ G; t
}# |, t {' t; F6 H
printf("opnd出栈:[%f]\n",b.data);
- t F) s% n! U7 h; F1 E. |& B$ Q if(Pop(opnd,a)<0)
( t/ `4 W _0 w. B9 ^- G {7 M' B }5 k7 |/ n
printf("Bad Input!\n");
# {' k* z5 X1 ?( [, Y% m3 Z5 F; g fflush(stdin);5 l$ Z6 q! C4 A. c% Q1 H
return -1;
& Q) ~4 ~, Y0 W) ]8 b( W/ d' h }
. r c# T9 ]4 v! s9 S printf("opnd出栈:[%f]\n",a.data);
5 A: S! Q4 ]% M1 r opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/( y4 d. ?- o5 o/ H V6 n F" Z
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
( \$ i& g) L& \' ?4 _6 I6 V printf("结果入栈:[%f]\n",opn_tmp.data);0 A8 @3 M# w3 j: p8 _
break;& T/ I9 U% G: l: ]
}
$ w3 k! S/ H8 e }
. x/ ]! r' A) r. g GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
% F4 X6 n- f: c0 I8 Q) p }2 F3 c4 e& u0 M; i( v) Q9 q
GetTop(opnd,opn_tmp);
0 j; P+ E( ~4 S0 m DestroyStack(optr);9 j' @+ Y) j, v% M: f$ {2 p
DestroyStack(opnd);3 s4 J5 p$ U/ V( `3 v
return opn_tmp.data;3 T( J7 t# a* I. Z. ?
}
7 c* R9 D/ L2 H2 }& D8 u' U; p9 ~7 j$ P3 z' U
char *killzero(char *res,float result)% D$ j' L! B% A1 a8 i
{
, `% z' C6 _& k8 K' E- Y int i;
* m1 l j6 n" d' r1 o2 n% x; n, F- E) M) {7 B
sprintf(res,"%f",result);: |" F7 V7 y+ r* X' [4 d
i=(int)strlen(res)-1;1 L" r" j* r! A$ U9 R
while(i&&res=='0')% l. U4 }! o% {9 |9 u' H# V# `7 |
{# m2 V+ q" r. w9 H5 I
res='\0';
) f8 [3 w) b0 q' n D i--;. _9 n: y; }, J% I
}; z3 b7 O; A$ D4 o# |9 I
if(res=='.')6 P5 z( z, n0 b+ M8 s. @
res='\0';
s* ]3 b3 v3 t$ Z4 Q return res;; D: F& t- B9 S
}
4 v5 }5 E; g* ^: U" r# p
& l& C+ G: U- z9 `int main()( \# r$ q# |$ C: { G) i3 M3 f0 ]
{" |/ T% _6 b3 k% |3 a
char ch;: `3 f2 I4 [0 H/ E, ^0 W8 M
char res[64];
* h" d3 j( f7 X: n0 J# A float result;' x% `3 a; n A2 N: @
while(1)% X" ~9 I* a! |5 o& ^) N% H) A
{4 L9 O+ I# h L& V
result=compute();
* ^$ L6 |+ Q3 U% E printf("\nThe result is:%s\n",killzero(res,result));( f8 Z1 e# l# h. X
printf("Do you want to continue(y/n)?:") ;
7 Z: h' I3 S7 v P ch=getch();
: d" ]. Y4 G/ o+ }/ e" P6 r. B putchar(ch);
' S6 ~# g' c/ r5 `9 j if(ch=='n'||ch=='N')
& ]* R3 _' c# o& C4 l* r break;7 M, n. d) i! k8 M0 z2 g! z3 F# X
else& ]. S2 o- a. R1 N! \" i+ D6 i/ T
system("cls");. H+ ]( i9 L& \
}
; P$ n! _. k# h! l return 0;
' Z# a' _) r! E- L- `}
# G. B. V( U5 Q+ e: e/ C3 m1 ]* i9 U- `* r
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|