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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.5 C$ z8 z* T3 a% o
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
& y3 @( l8 T4 I4 q/**************表达式计算器************/5 z+ s% ~6 V) [2 b; s6 o" M
#include <stdio.h>
9 g* b3 t3 E3 }- D9 K#include <stdlib.h>! K; j/ t3 f7 Y. ^4 T- t
#include <string.h>; T/ j& I& w3 {2 e3 I
#include <conio.h>/ q" c0 W: S7 z' Y
#include <malloc.h>2 `4 ^& x* J! c3 w
/ _) a0 W+ [) Q/ S#define STACK_SIZE 1005 @& I7 u5 d8 P2 }
#define APPEND_SIZE 10 t. P s# f4 H4 z
! a& y$ G# U* H( F, n; i5 k& \6 fstruct SNode{
6 }- u* F! Z+ u2 T) Z0 N float data; /*存放操作数或者计算结果*/% `$ v1 K1 b; @1 X1 g4 Q
char ch; /*存放运算符*/ e6 n6 Z1 J; D! q' p
};/ v9 H, l& Q8 a. O3 _
2 G- t' Q- b- e1 c3 zstruct Stack{6 F" {5 \/ Z4 Z6 u9 k' L
SNode *top;; F/ W. h6 M% m3 B0 o
SNode *base;
7 |+ |, N/ Z4 x- ~* L4 n int size;
1 E, Z! ?% v* W};
! F0 c3 ^2 {; u: x, i9 I( U" H7 d, e3 {! h
/*栈操作函数*/
# }8 p: } y- H$ \int InitStack(Stack &S); /*创建栈*/
7 u1 p$ I7 r' k9 D; @# [int DestroyStack(Stack &S); /*销毁栈*/
% u( P$ |, {4 ?# ~5 G# hint ClearStack(Stack &S); /*清空栈*/
+ C o3 l) z( O! S# g9 D& Wint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
! C. q7 x) J! ]* v z' M5 o6 I. g; Xint Push(Stack &S,SNode e); /*将结点e压入栈*/
8 i( t1 x3 W8 A8 {. Uint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
$ U6 C3 i: l3 e* L
4 o n0 y# N# a+ v4 Y; K/*表达式计算器相关函数*/
' R: w F( \' {. ^( R0 X! Y/ ?2 Rchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
9 @ t0 I, o! Z4 B- Zint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/$ I( Q" N* `& L" D L) X! n5 R
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/$ \( F- \$ f( U5 n! @/ a
float compute(); /*表达式结算器主函数*/3 b& U! {3 u1 E1 `9 K
char *killzero(float result); /*去掉结果后面的0*/ , P& q# l- v( v! o7 R& m
$ G8 s7 }' x/ D/ B% w
int InitStack(Stack &S)
! D" U$ S" i( Q- ~{$ c$ U( l! ^& f. x2 J5 E) P' R
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
/ Q. Q; \' R1 Q if(S.base==NULL)- I, i; t' l( K& U' E8 ^) m! _
{3 x/ T* j4 d; Y1 H
printf("动态分配内存失败!");
: r0 e5 H* Q/ d { \& v8 X. `$ d return -1;
+ o$ H y! q# _* x$ J U }, T) t }+ h0 x+ Z# h. i+ e. [
S.top=S.base;
5 C6 ^( ]. m& j# [, a) n6 k* z S.size=STACK_SIZE;6 {* {; U1 f( @. e
return 0;
$ z" i1 `6 v/ Y2 ?$ n2 {9 c}4 ^* Z& H8 t: T& A; _
( S6 F7 k1 U" k5 W h) sint DestroyStack(Stack &S)+ ~$ w: }& s8 d, v* `
{" K: \9 a6 \3 S7 y. |" {
free(S.base);3 [' e% ?& G! ^2 x5 {0 @+ V
return 0;
; d! q' ]" ^" g) H}/ r6 R! Y+ Q' X
9 W# M5 r' W# i$ Pint ClearStack(Stack &S)
3 O1 | O; U+ M& w* ?6 |% R. y- N{# u% v5 M$ Q, t- d# T* v, K+ a/ C3 e
S.top=S.base;
; ^: y. E& F) j& g% i return 0;4 t% C+ n) _1 j+ s9 U% E
}. @% s: X, a& N0 `. j
& x5 q$ c6 D& y3 ]9 M3 O
int GetTop(Stack S,SNode &e)7 C( ^7 i( h! E( x, ~/ i4 l
{! u ?& M; M u B
if(S.top==S.base)9 p, l% W1 {) z% w
{, C% k, P3 [6 Z/ r) g& ~8 Q
printf("栈以为空!");
/ E7 n+ Q J2 z& N5 B5 n7 v0 F return -1;
* x% w9 t8 K1 S* O4 n }
% C4 A; h, {* h) {! b5 I e=*(S.top-1);
+ s* d6 J( M W4 y5 X return 0;& e5 {; m5 V+ |/ Z
}
3 A, v2 S) s, u' _. |6 x) E, N, C+ P3 G8 Z" R/ K
int Push(Stack &S,SNode e)
/ f$ p% B5 P" G+ J( G: c) ^{$ U4 ]6 A- ]3 { q: k3 k
if(S.top-S.base>=S.size)
* b. N2 I0 w! [ {3 m, C( B+ g) s: G. q
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
4 @( {+ }! g2 `5 u if(S.base==NULL)0 S7 q" A4 X) h. w8 {( `
{% Y; l4 |0 p! i4 Z3 s5 D
printf("动态分配内存失败!");
7 w7 X) ?' u ?' U, x {) \ return -1;- j' ~. j* G, m- w) e3 ?
}( d- n# V; Q: L* w* ^
S.top=S.base+S.size;
; U; [* R1 ~5 w) Y S.size+=APPEND_SIZE;
! M3 f8 \% s y4 `" n8 F) l0 X6 s) E0 S }
3 U6 S9 f, J0 H *S.top=e;+ _2 c- [1 _4 o9 z5 l' m9 I
S.top++;
3 k% E; X. r7 @% I' b4 z, ^ return 0;
$ r1 N$ n: @+ b! O* _4 a6 [& s}
! u0 I+ L4 F3 e! ~4 S5 z4 v+ P/ Z5 h$ k/ p$ J
int Pop(Stack &S,SNode &e)/ a2 b, ~) M4 @; R0 |* r' M
{) s8 u& D& L4 z, ?- Q/ p* `
if(S.top==S.base)
% z, L; Q L2 s0 A m# y {
$ V- H( E [. i- c1 o2 J printf("栈为空!");
+ G6 N9 L# q/ j% c) Y return -1;! |: {4 f {+ Z5 [2 p" [2 Q+ b2 J
}- i. U, A2 w% t2 z8 T& f4 ^# Z, e
e=*(S.top-1);9 m, v7 ]) {4 r# W9 Y( e, q
S.top--;
0 @ j5 L* S. [+ C) Z0 l/ F! L return 0;
. X8 ?0 c1 M# `* l0 G; A) L}- U, ~, z; N& C4 W9 o8 q
, Q+ N. D4 [1 L6 ]% }6 M, E: M, r
char get_precede(char s,char c); F6 Y5 t5 W. O. a% a
{
/ q9 ]$ w( s9 j/ K2 a" C- k$ }+ [ switch(s)
# @1 F" ?, ^- s8 ~, z" ~ {
. Y+ m8 x5 W, m6 U- U) V+ K: }5 H case '+': / e9 x7 G7 A: B& R
case '-':& b# l4 L1 U6 P O6 Q
if(c=='+'||c=='-')2 N% O0 G: n" f n
return '>';
" W+ m. b* R7 J: A else if(c=='*'||c=='/'). ~) t, u* L( p5 Q7 H" G( \
return '<';
: U" y2 P, i3 O( `) F( f. W else if(c=='(')
5 M% a6 j8 b; D return '<';7 _0 M& H7 i, ]9 W9 c
else if(c==')')9 u D2 \/ m+ A6 s& B
return '>';8 d$ \: J* i+ Q: ]
else . `2 g a% g$ B3 V8 w
return '>';* M4 }5 O1 i2 o8 m1 Z5 [
case '*':
Z- Q3 V! P* q. | case '/':
# o$ a$ u j* M2 `) t if(c=='+'||c=='-')1 E$ B$ x' L1 j: i
return '>';
; B L* o) @& K. ~6 N- z6 i9 a8 T( X( s else if(c=='*'||c=='/')
; p3 ?6 N: U9 q) r) I% F return '>';
3 R0 U! ?: O! s/ y else if(c=='(')
9 q" p4 i) A0 ^9 e- W; z7 \, @ return '<';
# f7 D) N, y+ ?& G else if(c==')')
& {/ |% w. T# R9 M0 R8 ^4 F return '>';* l5 f5 p- A4 }) `" q: T
else0 g( \% G& q# j2 B
return '>';
2 S/ i8 O |# P. |- F( k case '(':2 k# z, G& q9 g1 n* E
if(c=='+'||c=='-')
5 g/ x+ _. M! g2 F return '<';
2 ` }+ v, c' N. b q6 I% O { else if(c=='*'||c=='/')
2 d5 ^8 W; |$ R8 f; m7 o( p return '<';9 e M) y4 @7 g, L/ |7 w$ @
else if(c=='(')
) {9 [/ m+ r! @# A) {+ Y. } return '<';0 {" D4 U& |( Q" Q
else if(c==')')2 ~3 V; |$ e5 v
return '=';, r; t9 A3 M; N% o) V# g
else
; Q7 W* D8 \' q- z6 @8 }# Y return 'E';
% o. [& p/ M p9 L$ V7 ] case ')':
0 N3 \: d8 [5 @ if(c=='+'||c=='-'): v4 r' d- M' F& C
return '>';
7 V4 Z4 x N; z L% d else if(c=='*'||c=='/')
7 r7 X% B* r9 c' x$ w" g return '>';
3 `6 I& T: S4 P* E1 u6 X! P else if(c=='(')
4 a5 |/ E+ }! {, D return 'E';1 P5 u* R' C+ `. a, Y0 D
else if(c==')')
' `! w# f3 p+ b( J3 q. T return '>';
5 A0 ]% \# o3 ~; m0 Z) w) T7 N; B6 [ else
# I/ W* Z: _ {* D | return '>';) o1 ]5 E) I, A8 y+ ]; z1 o
case '#':. l! d7 D( t( Z2 v( i
if(c=='+'||c=='-')7 o* E' \- t6 X
return '<';+ s! v2 R: z6 K; Z- H
else if(c=='*'||c=='/')
3 a; d3 [: U8 T2 P return '<';) m+ K# Y+ `7 ^( B/ i
else if(c=='(')! |7 B; C8 C$ O, _: a1 N. n
return '<';9 V& o& J& X0 W9 N1 k, _
else if(c==')')
3 f% e0 a6 G6 e0 d% }3 F return 'E';4 v% O/ X- X7 p) U
else
3 O- A0 n0 C2 H8 D* C3 C5 S return '=';
1 x7 x/ c" D; Z default: M5 }9 O, E2 Y0 e- d# A) k" E4 V6 P; _
break;7 B) {. e2 a% F9 x$ m
}6 O( r, ~* j) M; _! h
return 0; . R; _: [3 ?; L% D
}! b8 l2 c0 i! C! H7 e ]
6 M$ z4 `; h7 z! y. y N& v: ^" M( Z
int isOpr(char c)
9 [1 \0 [3 c2 }" I9 n6 K$ d+ l{8 z5 h# N. ?+ N B4 s J- e. c' [
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
0 Z5 p1 J3 { U1 ^6 y: e% E: I return 0;
) o7 g; H0 p) V ?- d6 e else * N. [8 h% v% ^, w" V2 E) X
return 1;
& H9 e! w* g1 Z( g* k}1 D# N r' c2 X) w) X2 G& ]- `
! U7 Q5 a; s; Z! G. ]8 x3 n# Ufloat operate(float x, char opr, float y)
' c; [7 a# M# D$ t. i' u- x1 A& k" d{4 X( W6 f0 n0 t" c" k: e: S8 t
float result;( |- k' m- \ l$ y7 @' o
switch (opr)/ H% V6 n4 e7 v, J* g# q0 d
{" g- B( o& H6 U7 f- d
case '+': ! |& [ _! o, ?: d0 ]
result = x + y;
& H9 k- e: G2 X2 X2 I1 C( Y break;
: G9 [. W& ~1 e7 q1 g case '-':
2 _9 A" S) e. P! ^) A0 f2 E result = x - y;
, t$ r2 @1 H1 M# L break;. G0 ?1 K, b0 ~
case '*':
" `$ k9 {( T% S6 S) h. [# O' k+ B result = x * y;
% y% {& t3 Q; z Z5 c" @$ ^! u* A break;
6 M$ [) E4 w7 v6 w case '/': $ `' J4 P" R3 U# X0 B
if (y == 0)9 H2 j5 C) g9 V2 K+ z
{
, Y9 Y0 K' i, w' T# c printf("Divided by zero!\n");
) ], r I+ c/ S2 o, C7 }- C% e return 0;9 C" w' w1 S2 Q( g8 K
}& f) U# p4 x+ i/ U' b% S6 h
else
9 j% R+ ~ f- H* I; E2 ] {0 S7 V# Z: S f' x
result = x / y;
" X# Z: u/ r2 V4 k3 _" K* U break;
+ W/ W& G% O& k6 R }: R; `6 K: `8 Y9 b7 t
default: ; m# A) H, _/ D8 q! t9 ]
printf("Bad Input.\n");
6 U p) | U4 ] return 0;% Z) S! p3 G+ a
}: k7 u$ y) d" l! o8 `1 `4 N
return result;! U4 c& \: x8 n; p+ b
}
( L4 a. z- _# A- |4 z* r0 _
9 @4 D8 V, Y/ T& f- Zfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
8 w. G7 m8 i* i+ M c/ b7 ^3 {{
5 M0 H4 O6 D/ w7 Y, g6 {/ O Stack optr,opnd;
2 ?. d D) x5 n" ^* e struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
% A8 u k7 J# W F, \% N8 _+ { char c;
- k/ k/ C% Y* N9 \% q) C char buf[16];
, r' }" M) `: M8 A$ ]2 E int i=0;
z" d; w6 ^2 |! Y 3 [5 B8 o% _' @5 P; |! w
InitStack(optr); /*用于寄存运算符*/) R. ]0 P, }) q
InitStack(opnd); /*用于寄存操作数和计算结果*/* g. x6 @8 t, l8 Y7 y$ g2 W7 S
memset(buf,0,sizeof(buf));
9 Y. l0 K0 \9 @. `
5 q. e: o1 T) J# K printf("Enter your expression:");' V) J/ ^, L7 S' T0 d2 E
3 E H- |5 _% D" s
opr_in.ch='#';4 x w7 B* A1 |0 d5 _ C
Push(optr,opr_in); /*'#'入栈*/7 C. ]" v+ u7 E# N: Q
GetTop(optr,opr_top);
0 A9 j& W9 x- p; `- W0 i/ L! z8 ] c=getchar();
$ H8 o3 r) Q8 n9 q& G7 s while(c!='='||opr_top.ch!='#')
, i4 h& U1 ]: i) k+ C: ` {) f1 z; d( Y7 c* z4 w
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
: m4 e) G1 _1 b6 `# r {% `0 K- k) x: i3 v& z" T2 g) a
buf=c;
4 b7 G% V0 J7 ~5 `3 q% j0 | i++;1 U, E, Z3 e N# X# O9 y/ l" Q) g' u
c=getchar();7 s8 n9 {7 C( y1 g( f P
}; v$ Z- [# ^- q3 c* V% _
else /*是运算符*/
2 j( @. L5 |+ C$ h# a; d+ s( w' v( M {
0 u* ]8 k4 k* m: F9 v+ K buf='\0';* M% G. i( Y6 z5 G0 O6 g
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
5 H6 K% Z2 _6 W {$ n' D7 x3 L3 i8 S* s! M9 e
opn_in.data=(float)atof(buf);; H s6 i: [3 v/ \4 B0 u/ o0 s
Push(opnd,opn_in);
6 M+ o: Z. Z6 E1 Y+ w s7 [ printf("opnd入栈:[%f]\n",opn_in.data);
4 {0 O6 _. U( R0 N4 n. E4 F i=0;
4 k q5 P. @6 j) o1 m& C0 u/ f8 Z memset(buf,0,sizeof(buf));; H/ d4 g5 l7 c
}9 _1 E: P: E9 M
opr_in.ch=c;
; f7 B3 M& Y1 S% ` switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
^7 {4 A, {8 z( I {5 V2 z- x8 i3 K- Y! c) A
case '<': /*优先级小于栈顶结点,则运算符入栈*/
; X% L3 E+ j/ \# t6 z* Y# ]- D2 P Z Push(optr,opr_in);
% i; r; h+ `, D8 T; w% p" w5 e printf("optr入栈:[%c]\n",opr_in.ch);
9 C: i, m. p5 ]3 i5 v! Y; t c=getchar();
1 L- K3 ]- G! c$ L break;% q8 A: t5 {; X+ B6 f
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/( S2 @# |5 C: M! k, k9 l
Pop(optr,e);
& b( ?1 `& b# @ printf("optr出栈:去掉括号\n");% z- V1 |4 |' l/ h- X6 h
c=getchar();
" R3 m0 U9 X7 D9 A# {/ L1 d break;9 Y" a h! U4 u8 K
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/" T3 x$ j/ H. Q- m
Pop(optr,opr_t);+ M; g* H& Q7 r' X& ?" v
printf("optr出栈:[%c]\n",opr_t.ch);) h, b' ~' b* S: i8 a* L
if(Pop(opnd,b)<0)" \7 k. K3 @' k" D9 _
{
4 H( w5 Y4 I# P, g0 E, e printf("Bad Input!\n");3 N. I1 A# w) g* m1 m; A9 `& j' q
fflush(stdin);
7 V* J! |( h" y# x3 j return -1;
9 z8 ~4 F g" C3 x1 Z }5 X9 H8 R# A i9 @
printf("opnd出栈:[%f]\n",b.data);
+ b! N/ v8 V K8 G if(Pop(opnd,a)<0)
; `- {8 }- C( r4 G& ` {
/ c$ ^+ E" c' o9 u! G! R+ }& x. D printf("Bad Input!\n");* j+ r$ J0 ]% U' D. _
fflush(stdin);0 M" G% P7 p# T* U# M
return -1;, ^- w, m4 j' v b* U5 q' d
}0 t, D! H" ]( T; l# f
printf("opnd出栈:[%f]\n",a.data);
" I% |& S& q) H3 W. v) C opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
9 E6 ~4 B0 T5 Y& s: ` Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
6 W9 o) R& c x7 t2 H) N printf("结果入栈:[%f]\n",opn_tmp.data);# p, l% v3 S8 F& m7 f
break;0 Q2 O6 p& }) x ?1 f
}
+ }& F8 P& m3 w# M }
( [' Z6 h( q- n GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
@1 b8 t$ ]4 K* ]. ?$ l }+ h1 M' I" `2 V7 u# l3 v0 P
GetTop(opnd,opn_tmp);
: r: U4 x& w& u0 o# b/ Q8 Q DestroyStack(optr);
/ _1 y) N8 Y; m- u a T DestroyStack(opnd);( M( D8 R: \" m; _
return opn_tmp.data;9 a, S6 V% H: x% J
}. W' S: X! Q o% U7 P: E2 J/ j; o$ B
1 r7 w$ M* V3 ^+ D
char *killzero(char *res,float result)$ w' D- f3 W, p- `6 P+ V9 g0 @0 P
{
; Y* j- J% k3 L0 d int i;" V% @2 t1 I# Y0 _7 n; q1 y
! F. s. J% c* D
sprintf(res,"%f",result);
5 m9 l9 R6 d/ U+ r5 R" Y g) o i=(int)strlen(res)-1;0 }8 Z# p4 L; j+ _, m, r( x
while(i&&res=='0'). |- v4 S2 `+ b- a+ \4 o
{1 d! K" ?9 W; G5 @; M
res='\0';
* N- B; i4 Y& ~6 F i--;& C0 O# y/ P- z
}+ G) K3 f4 h( a0 B2 D' I
if(res=='.'). I4 }4 x' g+ o; b& |5 M+ s8 p9 z
res='\0';
1 M+ |2 i$ p0 S" P; P$ Y U _) h. { return res;
, j; L5 z: o! f) ?}
# U1 [, D2 O- U, f
7 ~4 P! ~( G3 G; G4 fint main()
% V! Z$ H0 Z w5 ?( W: f{
2 a3 F' E5 Z. n+ V char ch;
: {# x6 e) g3 \' ]" ? char res[64];/ \# |* l& d4 e4 c- H& r4 O; Q5 l8 ^
float result;
4 `' [4 `5 l2 U7 D$ l: e while(1)
: H- h5 G: m7 Z, Y {
L B# v# v, H result=compute();
0 L7 g% f# B$ c# g8 ?/ T printf("\nThe result is:%s\n",killzero(res,result));; H, q( `. u, o) b3 _
printf("Do you want to continue(y/n)?:") ;
3 F. u! E/ K6 K: {8 a- x ch=getch();! f4 w5 K3 c" _
putchar(ch);
5 v2 \' X: @" o3 [ if(ch=='n'||ch=='N')7 {# g3 E: p: R1 ~+ ~0 s6 h
break;
; ?0 p. U( J, M0 E4 y G else
+ H/ k' q8 W( {+ q system("cls");
& g# g4 v! b8 G4 C1 o }
" k6 `6 q6 q5 s, T return 0;) h! m# X$ q% Y. e4 R+ U
}. q; ?4 x9 b) U# `0 P$ s1 B; `4 |
0 @' N2 V/ a. | d- I6 X
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|