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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
6 E- }/ t i, w, O8 s; H( J程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
/ ]; v' ^& B. {) Z& S) J! ]* z0 Q0 `/**************表达式计算器************/
2 \3 {5 }, z* {$ O/ I/ z#include <stdio.h>0 z u& E; Z( Y- L" |
#include <stdlib.h>
9 T( _8 h* V3 L) R+ Q& o#include <string.h>
- k% |6 F$ e# J#include <conio.h>% H1 p) Q$ M: d9 ~& W4 J
#include <malloc.h>
3 m) p& t5 n! w7 q- _; ]8 X# u. {: L% g7 K" u9 ^
#define STACK_SIZE 100+ I# f9 H+ s2 u, {
#define APPEND_SIZE 10# \8 O! Y% h$ U( M- x+ w" \' {6 {9 S
& ~, v% C' ^0 ~8 a8 r8 v0 bstruct SNode{
9 F; m6 z" J) x. V' `- D% P3 C float data; /*存放操作数或者计算结果*/) |1 L" l- K. I2 A+ {( |
char ch; /*存放运算符*/
" p7 B& p. z& t% q4 a& E/ I1 A+ p; O};
1 n" s5 |; ]( K0 x+ p( S; w6 e: B8 E/ z1 Z
struct Stack{5 X! {/ \6 s2 ?' A
SNode *top;
0 u/ f. I3 l1 n% i f SNode *base;
+ p; T# f6 z4 i2 G5 u( w7 ~1 B int size;
( ]! g5 J/ C6 I; D0 a$ }% w+ T};* |6 v- h9 c5 u' d$ S! Z5 v
( v! S8 t& @0 Y8 A
/*栈操作函数*/( c+ i8 k, A% u& }7 Q* U' P
int InitStack(Stack &S); /*创建栈*/$ _& |. o* ]& S8 l2 L9 W) j
int DestroyStack(Stack &S); /*销毁栈*/) L" G$ }4 N- D: S
int ClearStack(Stack &S); /*清空栈*/
! }6 D% O7 V1 Sint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
6 t( d1 ^0 L4 C. l9 K& w# v$ tint Push(Stack &S,SNode e); /*将结点e压入栈*/
, ]; U9 o! l7 q# U+ _0 qint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/* e$ \ L$ a) z& o8 X
4 v/ e; g* L( t+ v2 a! D/ V/*表达式计算器相关函数*/, e- ]: ~. t* D% y. g D+ L0 Z- D$ y
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
0 L& M" J v! y" I! e6 V! N/ nint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/# G7 u& C$ ]# {& A8 {5 }" A2 m( V$ M
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
1 g: R8 Z; _$ t3 a# m1 A# [float compute(); /*表达式结算器主函数*/4 p# h! H' z1 {+ f) O
char *killzero(float result); /*去掉结果后面的0*/ 6 r- T$ K$ r3 L2 S3 c4 w" F
: c+ H+ x( G6 y
int InitStack(Stack &S)9 L; V Q# y) n2 ]/ x0 A% A
{
" z* D8 L6 a) X S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));# L- p* Z9 k* N. S8 j" x. h
if(S.base==NULL)/ E! F& o9 q/ f: w: I
{; E0 {6 a' \' e' H% f. G
printf("动态分配内存失败!");3 F4 F: Z2 W: V. {7 s6 t! V
return -1;
$ w* Y- T5 v1 E }
4 U# J2 i# B/ o- G S.top=S.base;
, J4 D( ], n: M4 Z2 x S.size=STACK_SIZE;6 P$ A( s [+ h# \: o' Q0 m
return 0;
2 ]! i |( H. }9 ` E/ L7 D}9 L" D! g: j' Z8 N
2 L) I, v" u/ Q
int DestroyStack(Stack &S)
! H* u5 D5 M' n) D* r$ @- B{
1 |6 K8 m9 N/ Y# p3 M3 o free(S.base);7 e% h5 b$ X0 J8 s9 @
return 0;
% w+ P2 p3 C: g$ G: ?2 L5 v}" e0 R7 }; f; |, z" @( Q5 x% ]# c
( b9 \1 z' L8 X' J9 X* b/ b
int ClearStack(Stack &S)5 y; H2 W9 _( E* U, u; f. @' F/ H
{
5 M! W0 a+ A I0 C" ]# V! U3 X S.top=S.base;
. I) ?/ l& @5 A3 U* k return 0;! A2 Z+ e# |3 Q: P$ g
}
9 n3 ?# ?8 s4 O" S% U' Q0 P' k: E5 a
int GetTop(Stack S,SNode &e)2 n: ]7 u# o7 [# Y9 n
{
F6 K" {! X, o6 C if(S.top==S.base)
0 Z0 U$ R+ e4 U+ N {
3 }" X6 I! {9 L5 M* ]( K) b# y printf("栈以为空!");
* M4 Y$ J9 W8 r return -1;0 O- P" T/ @1 n& Q' p" f7 Y1 a
}
! L* O0 x+ O) n. ^0 K) J: r e=*(S.top-1);
4 x0 p' U. ^7 T2 Y; n) [# U return 0;
1 m1 q3 `2 V) T}0 e3 q+ R: }9 D6 ^
1 @$ O: |+ _& L! @& c+ F+ k
int Push(Stack &S,SNode e)) P: O+ [( Y8 z" ^$ E( z* R6 ?
{0 w) w# [8 g) _ g0 k1 i& L
if(S.top-S.base>=S.size)
& {4 b# I4 ^% G0 z, |' o {
9 J! ~5 X4 i8 P$ M5 h5 f S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
# _( `6 ]( D" d0 X if(S.base==NULL)
( g- v; F/ a A6 X6 T9 _ {
6 y0 s' W3 \# T/ h" Q2 a; v ^* z printf("动态分配内存失败!");; M- r. V1 _& o4 P! o: y: c
return -1;
) Z$ Y$ e( l' g" H$ D }
) Y3 j1 ]# i# Y S.top=S.base+S.size;! |! Q; ?+ s3 y2 m5 u' X5 ?4 C; Y
S.size+=APPEND_SIZE;
/ R& ~' n* w5 J; j/ O5 u! x+ i }
, l) f( B+ r F( @+ j% ] *S.top=e;
2 j7 F' O3 M. K S.top++;
) z9 ^$ d7 {' O: D- O return 0;
! [0 h( Q) K# L}7 v/ o q( I+ S4 x
+ H' r( X' M" N3 u; p* |9 h" H! Mint Pop(Stack &S,SNode &e)
% l1 V8 L: M) i6 H* Y; S{9 i' q( Y* F+ @1 B6 g, R
if(S.top==S.base)
* ~0 Z( F" l4 e9 c( \: ~$ i7 D" t {
& R- b6 j1 V8 l; W, S8 k8 B printf("栈为空!");
; J [: H8 Y3 ~* W return -1;
8 W' ~: J z3 ?1 V; ^0 K }& W3 N: y) d9 d* c& Q
e=*(S.top-1);1 Z) S0 Z1 ?# `; h; B* s7 d7 s
S.top--;+ h9 e3 j& c: _
return 0;# L; f- a7 A7 y O
}; p& D3 M! a+ Y/ G' g ?! w3 A1 b
6 d) {" A9 |3 I: {; }' v5 S5 tchar get_precede(char s,char c)
* {. W1 |# o# P2 k{
9 P2 K' p% I+ b4 T1 L. C0 z switch(s)
) O0 L. }6 h1 y3 c+ M; Z {* B4 K. w. C! W0 q( c
case '+':
5 j- }; `5 s; a; w! s: F: X/ e case '-':4 d$ k6 v: b/ a% B4 m
if(c=='+'||c=='-')
* y( `$ n' K7 j0 O9 w return '>';' c+ t& m7 D p T- N w7 B
else if(c=='*'||c=='/')2 v6 b5 @5 J; u2 b
return '<';2 J! a M& Z3 I. P, U
else if(c=='(')
: H X' Y+ S6 m2 q" z& o# b6 A return '<';
. i# L- {6 ~, y7 S2 T else if(c==')')
; J$ t2 M7 _* {- @- L return '>';
, t, ?3 Y& i/ Y8 x6 N else - H: B7 u; ?9 `- J' a7 V) V
return '>'; R6 t* d) V4 {# T5 T$ S' N! }
case '*':
s) @$ C' n! y2 `+ U# z case '/':
5 ?/ `7 h/ |. e if(c=='+'||c=='-')
9 m( d( R- a: G4 p3 \9 p) N return '>';
( e, M6 q/ Y3 z else if(c=='*'||c=='/')& |4 E/ w6 m( v$ z2 M
return '>';
& [6 g9 A1 a! H* Z3 c else if(c=='(')
7 R9 E, X7 D; k ] return '<';0 [- L+ f p" T2 Z2 G0 h
else if(c==')')
0 Q. t2 ]% p G8 n. g: B1 p3 h$ K return '>';5 V3 x' M* z0 O
else9 D" j7 N3 F5 v3 g* H L6 i
return '>';
# K# }. [" E9 Z$ V b+ k+ O8 b case '(':
3 r( e6 x, a7 [$ I7 ]$ ?4 ]1 }2 t if(c=='+'||c=='-')
$ T4 e' e! Q+ u) P/ p return '<';
1 _' ~5 ~; H' [6 R else if(c=='*'||c=='/')+ J% m I* ~$ a; J9 R$ r Q0 H g5 W9 n
return '<';- x$ t2 q4 z/ ]" U' V
else if(c=='(')5 A1 s F; l* b
return '<';8 _) S. K% a5 w. k- j. }+ _: D
else if(c==')')+ w( w+ [+ b1 }& c$ I
return '=';2 J" o: k# z1 Q2 E- u: l- m$ p1 u$ P
else
+ V1 Z$ P- Y: I+ {' [ return 'E';
7 k4 j1 l! h5 Z; G, i% W; [ case ')':( K' J" Z0 T2 R5 s5 n- N6 Q# `/ G
if(c=='+'||c=='-')
; Z$ i" N0 ?- M" ]8 j: R: _ return '>';
( U9 j- P' }! ^& c5 E else if(c=='*'||c=='/')1 S3 v. o$ s3 h" m/ B
return '>';
: Z$ N0 L) k" V0 s else if(c=='(')
$ c9 d3 S; m2 d% Q" y# G return 'E';
g b" W: w% y7 ~/ | else if(c==')')* }8 @4 ?# Z& ]/ M
return '>';
7 c: G8 v+ k' `! K' O( j else
$ k% l& v t. m$ q$ Q return '>';( z7 ^" U! p* ?2 p/ a! b0 [
case '#':/ D$ u9 J0 K4 {
if(c=='+'||c=='-')& J/ b5 T6 c, y8 K( F
return '<';
: i8 I( P8 d3 E3 |6 R6 U; \ else if(c=='*'||c=='/')
0 D0 l7 g8 L' ?3 W7 ` return '<';
3 @0 i* b; B- p! y! B/ V; n else if(c=='(')9 V! J, s" h* E! o- o: |- y
return '<';$ o$ H) _1 E, Z! r |; R
else if(c==')')& z `* O0 Q B+ |, v2 f. y# P: g5 C
return 'E';
0 o$ ~ Y: U% C" p, V6 @4 e u6 Y else
( I8 z9 h( F& u- o' k; j! C8 t7 k" D$ u1 b return '=';) R8 A+ U' d5 J B$ y
default:# D$ V6 X+ `0 e3 F& U/ k. \% L8 e, g
break;
: B' M. L7 b5 l; v7 B }% f/ L- s7 S$ v2 W* C0 e
return 0;
( d" M G" F6 h# I}- o. N. D$ n( s# \9 o
7 b% ^# q% |* D. Y2 l, o) p
int isOpr(char c)
* S# L9 E; Q4 `' Z* [{8 D2 b8 M( e9 ?( Z3 c5 d. ~) q7 I
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
1 Y: i. }% Q2 X; [, N+ E return 0;
: V& S* m" J% [+ v else 2 e4 Q% n X' }( D
return 1;
0 ^( w6 r% h! \. S5 a8 v3 D}2 k1 i v# Q1 @; h( F9 g1 _& p3 h3 n$ X
, G1 a1 J: V4 t! p5 I& t" n( N5 Efloat operate(float x, char opr, float y)1 L" M% \9 n, {! q O6 {( C% p
{8 Q* d% x% w N* s$ n
float result;
* c2 `" l" X8 h* q switch (opr)3 Q0 G$ N+ R7 D4 u
{# o; p2 _9 f# v% s
case '+':
$ s1 s! g5 H8 ?( R result = x + y;
. l. x# N# B( \" T2 A/ D9 r break;' N. O) Y2 _! {) e$ G N
case '-': 2 G/ P8 L3 B) u2 P
result = x - y;
3 C7 |2 V$ z4 L& m% r. { break;
{* z( m" W% [4 V. a. _1 {4 f% R& N0 R case '*':
8 h$ d6 H( n6 e/ C& } result = x * y;
1 _' ^* \. t7 |: I* U& [- I break; P6 k: u6 k( ]$ Y2 s8 k; l; h
case '/':
, P: o* _; k- L if (y == 0)
y1 o1 R* r! g, W3 F5 { {
& W2 U4 b. w; k0 x3 `8 ~ printf("Divided by zero!\n");
( m2 ?+ m0 @; E. c$ ], @- ` return 0;
* K6 B4 j @# g/ z v }
3 L4 S- l- u* H* _( ]6 K else
7 V D. k% K- P6 @ {: P3 x' }: t9 X+ ?" ]% G9 S
result = x / y;
d& ?6 _) L2 E7 j, P break;
% c, c1 b0 J$ {/ p# ]/ P8 l }' Z1 K& s' c" [- \* B
default:
: a$ T9 k C/ X; f3 G% G printf("Bad Input.\n");
5 X& N8 X" J/ Q( [8 ?( a return 0;# |* q( o: L5 ^/ \; M
}7 H, F8 b+ Q2 h( D# t9 S! n% [5 b( W4 e
return result;# j: m5 S* M5 a" g
}
4 O6 x$ X3 r* W3 k1 E( V0 d; g/ \+ j q
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
% O2 p: Z9 M/ ?* [8 _ A0 l{
, h/ a# z N* J+ v% ?, }$ ?$ n( r Stack optr,opnd;
2 [. ]0 T. z. w struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
p/ ^6 _! R, V* g5 F! F8 Y3 Z# b6 v char c;# R2 {( S) ~5 m0 o6 h( w
char buf[16];8 U8 b! a" H9 U6 {+ a" P6 l
int i=0;. f/ m# V! U. G( r- A1 C! h2 }
) G; @& Y& n( s C& Q
InitStack(optr); /*用于寄存运算符*/( c; k, g2 l1 p# k+ U+ \
InitStack(opnd); /*用于寄存操作数和计算结果*/
: @3 |* t( Y* t# x' f, Q memset(buf,0,sizeof(buf));* [9 u( x7 S5 ]) p
" Y% r4 j; p: Q/ f printf("Enter your expression:");
) g8 h/ E$ {, Z+ l' c0 W
4 U5 T. n8 z, b% d( N6 o/ ^ opr_in.ch='#';
. g p' R: J# n4 g: h6 D. O Push(optr,opr_in); /*'#'入栈*// v* k* O8 l ~+ _" O9 W
GetTop(optr,opr_top);0 F) `# X* i- u u* J
c=getchar();
; ]: w# B7 H! Q3 A; Z# S3 N. Z$ h while(c!='='||opr_top.ch!='#')
% \. L# i8 U4 @4 S- e {
& U- V& F, t5 q; J4 S if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
5 K5 j4 S. U6 n2 h2 }7 O* i( ?" g {' N4 e' x! E, S( a/ N/ x# x% g
buf=c;
. D( V( B+ V* k9 W i++;' D3 y" i, K* G' }; J0 I
c=getchar();
* H6 g" w' r* l* T6 P: y6 A" S }9 O s9 W# G4 Q' H9 `. \
else /*是运算符*/
" d+ A. p, _' r {- ?+ N! e3 y* G0 F8 T* ?; W
buf='\0';3 ~# `9 ^+ P9 S+ P
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/( y/ l! O. B6 L W$ q
{
P% r6 c7 e B8 l9 ~2 o opn_in.data=(float)atof(buf);% i* Q9 T( ]* D4 @* _; C w7 E
Push(opnd,opn_in);" `1 f$ c, O5 W& r# j2 F3 b+ m2 I( F4 F
printf("opnd入栈:[%f]\n",opn_in.data);
, _9 _; V4 ]% g2 a2 d1 ^# h$ x2 P" M i=0;" d. x$ c8 k9 U
memset(buf,0,sizeof(buf));& E: L% `" `( y9 ?
}7 w/ a6 `: b1 a- |7 t
opr_in.ch=c;) D/ M. [; O% m" d' M- H* O
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/" t n. c! v( t/ t2 u; k2 g n
{
' X1 S5 j a7 ~5 A1 f% ~( M1 K case '<': /*优先级小于栈顶结点,则运算符入栈*/: o0 d1 N g! ^5 g! f9 V. d7 Y
Push(optr,opr_in);# Z- P. U. I8 i+ j) {' n) }
printf("optr入栈:[%c]\n",opr_in.ch);
: N6 W% ^* k; V7 o c=getchar();
. d0 R, p P/ g7 [9 t0 K break;
& _7 o: \+ f. z8 x case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
7 y# @- G Y) W! U! X Pop(optr,e);
( y8 _" u F3 R( `- Z printf("optr出栈:去掉括号\n");
: ^1 w5 S+ i* z& G1 o6 c c=getchar();6 F2 t* J; T8 \* I* e
break;
4 e" A% {' ?/ D) Q3 r& N1 J0 j case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
7 W% l* r( M0 g Pop(optr,opr_t);
) q$ q# T' I# n; N! o; x- Q5 W printf("optr出栈:[%c]\n",opr_t.ch);7 U K$ H: Z8 T
if(Pop(opnd,b)<0)1 w! ^5 d% Z( d6 B2 M1 q
{8 T3 R: ~& v1 o3 Q4 _! e" J' c% R
printf("Bad Input!\n");' l1 |& Z; V. r! h0 o
fflush(stdin);# A) M& T. u$ u B! {, W
return -1;; a7 P/ V7 S- b' z9 j) [+ Q
}# H& `! ] }) V# y: I
printf("opnd出栈:[%f]\n",b.data);" E8 I1 b% E7 V: q6 v% X
if(Pop(opnd,a)<0)7 y8 b& W/ x1 k2 [ U4 s
{) {7 ~ G! N2 j$ ]( M/ N5 m1 K8 v
printf("Bad Input!\n");# @5 f& o$ B7 D6 L0 U6 Y: ^
fflush(stdin);' P7 t$ X5 s3 N, H" _; g7 k
return -1;! n/ E+ \" u0 D( @( [2 a
}( i+ |% D2 s4 @8 o& b5 z
printf("opnd出栈:[%f]\n",a.data);
$ B5 I/ k |* L( G% v9 e+ J opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/3 J5 A5 D* @6 U9 k
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/9 d3 y8 M6 y! m9 r9 p
printf("结果入栈:[%f]\n",opn_tmp.data);
/ h, X' o7 R3 h- c" J8 C* a break;
4 f9 K1 D! k. D# t; n/ r, E* x }. h) K& J! C; D8 {* v
}* ]& v! ?" R) r0 m% c5 e
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
$ X! m/ ?/ G8 U5 `! G$ N& ^# R }
4 n% g E, Z8 N' ?6 Q$ U* ~, j$ B c GetTop(opnd,opn_tmp);# C) W. r& @1 w5 u6 c- M& n
DestroyStack(optr);
2 ^0 i8 Z# `4 @ DestroyStack(opnd);
5 V5 y ?5 L, C3 ~. |4 X return opn_tmp.data;
# Y3 T9 g: F3 H}0 V0 I) P/ m4 \+ R" F
, x. |0 f7 {+ v2 F. F! e' m- i
char *killzero(char *res,float result)
, `3 T0 E/ a4 ^' _* O% h{' U" |& v! G9 ^ y
int i;( A9 J% r3 o( s0 U$ u* \* J0 R; ?
) m2 @3 z1 K0 e, E0 q, j sprintf(res,"%f",result);2 t# i6 C& x# h2 q- l" H5 x- r( ~
i=(int)strlen(res)-1;% e: T+ c6 K$ J, q( T
while(i&&res=='0')$ r a5 Q3 e4 _
{1 A) i: d6 [8 _) \/ ?7 I+ U/ d. k
res='\0';
6 ^# M- W) P; H i--;
" P) Y+ ?( ?8 b8 M! q }
) {4 M# d/ [# h4 q6 f7 Q0 s% H/ F/ Y if(res=='.')
; U7 N* |, o5 z. \5 w! d* h! e res='\0';6 c* e! k1 Z4 L e5 ^% J9 j
return res;
2 w5 d, i4 D$ J6 ^) Y+ }! C}
5 t+ ]8 ]* g& U& }3 {( F+ M# R/ a% q) K4 p2 D
int main()
- n0 ^$ Z& S1 K$ N{- k9 {3 w2 |" N) Z) \
char ch;
9 g# s* L4 ~" w8 W! Z char res[64];
3 f! M2 Y. e2 a) g float result;
+ g& |5 E' y/ u. c8 _ while(1)/ q5 ]4 \' d3 ], Z: x$ X) ^
{
) ^# j8 n6 ?% o result=compute();- R3 D7 p1 Q/ s5 V; J3 U
printf("\nThe result is:%s\n",killzero(res,result));. d2 p* c# r9 z1 \: t1 d
printf("Do you want to continue(y/n)?:") ;
" Q& I3 S4 f6 A' o% p) M6 }* X; u+ m9 b ch=getch();+ E' I4 l: z6 P y0 j; Q8 p' S
putchar(ch);2 h# r. m3 Q) y/ g+ u$ v
if(ch=='n'||ch=='N')
/ _$ d4 J8 v4 R6 \6 w8 e break;
' {0 v3 ~0 K, R2 g else
, \3 I3 T# Y! K. @' Y system("cls");
- a6 f, J3 k( ^8 o* P }; h) e# _% L( b6 z. x
return 0;
) H, r& u- {4 v, c; d+ l}& h- _3 a! [' L& w
) v' \% C' ]' P1 U" Z[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|