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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的./ ~, Y& X" D6 E, D& V B+ w6 e
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=1 M, H( b0 k( K$ T% ~5 m
/**************表达式计算器************/
2 Q7 o, A7 U ~- n#include <stdio.h>
: {$ ]& h% Z7 \6 }7 ^#include <stdlib.h>
8 m+ H+ l5 z1 g#include <string.h>4 D+ \6 ~- X! E* O I/ L, D; q
#include <conio.h>) r$ q; U2 t" B$ r4 |* Y6 U B
#include <malloc.h>
+ t3 q: Q$ v9 B( g
1 ], s7 Z# n# ~0 t9 V" D9 M#define STACK_SIZE 100
2 x8 K: u1 [- X+ I: j5 o6 C1 K#define APPEND_SIZE 10
9 e/ `) ]; Q4 [" @
2 t) h! g# O+ v9 M$ O$ k0 estruct SNode{$ Q7 ^. R: s7 C1 t3 J- K. Q3 w4 ~% j
float data; /*存放操作数或者计算结果*/
$ W3 x9 V' y8 O( x: @ char ch; /*存放运算符*/+ ?( t. q7 _4 y, |3 Z( n
};
6 _5 z( ]$ C0 v+ q+ v- [
v3 H$ J( T: j# H9 Q- Hstruct Stack{9 _9 k. Y) P* _( Q% k
SNode *top;% ]: z# N+ g4 F* v) j
SNode *base;
0 C: h: K2 A9 t% w int size;
2 ~! U& y) T# q8 ^8 b( r};; m5 F5 ? w" m9 U) F' @6 ]5 V: ^, j* ^
( \2 g/ [+ t- R0 ]8 Q$ i1 ^
/*栈操作函数*/1 C3 Q E. D5 ~7 F
int InitStack(Stack &S); /*创建栈*/% s' e5 _1 A4 M; o( G$ \
int DestroyStack(Stack &S); /*销毁栈*/
% p4 ?6 v6 S& _8 a5 g9 ^int ClearStack(Stack &S); /*清空栈*/. V$ E! Q# ^- H# D. g, z5 [
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
9 a8 U) n, U# ]4 Fint Push(Stack &S,SNode e); /*将结点e压入栈*/
' k$ E0 Z7 w* g$ pint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/9 ]1 a. y+ e2 _3 g+ K/ d+ ~" k
* k* f2 a: d. T" C2 Z/*表达式计算器相关函数*/' o: q% j% ~: l
char get_precede(char s,char c); /*判断运算符s和c的优先级*/8 t: f1 J! A$ L
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
6 ~5 U& I% `: \4 @float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
2 e3 }. Z* b" j9 K4 A& Q; k5 I# ufloat compute(); /*表达式结算器主函数*/
. W+ ~" G, S; [+ g9 d6 m( j. g1 Echar *killzero(float result); /*去掉结果后面的0*/ - t1 S2 P- B! r, F2 y" d
5 n" D* p0 y3 |int InitStack(Stack &S)3 X% o9 q1 P7 ?+ n7 U. A# W
{2 ~: k, n y- H4 c* @0 l$ a
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));0 w3 [! v* C% Q- X1 n
if(S.base==NULL)+ J& ~+ _, V1 j
{2 Z2 z0 e' w* e; {3 k1 l) {* {
printf("动态分配内存失败!");
1 }8 X3 H; m4 `( ?3 q# X) x& Y return -1;
0 F4 T( l/ T% s( V }
' J C" i- r+ W" z5 s S.top=S.base;: g6 v; E: Z$ n+ f" x: z
S.size=STACK_SIZE;
1 U% j1 r9 L! c x0 D D. H/ I return 0;
( ^: A( m! I& ?}5 |5 c* R; ~# J
3 }9 t5 p1 w0 b# a
int DestroyStack(Stack &S)
3 H3 c+ d. s; s. Z% _- h9 P1 V$ ~{
/ ]! R: b. f7 F free(S.base);
% n: a0 x9 V0 ^7 L return 0;
/ W# X$ B- w4 }}
/ ]& u6 w* j2 A R8 V# s8 D& p5 @" w4 R# j) m/ Y: t
int ClearStack(Stack &S)
& p' _( [ |0 j, |# I% r{# r7 I: b1 O6 _5 t7 v$ s
S.top=S.base;
! `/ `5 k$ b$ C, z. [/ q return 0;
H3 @; F/ Z7 u3 _. _0 h}8 T- k) H' k8 j3 _" E5 F, `
0 g$ D. H& K) s* m9 r& B. ^8 s3 m# k/ h
int GetTop(Stack S,SNode &e)
( u: D( X' M# w{' Y8 p- u8 p4 U& B! {2 s" N
if(S.top==S.base)
, w# G6 x# x- z$ k9 M; q9 W {
5 H, D7 H- ]1 d; u" \- e! t9 t printf("栈以为空!");
+ i3 } T/ l! S0 w5 {, d return -1;
7 C8 j5 T6 n0 T }
5 B- ~5 w; s' y5 E9 c$ y2 F4 I e=*(S.top-1);1 S, z9 @* D6 K
return 0;! b. D2 ~6 g0 q. X9 w
}5 ?' R4 ]* {9 v6 y
! Q0 ^0 A `8 o, pint Push(Stack &S,SNode e)
( L- R# C _6 n& |) u{
. `8 N8 C/ L* s1 D$ Q- [% Y if(S.top-S.base>=S.size)* x( Q% U! E' g$ g" Q/ K
{- ]0 x9 l2 E- g4 A0 B+ W9 a4 T
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
: |, p5 L" X) _/ ] if(S.base==NULL)
1 {! t) B& Z* d, F ` {4 y5 ~1 h8 g" g' ?- K( _9 t( i4 J _
printf("动态分配内存失败!");1 h3 U6 c' \: G
return -1;( P9 O7 m) C+ n( t9 g3 G/ J
}: y2 L; i& h% e/ q; x Y! Y
S.top=S.base+S.size; \ ]" ^4 z% R6 V$ k- x
S.size+=APPEND_SIZE;
7 z2 Y) K: c: m* F* ~6 y% p }
" x# T( _9 z/ F" r *S.top=e;, l4 F2 W% u& u0 J6 q6 J U9 J
S.top++;
! @; n5 u+ N0 [+ z+ U7 n return 0;* J% `( I! M* w0 p' l' n
}$ M$ X" e$ A& z% l ?/ |
& b9 k. x" G* ?( D# `. w
int Pop(Stack &S,SNode &e)
O. K2 U M: n6 }{
, D: G( s( V l/ e. F if(S.top==S.base)
$ E) y1 u$ f3 T! X7 k: } {5 [$ j9 I2 l& N) D" b D
printf("栈为空!");
+ z, N* u8 `3 \* X7 { return -1;
4 j5 S2 d( t, c6 j }! Q* J% `" b2 G* R
e=*(S.top-1);
: J& r7 r, f7 [4 U8 g( Y S.top--; b# n, T" p! }/ p
return 0;3 _+ D, A1 Y1 `7 ~* v
}. V5 z9 Q/ H. W; `; l& k) q
4 W i; o2 r! r) a9 Nchar get_precede(char s,char c)* S2 L8 L! g1 a/ a, P, D" u
{
2 S( `5 J4 b& o+ F3 I switch(s)) r# b: g/ w z I9 [. j
{ D# z# l! N9 [4 e1 z
case '+':
* @! J2 \) }$ Q( H' a8 e2 A j5 s2 m case '-':
2 r, H. f9 H5 h- t3 K( { if(c=='+'||c=='-')' H0 P$ B4 z( N9 C
return '>';
7 r- S3 }0 W3 T$ T G l+ s6 X else if(c=='*'||c=='/')
6 Z/ D$ h6 o' J) N( i7 m) Y return '<';
3 k5 w; G3 N b else if(c=='(')
% i2 v8 }: n& E7 z% f6 o Z$ q return '<';
; }) W# Y: O2 q, o7 N( z else if(c==')')# ~. c0 {& j+ j
return '>';
% ~" A8 \' V: g else 1 E/ ~) e& s, F, U! }% f4 \
return '>';
5 K% u7 c: c9 m! | {6 R2 u! ?8 y case '*':
' z# }( _2 n; } i case '/':
. z6 j! u/ Y' f Q if(c=='+'||c=='-')
6 K7 Y: n m7 I7 i return '>';
7 m9 c6 ^4 J. h2 x. L7 Q+ \ else if(c=='*'||c=='/')
6 {! M n& @7 V8 L" ]$ w5 ? return '>';
! _9 G8 Q( A# t: R$ F. d% u else if(c=='(')
8 e' l) o! R1 w return '<';+ J" j9 _* F; ^- ^
else if(c==')')
! G5 M8 v D2 g- U return '>';" {& r5 p0 f w$ y2 R
else9 `6 q* B0 G/ N; \* l4 x! ]
return '>';
5 j1 I% {! R# l8 e, w- Z4 w case '(':
1 m4 L8 L# s5 e% F9 R' ? if(c=='+'||c=='-')
# ~" n% {6 I5 Q, K$ K( k return '<';
& q) ` Y5 h' e) W% H else if(c=='*'||c=='/')
* ?# `/ b! I1 A) @ return '<';
% x, ^( i' S0 h. v. [ else if(c=='(')) h, J: e+ u6 f2 ?2 a
return '<';% L' c$ ?, p* C7 Y. Y. _5 Q
else if(c==')'). W) p, Z w& F+ `2 P3 N8 S
return '='; Z: ?7 O4 M3 O; _: ]$ l/ q
else
( _ W1 `" _& @6 I6 ~ _0 B return 'E';8 u. {; I) T5 g' y
case ')':# G3 ?7 i, {: j! Q3 e) D3 R% H
if(c=='+'||c=='-')
0 W' k& F# K' T( V return '>';
7 }- n/ k, u# g# X else if(c=='*'||c=='/')& i, m& K3 t+ V0 m, d
return '>';
( U5 {8 `1 {7 T; D( a, V else if(c=='(')
; y: t# u; `8 ^. K$ } return 'E';8 Z* b' D5 x8 T( }8 c0 m3 I
else if(c==')') J8 L0 ?( m$ G6 h
return '>';
1 A: ~; a1 q8 b) C else
! P9 {8 W+ X! r. A" r6 H$ e) `$ k+ x return '>';+ s: e* w. h# j
case '#':% [( f6 ?$ I* ^7 C: n* H+ U
if(c=='+'||c=='-')
( s1 A/ H' ? Q6 n# l7 p5 \ return '<';
* w2 y" C. U/ q8 @5 s9 } else if(c=='*'||c=='/')' d6 J7 Y% `1 r! Y0 A5 p' n
return '<';" P! _1 C) `$ V6 u/ X2 ~1 X
else if(c=='(')$ N- V" b, H% J9 Z+ r$ M+ ?8 O2 t( r6 G
return '<';# b3 J* p+ x* M- D8 L
else if(c==')')8 i4 y+ U1 K, X- D/ l8 I
return 'E';
# n* y. a* W8 y else& y; [. a. ?' D% I0 K) O6 F* Q# F
return '=';
+ }. \! f% U8 P8 e0 L& W default:' B. @; b: \7 j
break;9 ?% N( N) z& |; D. [0 }$ ~
}6 }" N* J# b' l: Q" Z1 Y# `& ]. N
return 0; 8 U F" u2 c- R8 U5 f+ p i
}3 x9 K1 h# F" }0 L# }% J% q
! a: O# w0 ^1 |, Cint isOpr(char c)
1 E& P% k7 w: m- O. j/ x8 ~{2 x* p$ _% I' }5 g5 N
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')* ?- D/ Q& F# L) B6 u( h
return 0;# p+ B: g& y1 l! V: w
else . V, U* i8 q* F) k& I9 T
return 1;
+ W. B% T& X' Q2 a9 Z' q4 a}
( K/ _0 t3 o5 P: v! ?$ h- g, H6 m! h! e/ z1 X( J4 J2 c
float operate(float x, char opr, float y)
- i' i6 e: N+ j7 I% \{7 ^7 Y5 k5 z% A1 D
float result;
/ v0 i6 I5 w+ m' k# U8 o switch (opr)
# }! X& B! P' K9 f; F {
: W( q/ a+ J0 A case '+': . F- Y9 i% A5 M2 F; k3 |3 M
result = x + y;' |' B. r3 X5 m8 m
break;# E0 `1 N5 o6 n2 ^
case '-': ; {3 e0 d) k- |$ N" ^
result = x - y;" B5 j d+ K5 [& Q. ]
break;
+ X+ a' M3 R. L/ x case '*':
% ] j9 M" n" u$ P* x2 L result = x * y;* F' l* Z2 D. o2 Q( a/ a8 c
break;
2 ~# B+ A) J9 S& p$ p& m case '/':
" I. W7 v2 Y& T6 z1 n2 ~1 U+ B9 W if (y == 0)
, V! S4 y. s5 M. |5 N! z* O k6 l {
" k* K7 i N4 U; } printf("Divided by zero!\n");
0 [/ u8 _; g6 P: c# } return 0;
5 j# t8 v# t. t, p }
/ U1 I3 G: e |: D else
5 p: L# }* S7 w$ l# V* }( g {# o8 z% [" k; M
result = x / y;6 b3 Q* T* k( `* z
break;. P& D' T9 t8 S! S- F
}
; M! S! r. {& Y0 Z% @ default:
) P; l& H2 }6 `7 q, ] printf("Bad Input.\n");
8 X) I8 C S" C$ { return 0;
3 h& o/ y* I+ K. K }2 ?/ l7 L+ O; B- A: u: B- N
return result;/ T: j/ s) B4 z% N7 K
} + A" r5 G! [/ R3 t- N
0 z* W" J- N6 h/ X+ r6 Vfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
% }. d( ?, j- r7 B{4 H& {, n, p% E T7 G: l
Stack optr,opnd;) n* r) Q$ y0 D
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
$ A! v7 P9 M9 k5 p4 |; ~ char c;
) W' H$ v; Z# w char buf[16];% r; H0 |% P; r3 X1 z
int i=0;
. P9 s. P( F3 J* d% ?' ]% I - V) b+ J7 L$ S
InitStack(optr); /*用于寄存运算符*/
% M- G& l2 e1 | InitStack(opnd); /*用于寄存操作数和计算结果*/1 u% g/ ?) r9 U! Q/ y8 e
memset(buf,0,sizeof(buf));
4 g0 F/ n! w7 L1 q* `$ l " J& v* I! X5 Y1 ~3 u
printf("Enter your expression:");5 C& x& l" C; v) k
3 L2 F P# _! [: C" l' U4 h
opr_in.ch='#';- h! h9 S! [+ w) \8 l
Push(optr,opr_in); /*'#'入栈*/5 _* _& ~. W# }( X$ y3 z
GetTop(optr,opr_top);
& {, S% l2 a2 I c=getchar();& T: Y0 o* Y4 x/ d$ I
while(c!='='||opr_top.ch!='#')# q" K) {8 p: @4 l$ ~7 n
{
+ O4 p' B! f, L3 i+ i if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
/ m$ M: l. S- h0 F/ j/ h {
" m9 n S9 \+ C$ i, I h buf=c;
0 X) W8 }% f/ M: o4 b6 } i++;/ H" z2 k2 F, ]& X7 V; O2 }
c=getchar();8 ?3 L9 M O" p& D$ `3 Y: i1 B
}3 S& ?8 g3 i' X# [$ ~
else /*是运算符*/
6 I' U- t7 h4 J2 { {
/ Y6 {) D; W9 a% y/ ^ buf='\0';* D i* B$ U' x6 l0 U
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/( D& z" a I! @: N4 i" |2 _ @
{
: T9 g [4 D0 D# a$ l opn_in.data=(float)atof(buf);) a3 k# J) s: O) `% l, J& t
Push(opnd,opn_in);
. I; X+ O' g# ^) \! K- L printf("opnd入栈:[%f]\n",opn_in.data);/ X* m! q9 G* o
i=0;8 @- h3 S0 m6 d
memset(buf,0,sizeof(buf));: V. B0 Q, Q K( i( v
}
8 w& Z- {# d/ |: b. T# P$ S* l* P2 j opr_in.ch=c;
3 `. X% t& Y2 J7 A1 I switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/9 P: A- q$ d4 E
{' n; k7 [: a/ \) o) k c# T% {
case '<': /*优先级小于栈顶结点,则运算符入栈*/6 B9 S/ W; E+ t7 Z3 {$ ]( U9 @) ?
Push(optr,opr_in);3 E2 L$ w6 Z/ K& X* V5 K0 f! e
printf("optr入栈:[%c]\n",opr_in.ch);
! V7 G( h' k, B/ m6 A c=getchar();- _, c/ z) V4 h, ?' k) w
break;
& ~, _: @' p" h: m7 L case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/* G6 i; r+ i3 Y
Pop(optr,e);3 h" H/ O# E0 N" d
printf("optr出栈:去掉括号\n");
9 V7 B, _! l0 e c=getchar();- M; a6 \2 {1 u
break;
% g* [5 I5 ~" J# K5 B: i6 S case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
2 {4 {* S' J# n Pop(optr,opr_t);
' E* {" N; I( u9 C" \4 M3 V$ }9 H! S2 p# p printf("optr出栈:[%c]\n",opr_t.ch);: d% O) p1 _ y
if(Pop(opnd,b)<0)
q/ D5 u* d/ r* `$ R$ \ {
: c1 y( r& @3 | printf("Bad Input!\n");4 @$ ]8 M* ^# k9 h9 y! x
fflush(stdin);
: s7 l( w* R/ d4 X0 v return -1;
# K, q5 D* v$ x, s% j; ] }
* {1 j4 n3 Z$ l1 y printf("opnd出栈:[%f]\n",b.data);
1 `7 ~( c. o+ |8 m( C if(Pop(opnd,a)<0)
6 X" k( M: j( `; o {6 K. Z. v; x) i' b$ e
printf("Bad Input!\n");
" V& d8 F; I, D- _7 V% e fflush(stdin);
* }8 _9 m4 x# d3 D return -1;
/ y0 b; z4 b5 h3 l" q6 L, m }7 v- V+ l+ k. l! n2 l
printf("opnd出栈:[%f]\n",a.data);. u0 A* s. h5 A u. g' x
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/1 |. W- I% a8 b% {
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/' w& r' v1 I5 b6 U2 n; A" s: z
printf("结果入栈:[%f]\n",opn_tmp.data);
+ F# r4 e# N& N5 O7 n9 ~2 u" K! n break;
9 x7 Z4 n) b9 t2 J3 w \* L$ m* F }
7 c0 P" W, r2 j+ t. Q; M# O }% A2 f2 @1 W7 y4 f: j- {
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ ; v |& l# }. c- R- b9 c6 [
}
3 u! x" P% \2 ?, Z1 ~+ J GetTop(opnd,opn_tmp);" z( u4 E; B' |! b$ I2 n$ y" I
DestroyStack(optr);
% g" f! L% y+ v8 L9 a DestroyStack(opnd);; R% d4 H2 @4 A5 J9 \9 _
return opn_tmp.data;
) J* `% x6 c, K' |. P}; i& E3 H; G% J4 k5 N+ _: F+ W
7 Q5 I8 U. A$ Z/ s* [char *killzero(char *res,float result)2 \8 |5 d% Z$ |+ `( A
{
0 ]7 |7 k6 z- Q" C8 Y; A int i;$ B0 ]* m5 }+ q9 B
$ y% _: `7 j3 M# t
sprintf(res,"%f",result);9 N* o- b W" _9 {4 C& b) I+ f% n
i=(int)strlen(res)-1;
: r- S6 H. N" H3 i' ? while(i&&res=='0')
4 ^5 z- Z9 i# t. ` {
* ?) g4 V5 \$ q+ N! L7 s: C res='\0';) g- k! F9 q1 k
i--;
) e( V$ n. d0 z+ ] }
( _) x- U- }* d+ M+ \ } if(res=='.')
# }% ^ x1 I/ p) D! ? res='\0';' N! U: C( U1 C$ h% ] _3 Q) @
return res;6 ^( a" J0 d+ `' U
}5 R% R0 K% }4 B
# c* F/ E) T6 y! {
int main()
5 O- c7 L' {3 r" J( V% a{
8 S5 l, T) d8 |$ | char ch;
) a1 Q Z1 o3 Y N5 P: @) k; e& } char res[64];
9 T; u4 r" X1 _( {" P, Q- `$ ?0 X: d float result;
" x) ?7 b7 H' d) L# {8 f8 [- g while(1); |2 j8 m2 s; ]" \
{. [+ H( q! R" E' x: G! y
result=compute();
, o9 ^( O+ f& J& f printf("\nThe result is:%s\n",killzero(res,result));) y& r) m& e9 A7 z9 a% O/ ~
printf("Do you want to continue(y/n)?:") ;- m+ M, W; B$ Y0 H
ch=getch();
6 Z) h8 w# y* i/ M8 {6 Y+ G7 c putchar(ch);! t6 e- w, O$ d
if(ch=='n'||ch=='N')
3 q0 `/ S( g1 D# K0 h# _ x break;% w8 ]: J$ a$ ~1 N4 G, u9 M ~
else
# d$ N* Y/ Q% g, R; R2 ?- o7 G) c system("cls");
6 ?* ]# ?3 t0 U" ~ }
0 [6 _8 ^. z/ J1 M, T return 0;! d. C) i0 _7 s E
}
{" y( H4 j" [6 p, { a/ Y/ @# D& }- U. P B
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|