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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
1 c6 o* f+ u3 P. k: d( `0 Q) e& ?程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=7 W- p F- `7 r, F3 I# j7 |
/**************表达式计算器************/
' Z/ k H: a; z# J+ T#include <stdio.h>& B0 P1 ]9 i' S+ P6 E$ h: G% h6 D% {' h
#include <stdlib.h>
; N, \$ T9 P1 T5 o0 K; Q#include <string.h>
7 ]5 B( V7 J: @8 f9 q$ \#include <conio.h>7 I( ?6 v6 ?- u0 F# E
#include <malloc.h>. n' N, J7 C |, o& _ b
1 I) f6 r3 C9 R0 `1 t$ y1 p#define STACK_SIZE 100
/ @4 T1 F; p0 m' D2 U3 K: O#define APPEND_SIZE 10, s' [0 B2 k1 S! @4 F3 I* B
; f1 [( ?8 f2 A; \struct SNode{9 B8 r$ y2 f+ `
float data; /*存放操作数或者计算结果*/
\0 V4 f j$ I4 O5 `" h% [ char ch; /*存放运算符*/9 ]6 G3 Z1 m8 J2 E4 l6 K
};$ @% `: V6 _8 o
# X: n- j1 K% n
struct Stack{+ y! }5 ?; J+ P0 L% d1 M
SNode *top;- N; P, k2 A$ j) N) s) Z R" h
SNode *base;
8 |4 {; c1 X0 @8 \* q2 g int size;0 i; v& ?# G* j) b* P
};1 r1 g* s1 T0 ~ I1 h2 Q. ~) o
. H" r; i4 B0 |% ~& K
/*栈操作函数*/( _, H. x8 b- e$ \0 a! S5 ^
int InitStack(Stack &S); /*创建栈*/
, t0 h. y8 B4 u* D. E# q- lint DestroyStack(Stack &S); /*销毁栈*/( J$ M/ L6 V8 j3 Z: b; _7 L5 {0 t
int ClearStack(Stack &S); /*清空栈*/7 P1 [7 e7 s; D: A5 w8 E* f; S
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
( n/ O U9 F P, h; u0 ]int Push(Stack &S,SNode e); /*将结点e压入栈*/0 [; ^- W( s; M0 z2 O8 _
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/9 D2 ~/ ]' H" l1 k" b
3 q- }4 c' G# K$ Y& L& a ]/*表达式计算器相关函数*/' w$ Y# Y; J0 s1 z1 O* p/ P
char get_precede(char s,char c); /*判断运算符s和c的优先级*/0 S" R+ @1 H, V6 g
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
& [! l* T" s5 g8 ^# T3 `& M3 I6 Zfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
, b! B4 q* ]: i& Q2 D. rfloat compute(); /*表达式结算器主函数*/
( x. h- j5 S4 O; ?char *killzero(float result); /*去掉结果后面的0*/ + Y% L" z. v+ T, \+ E/ f% {5 [- W
' t" |0 u, }* F$ G/ ~6 W
int InitStack(Stack &S)
i3 E$ Z" Z) D. ]" q{8 m/ L; x; i- u
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));' x6 Z! G! o8 i9 d p! |
if(S.base==NULL)
9 c+ G Q# X" z* g2 `( i( f7 s {
; I+ ]9 e* h4 l# S printf("动态分配内存失败!");! ~: E% L6 M6 s% E4 A' S% Y# T7 r
return -1;! J( X' k3 p5 h9 K
}
9 {5 [7 r" p$ G/ ^ S.top=S.base;
3 R# z, D' D% w; y0 G S.size=STACK_SIZE;
' ` I# C% O8 x K% \! F return 0;
2 I: l2 B0 S5 F( j2 w8 `! ]}- y+ D' v- V0 U/ g* e7 N O
: Z4 P. b8 m6 }$ ]int DestroyStack(Stack &S)
6 S& v1 o/ k6 g2 {# Y- _" M$ W{/ l& [0 a# |6 d' R k9 _
free(S.base);
1 |+ y. r7 C8 \, c return 0;0 h$ s! j% h- v) e& X6 a" ?7 ^
}: ]) A J7 d7 i1 S/ r, @, K5 G0 _
% ^5 Q' P& m* p r& o7 z: U' n
int ClearStack(Stack &S)
2 e% K2 @/ v0 V& E. S{
5 Z! M) {& o7 W+ K. O2 B& t S.top=S.base;
- w, {5 ^. ~( Y, b, ], H u return 0;
* w# D. _( [- v( i}9 z( f: F$ P' o6 l
' ?8 Q( K8 Z: d8 xint GetTop(Stack S,SNode &e)
( W2 u/ |3 Q2 Q; n I{
. H( X5 `# d! N: p if(S.top==S.base)
' }+ ]8 Y! t/ w1 V1 v5 Z: M {
. ]7 N% A* f: O: L printf("栈以为空!");# Y3 M+ ?3 e8 l- j
return -1;
0 ]$ k" h G0 f7 V+ ` }
+ \- Y: W/ X3 ?7 H e=*(S.top-1);. ?" [& M0 v% H! @5 O
return 0;
& j: B0 x' f, _& D}
2 t, l9 Y( R1 H% j0 ]4 U/ P; [/ ?; j `+ M9 e7 R$ K
int Push(Stack &S,SNode e)
3 ?6 d( J9 R' K4 D0 I( n{
" P0 l1 }& F, P: u if(S.top-S.base>=S.size)# w0 m8 o2 E- u
{* Q5 {; }" ]; z3 R7 `
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));6 w0 S- O) X8 ?8 N' {* N; H' r
if(S.base==NULL)# E3 D3 [; }7 [4 b8 w- \9 }
{" a N+ G& S9 M2 ^. I9 R
printf("动态分配内存失败!");
7 L+ W. @" U9 ]/ Q# I( b: R return -1;( J( n2 `. r Z: X' U5 ^
}0 S2 q2 Q, f ^# ?4 T) `6 ]
S.top=S.base+S.size;
2 N7 O* m/ b6 F6 N0 c S.size+=APPEND_SIZE;% }/ Q& c# U& f9 O- t* a! G
}
4 x( j8 D) B& h( N% f *S.top=e;4 J3 ~) a7 D( u1 L7 z
S.top++;/ [) {" H+ {1 [6 z' F8 @
return 0;& B; S" s9 |. Q
}( l1 x; [- h8 K v& `% X
0 B) k/ A9 s, f+ B6 G. k2 }4 E
int Pop(Stack &S,SNode &e)
+ C) S3 O, q" H{
' b4 G* J' H8 P( V1 G" j5 ? if(S.top==S.base)# k+ }. D+ [! r1 J F! y V5 u$ T
{% ^5 U7 j: }2 N! z O" R
printf("栈为空!");
0 h6 B$ B2 H# L; L0 m- `& R# E, U7 D3 x return -1;
% F- }& r2 L# v5 @& C }# w1 g! o! p! ?# p p/ _
e=*(S.top-1); T" b8 P: `/ F* e6 l( h* J+ s0 Q
S.top--;
1 G0 u/ H6 R. T/ b% W$ F- w return 0;6 U% x+ ^7 I1 I( K! E/ T9 l' h
}
1 W, }" u `3 q
1 b' \( E9 S3 e' L5 T0 \char get_precede(char s,char c)
# J$ ]3 M* |. L: Q S{; Y( F" g# F4 ^% O9 Y; @
switch(s)
, s8 T% S" G. E- A4 ~; D$ [& e+ i {
5 X; _, n( S4 z# ] case '+': ^) C2 _4 S" r7 X3 K
case '-': j& O8 n, ]- I3 W. F
if(c=='+'||c=='-')4 S, y4 V* A: U" N3 u7 n3 V. _
return '>';
- v. ~7 |5 b4 H+ \' K& C. T else if(c=='*'||c=='/')
; B# d6 J/ A( O% f1 Y- J9 g' _ return '<';
2 U$ ]* o7 Y: f5 D0 v$ o else if(c=='(')
; \* O, H+ e: Q1 u `! M( h return '<';
( f% I% t8 ], k3 f else if(c==')')
1 R3 {8 x' Z M" e' T return '>';6 I$ w' |: D, L$ f# }5 Q+ u/ o
else % X0 ?$ Q7 B2 p$ |& D2 `
return '>';" r, @( r* \8 V7 e
case '*':
9 b3 v) j8 A# ]' _: D+ G* Z case '/':! s$ |) Y! k7 I$ ] [" p% Q. J3 a
if(c=='+'||c=='-')1 ?+ o3 ^! _5 i1 C+ C! h, o
return '>';
' K% z0 ?% b6 o4 j else if(c=='*'||c=='/') e7 u9 H6 p, `! O6 `; X) `
return '>';0 H+ ?, ^4 ~% |7 \
else if(c=='(')
" q$ \: \ M3 s' W9 e6 S return '<';0 u j/ f$ m" k8 g- v
else if(c==')')
& V ]# _! i7 [9 j, S return '>';! ?" |9 e1 p) p* F, V& |
else
2 f* p$ I' J2 t4 o& f4 \% X return '>';
+ z n7 s8 D! {6 V2 v case '(':9 P$ f: c8 {6 |2 K1 ?) O H
if(c=='+'||c=='-')4 ?! q+ I7 K% y2 e2 P5 x
return '<';
2 ~- O5 k! W/ @/ Y+ d; u else if(c=='*'||c=='/'). T" k; u( [) O8 {- k+ R6 d
return '<';
; ], j7 s$ g+ P# R( G+ M2 Z8 v else if(c=='(')2 P5 a% t& i3 V5 g+ E
return '<';
2 w, N/ I6 u8 L else if(c==')')5 P2 z9 U3 F6 ?# N& ?6 z
return '='; ^6 a$ \2 ` W8 I' l1 y
else
2 F$ ^ K1 Y6 M& H7 q1 l return 'E';
3 {/ D% s6 |4 @. L0 X ^# v0 {3 n case ')':# B* E, o3 B8 B+ f) D
if(c=='+'||c=='-')0 o# p7 d; q j0 p- D" J) Z
return '>';
# h& j# ?4 }! k* U4 a4 [ else if(c=='*'||c=='/')% P$ i q7 [4 V% B! M
return '>';
. v, [. u* o, `, Y else if(c=='(')
# _2 G7 j4 }- F1 W6 B( H return 'E';
3 i' `7 c, A8 g, M else if(c==')')! j1 x& _% G) ^
return '>';
& n0 T. ~ u* w9 r else
6 ]* t+ S- j/ ` return '>';( T! K% a- v: [: l$ k; }
case '#':
4 b2 { a/ q( i if(c=='+'||c=='-')- Y* ^- Y7 q t) X- n" |
return '<';+ F8 G' L( v1 L8 c% R% h
else if(c=='*'||c=='/')
" Y$ ^7 S8 \( F/ R4 Y3 ]% U return '<';
$ i. j! V6 x# U. |5 }! r. }, _9 z* u else if(c=='(')
& \( m* T4 n, [/ x F return '<';- C* D' [" R G* f! x
else if(c==')')
( Y& ~ v) F7 @9 V return 'E';
% O9 R3 X5 M3 s; r else
4 p( T# ]9 S0 E; [7 A return '=';- U) u. w. m1 R r
default:: R' ]) o$ b3 B3 W, p
break;
8 p6 J2 S& v" p `% u: L1 k }
1 t7 u4 E- v% G1 S6 ^ return 0;
, Q# I: {0 ^4 a8 w2 G}' ~/ Z5 e# h/ f o- ~( T: o
* k! b3 \% ^$ _int isOpr(char c)
" o. _. \( _$ E6 g5 g9 N/ S, V{
; R" ]( g) o' P0 \3 r if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
5 k8 L2 i; c% }, ]2 D return 0;$ r9 G+ h1 K3 V6 {5 Z' o& X6 [
else
: g5 b+ A4 @7 p; D: w. B+ b/ Y return 1;
6 M# x7 j- J3 U) X Y$ K; E* J}
% H, d1 S/ M) ^2 X& a7 E- n- K# W7 v
float operate(float x, char opr, float y)* Y! U* q% }! l5 t4 c/ R
{
8 Y5 B8 N8 c4 ~ u- i% D" { float result;" Z( t5 _& D) q# s0 \* x
switch (opr)3 l+ C- f Y( }
{' v* I0 N4 Z" W) d
case '+': . }+ _4 X4 n* @- u( |
result = x + y;
% n# J' Q; @# ` break;5 g3 R$ i6 G3 x: j7 N
case '-':
/ H& ^1 a0 z' S result = x - y;
7 {; S: S2 G! j1 Z break;
# D9 e) D E/ O4 k( d1 D4 }/ r; G case '*':
+ m# |+ X( {4 Q! K result = x * y;7 G+ E+ b' D9 ` V4 `, o3 d* u
break;
6 u- T \6 r9 u case '/': 1 ]" {- B9 I4 p5 y
if (y == 0)0 ^2 V* _. H* ` ]2 i5 Q1 R
{9 Y6 k5 B; e- z4 `* N
printf("Divided by zero!\n");
' s' H4 f+ S; y5 D" |8 o: B( ]% S return 0;
( [ n- Z3 H% j* b1 c }
0 o# @+ ~/ ^6 X2 z# f6 G4 h; g; ^" r. L1 L else
a. @6 _- w& N3 B3 R# x {
* N, L4 g) F, } result = x / y;
* O- B- i+ K" M) t+ W break;
' m; ?6 A2 a# J% [ }
3 d# n( D: _5 h1 X! [ default: # a- ?7 A" s+ d% o
printf("Bad Input.\n");
) D0 P; ~+ X. s! Q return 0;
?$ w J# {/ v2 n; h0 X ]+ P# t } _ [4 _5 |: b3 I6 a; F# D1 h
return result;
$ ~- x8 Y9 l8 q U( _% H} ' I4 v( U8 `8 H* I( f' S' e
/ ~- s4 u* F j n8 | v Q5 N: k) a
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/: R$ N2 {. q1 x! Q5 R' Y% U; u( u
{
3 ]: a3 e$ Y' j; ~% o" W$ D Stack optr,opnd;' P- [" M2 H& U# E) f
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
) S+ v" ~4 U- U/ V char c;
, E {: m3 ]5 q' b char buf[16];- A/ |2 \% D7 b' a2 A3 `* \3 c
int i=0;
5 T$ d; O9 Q' O! `6 |8 R: c
; T; z3 B, _* Z0 Q InitStack(optr); /*用于寄存运算符*/0 e9 b8 P2 U' r- u: c* L, Y4 E
InitStack(opnd); /*用于寄存操作数和计算结果*/2 G p2 S7 J! X1 _
memset(buf,0,sizeof(buf));/ [$ ]7 z5 ?, r, |
3 K$ l# p- O' h @
printf("Enter your expression:");: T! Y6 I/ m0 W8 P& G0 ~
6 y0 P3 q6 Q; o' \. N2 y2 a
opr_in.ch='#';
- a" O' u. [6 P Push(optr,opr_in); /*'#'入栈*/
. `9 m0 n6 j2 d2 g" {2 v% M( [; ` GetTop(optr,opr_top);; _- l% K2 B5 M; f p
c=getchar();! g9 I b) e3 z4 N
while(c!='='||opr_top.ch!='#')8 S; L1 L# i( I7 G! b
{
8 C& G. O; V1 }; J! L1 R if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
( O2 [9 D! ~0 k3 Y/ _8 v {! ~4 q. [# r! v. m, A
buf=c;# e: r8 U& T+ ~. S# E
i++;( _% X6 r n. v0 l l* L
c=getchar();
9 U5 q/ l' X! m: s2 U6 z }
$ m! \6 n% @: M4 n: p4 ?+ B else /*是运算符*/8 [$ m7 E1 ^5 G, w2 }7 z. E0 u
{
4 k' Q8 q5 ^5 \$ _$ U; E buf='\0';
?' w' l1 C7 L. Z. X. H& z; F if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
2 `1 x7 b8 j1 m' s' h* N {9 y3 P6 |0 d/ m6 q$ C: b, }
opn_in.data=(float)atof(buf);4 `; e# `7 `6 y$ \
Push(opnd,opn_in);1 H+ z0 ~1 F9 [5 ]- F5 q& x
printf("opnd入栈:[%f]\n",opn_in.data);2 g+ o) g5 i) s% M7 g
i=0;, \: E. B3 C! p6 f# e* d, K
memset(buf,0,sizeof(buf));3 W1 }" x1 z& `$ u* D& Y( ]
}- a/ S K: g' Q4 C: z
opr_in.ch=c;
2 U( j" ?4 }# D0 i4 K; O2 Q! h switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
) N, O1 m! Q) g/ G" w" B. Y {
+ A7 g/ k( M" s' a' N; l- N case '<': /*优先级小于栈顶结点,则运算符入栈*/
/ x4 p. P. I) k: E" _ Push(optr,opr_in);3 ]7 { o# r" h/ B+ }. E
printf("optr入栈:[%c]\n",opr_in.ch);
5 V4 C0 Q4 Q* `1 {9 \1 v2 Q c=getchar();
# Y% s }3 b, E6 b break;
" J" b, c& C @0 l' h* x6 M0 ? case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
. U. ]7 B! u. e3 Q4 h) q Pop(optr,e);
, v: {9 \3 E5 w2 S$ c' b printf("optr出栈:去掉括号\n");# ]+ f. _$ ]4 w- I& t b
c=getchar();( q, j( H9 z) J$ t$ d* N
break;
7 w' m+ K1 G9 W& w* e1 g4 _ case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/, _" k1 b3 D3 `
Pop(optr,opr_t);
" {8 M& ?1 l' l6 o9 {+ N3 m printf("optr出栈:[%c]\n",opr_t.ch);! ^$ S) N# f' i8 |+ B' O* T5 n
if(Pop(opnd,b)<0)! w+ C$ J! `* ]+ M2 C
{, A6 t. s: w3 T/ B8 E9 J
printf("Bad Input!\n");
% N* R8 \! O Q6 w/ J" J# M* n fflush(stdin);4 U0 V+ Q0 u% {
return -1;
# F. i( r0 r! w/ _$ ~ }% D+ ?6 G3 I# K
printf("opnd出栈:[%f]\n",b.data);
0 r" z- r$ m, u if(Pop(opnd,a)<0)
0 f( x9 H/ m3 p1 c5 p {% I, l7 R1 w/ X
printf("Bad Input!\n");$ i ^, }% }7 C
fflush(stdin);
- F/ P( G+ I6 v7 B7 s# F+ T$ \ return -1;/ Y1 x4 [, J3 C/ J5 y
}
9 |6 |' I0 l: ]( Y printf("opnd出栈:[%f]\n",a.data);! |1 ^; M/ s0 s$ L1 s* P1 n! g
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
5 ]# V3 r( G0 U9 T! G/ b Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/* d' _- p: M0 ^2 l" F0 l; c I: F
printf("结果入栈:[%f]\n",opn_tmp.data);
' u( i/ o y6 z& Z* g! ^$ A5 L break;' T( c' z3 I6 K b
}
4 o* z% E# \; L) |* m- m+ H }
. {: C+ m( D* ?: `) w" T3 n3 s GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ ! t3 t d6 H0 {0 @* E
}
6 m& x# ]7 e. v3 h GetTop(opnd,opn_tmp); \; R W2 [# x" D
DestroyStack(optr);6 X+ @4 c* h. K" M5 {$ d# _
DestroyStack(opnd);
, q# K3 O9 {! ]1 z$ y9 m4 @ return opn_tmp.data;: ~3 E# ~ t% ?1 K7 b
}
6 c4 `% i5 B5 F8 c* \
( H# N: }, d& @' X( t# Kchar *killzero(char *res,float result)
; L5 N, U5 K+ j% M/ a' t{* g4 a$ d/ J% `$ |# g
int i;
' M( H& D r: ?2 C7 [8 A L8 i; S& P3 I, E. c) @
sprintf(res,"%f",result);; j" O1 X$ _6 m2 ]
i=(int)strlen(res)-1;
" |% x/ u7 q% ]! n* Z+ p, b while(i&&res=='0')+ {2 g$ Y* @, t* h% X6 \
{/ W& I6 |. S* \( a
res='\0';! V! l6 V- n4 }
i--;
$ ]0 T2 p$ M; ~ }
: ~; R9 F/ `+ o if(res=='.')
9 f% v, ~7 P b* `/ N res='\0';
" q }; ~* x) `! I$ A b return res;
+ n6 c* P4 H7 \3 z+ z}" T! T8 x! X& x+ i' m8 S
" x+ r9 ~3 w0 H
int main()' T8 H Q$ ]0 B; M2 z0 a1 q$ Z8 \
{
; {7 S" y1 |6 l4 F& \4 W9 u5 C, A char ch;
; l9 f3 d/ a" M( j6 o. U char res[64];
/ {' V$ T9 w# K/ O( c" B+ L float result;0 B1 N. o5 _/ J4 {
while(1). D6 x2 ~+ `/ [ G5 f8 G. X
{2 X/ A d9 T1 H
result=compute();3 N {4 S D2 v3 e% b7 K2 P
printf("\nThe result is:%s\n",killzero(res,result));
2 \& o0 q% m* Z+ W; H; t3 C printf("Do you want to continue(y/n)?:") ;
; ~5 b/ d) w, S, g* b% E- m ch=getch();. E# n+ D% b3 ^# d
putchar(ch);
8 u6 j1 V* h0 [ if(ch=='n'||ch=='N')/ b- |0 h6 i7 D6 S! Q0 m* g( C# n, c
break;4 ]1 n; z4 a7 R4 b* i
else: b: y8 }6 _0 G1 S- [: _
system("cls");7 n% @) X* n4 o+ v" @- c" {+ `
}
* G/ U6 I! r$ e return 0;9 D2 p# c, f/ ?7 h2 u7 F. c
}
2 E; z! Z3 ^" n4 n4 r" k
5 X. A8 K* ^( l[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|