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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
8 {& P0 @/ |) P4 e* w! W% [/ Z程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
; l/ }( T0 N4 h! b: j0 c+ A/**************表达式计算器************/
2 Y' t, R& Z, p j+ y, e* @/ A: k% ^#include <stdio.h>
( H$ \: X6 I8 d9 [* ^% z7 M, d#include <stdlib.h>8 F. t8 P; k& Z' C
#include <string.h>
0 I+ q; C2 ]! ?#include <conio.h> f) a. C) i1 R: i
#include <malloc.h>
0 Z4 R! B- @" O5 h$ @5 w: e. M. @
#define STACK_SIZE 100
* h) k, `: Z4 _3 ~' r$ B#define APPEND_SIZE 10
; y' G% w8 Z) p9 \) J6 P
6 ^' p, _: W1 z' fstruct SNode{9 Z" v: |/ s+ P
float data; /*存放操作数或者计算结果*/7 p, M9 p9 o* K |6 W
char ch; /*存放运算符*/
3 [+ ]" A4 }0 d- g1 \};
0 r% ?0 ]3 i# g: |8 h7 X5 n7 N' h" o- @* n0 ]3 S! r" }0 r) O0 h1 ]4 F
struct Stack{5 y" c" C; U! K
SNode *top;! |6 j. r8 c6 }
SNode *base;; u6 x( g+ R, T! p
int size;$ W4 w" w2 f9 X' w9 \
};6 p" C1 l0 p1 V# N
1 T$ ~# z' x1 z. p M4 L% h+ ]/*栈操作函数*/) n- d9 L/ X2 t- {0 }# E W7 Q5 Q q
int InitStack(Stack &S); /*创建栈*/, \0 n) `2 D1 o, J/ {
int DestroyStack(Stack &S); /*销毁栈*/
2 s# I" [+ Z" Q0 _& |int ClearStack(Stack &S); /*清空栈*/
3 f8 { V$ f' O8 [6 Z7 iint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
6 C0 v" ^# q3 L# C+ D" r5 y( |. `int Push(Stack &S,SNode e); /*将结点e压入栈*/" \" a% J/ `( l% I# L
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/5 R7 g' E% L, B* C l5 E
& O" E2 v/ a P0 T
/*表达式计算器相关函数*/ E2 ^0 y9 ]7 w% r% d, z1 G+ ]
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
2 J0 X# w8 _% v# T& _: w+ |( jint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
0 }8 z# _* x3 q. i7 u. ]% U/ cfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
j+ t9 B. q& k. _, Qfloat compute(); /*表达式结算器主函数*/
1 f W8 n. C7 a, k0 ]char *killzero(float result); /*去掉结果后面的0*/
; I. i6 W$ E# M- h; @4 ?: x& Y% Y6 O9 N' }
int InitStack(Stack &S), U- R# J4 R1 J5 d/ @# E0 J9 g/ q
{! B0 e6 f+ _7 k5 e1 E3 b& W4 Q
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));& R5 c: }6 V! [- }
if(S.base==NULL)$ _& K: ^+ E, C- J
{! I0 Y0 w, t, A9 Y3 ^2 h/ b4 x* l2 X
printf("动态分配内存失败!");
, L- |1 F& @9 L return -1;
z4 M$ V1 B7 ~8 j0 K6 { }
! G/ ?. [3 D4 f! ?3 Y S.top=S.base;. M& \. k M6 t( `
S.size=STACK_SIZE;
3 T/ G0 W# j( }- r/ E- m3 t4 } return 0;
" ^) G0 O/ w$ l2 [* c, r s4 M6 I}
. {6 K+ O) i; v- n1 d5 v+ c/ |: `0 m4 `6 z9 D) Y
int DestroyStack(Stack &S)
3 T8 q9 F l3 G d$ W{. z: _& N0 ^$ c2 F" j7 M
free(S.base);2 z1 U5 N+ V( s$ i8 N* e
return 0;
' j9 m4 W( ^% C0 A& o( n}
0 M6 t4 w! _8 a4 i6 m R
6 H, j- M2 _ nint ClearStack(Stack &S)$ x ^9 P8 j& q, U1 ?) G- s- G4 G
{
9 ?, `1 Z6 T+ W0 e& P& ?0 F S.top=S.base;
. j7 m1 ~2 k- _: K6 f! l return 0;
& e- ~. J) R1 ~- x B/ |4 }, Z} T/ B @$ M. z) x8 d; T& g: h
2 W5 `" |; S8 ] N/ q' yint GetTop(Stack S,SNode &e)
: e# Q8 D1 g3 E0 n{# C/ V0 B# W8 h! w; ]
if(S.top==S.base)
, L; z* I O6 l( l2 ^2 C {& ?2 E5 P w& d2 E* y
printf("栈以为空!");, U. x9 N$ ^+ l" W+ b: r
return -1;
4 X# y+ s: {* a: q1 J- F/ F& [ }
7 i6 x5 x. L7 Y+ @4 z0 u3 I e=*(S.top-1);
7 A$ m g% I7 o5 ` return 0;% u( }. ^5 z+ v8 B$ S
}
! x& k: F9 E7 Q: r- I5 q* Z
$ h$ }# K: C* c0 Vint Push(Stack &S,SNode e)
4 L2 p! _ h5 ~/ D/ U{
0 ?5 p% p, a. D, x3 z) z8 i if(S.top-S.base>=S.size)
) `5 f1 S0 b8 g$ J8 J( n {
6 v5 B+ Z( \& N) Q v S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
E6 w0 s$ u; [9 H' D8 M if(S.base==NULL)9 G' Z/ z5 W& r* `" e/ ^1 Z
{3 r0 _# y: O# E9 V5 o
printf("动态分配内存失败!");+ [* P" P# Q. t9 F% l) j$ v
return -1;
" \! \/ Z5 J3 v }
$ f5 }7 G5 D- W1 k S.top=S.base+S.size;# y" R0 A! T Z) ] |) d
S.size+=APPEND_SIZE;9 j4 E9 h/ y6 ~5 M
}
+ a2 Y( ?+ P, ?$ R; { *S.top=e;" h) o. S4 y4 l$ |1 S1 Z* \
S.top++;# W e& j4 T+ \+ W
return 0;5 H; s3 V: j8 G. r+ L( A* F$ s
}* l* \0 J+ c1 r4 K
9 p" b+ X* N2 y4 t' [$ G
int Pop(Stack &S,SNode &e)$ m! }$ x% w6 _
{4 L% M# j! d0 a+ q0 X- z5 g/ r. c
if(S.top==S.base)
% C( `- N: h# ~" a) D# G {% r+ O. c3 m9 G8 o# \
printf("栈为空!");
) ?3 C4 q, P$ c" W% I- R, ` return -1;
( K. |& F1 I/ S: d1 q; U, K5 M }
: l/ y( ~1 l+ |! U e=*(S.top-1);
( Y, t/ H9 n0 v3 A/ R S.top--;
9 j( n, t4 s! l3 T2 B' q+ @ return 0;
$ m2 [4 }2 s1 c) Q+ e+ H}0 a' G! ]3 g+ C
2 d+ @+ L$ R- N) H2 d) _: [& k
char get_precede(char s,char c)
. w7 y) o, l' I2 h9 V, j) X{
( |9 I5 z' _* |$ Z) E# h switch(s)% ` i" F7 h. Z% A1 N }
{
0 I, a. W* \: i1 E3 K6 r. \: } case '+': # o2 D, T/ h2 \- p) F# T
case '-':& c R+ S5 u' i6 n) C
if(c=='+'||c=='-')9 J& s: i! m! z4 B
return '>';# a9 E# F: }; J. b$ x
else if(c=='*'||c=='/')+ A, S7 k5 k( H3 s- M, `
return '<';: m- T$ S* {0 k
else if(c=='(') ?4 d+ L3 r- C0 K" R5 U4 b
return '<';
( z0 [3 N! f+ @4 `( U7 s2 @+ z+ q else if(c==')')
, z( ?$ v" K' B7 s c1 u1 ^ return '>';
/ c+ b; U2 T. V: G; { else ! @/ X7 I( }: a% k8 w/ R
return '>';9 g' \0 Y, K* L9 O
case '*':7 N- R8 G$ T8 O$ b" ]
case '/':+ D. F1 ~6 }/ R7 u8 Q7 t; N8 c- W
if(c=='+'||c=='-')/ |9 f$ ~* L" A$ V! K
return '>';
) h1 o; S# ?- u9 Y% j* y else if(c=='*'||c=='/')6 @* B T: X& |" t2 e) z6 {
return '>';5 A* @; V/ e8 V6 ~& A: ~" t
else if(c=='(')
& H1 F1 R& u+ L; u return '<';/ K9 C' z$ G' D5 t
else if(c==')')7 X) ~7 K4 S' k) }) Z; [
return '>';# n) E$ \8 m$ x- W4 s2 }
else
4 m7 i6 b& d* ^3 _ return '>';" i' Y+ F( O- y1 e
case '(':8 D. N% A& Y, z: e. F9 Z
if(c=='+'||c=='-')0 Q: k. i; q8 o' d x5 h/ n
return '<';% B; p; q1 V$ E0 V3 n+ O8 p
else if(c=='*'||c=='/')
2 b5 f0 |: q9 b- Z return '<';
% F8 g) b8 k' B, R% U else if(c=='('); N: G$ ~, N5 a! T
return '<';
9 b( t/ V4 _$ s( Y/ p else if(c==')')
* i ^5 U8 \ P3 y1 X1 t return '=';
/ C* y# V# U' n0 Q/ l( a else
1 L( k9 b; {: S1 w: f0 L return 'E';
8 L+ c) K" E$ ]2 K3 X9 i case ')':$ s' P$ @7 p+ B! H7 I! u
if(c=='+'||c=='-')
% e. Y Y" f& R( _. Z; ?5 ? k& ]- W return '>';- u, l ~! ~1 Q& P
else if(c=='*'||c=='/')
% k, F+ }1 @4 D- z8 a E return '>';4 n3 V% u6 L6 Q: L- N+ A
else if(c=='(')
3 D, Q3 k k A3 g return 'E';
8 N6 J+ A6 F4 Z7 e0 M else if(c==')')) y/ R, n! y, v! f0 L
return '>';3 b' h C: h' }" Y
else- t' g1 F e% E2 b/ Y% ~
return '>';
4 `! p% D; {8 I" J) u" V case '#':
8 I H# q4 j0 k2 a, _0 p/ `7 N5 Q if(c=='+'||c=='-')4 j$ t$ a3 F1 i/ C# ]) Z9 O
return '<';( N# `4 U6 Q5 K: {% F* F) _
else if(c=='*'||c=='/')
2 ]- Z" ]* z, [7 v; K- ^+ g | return '<';
& C+ p; a- N: p2 @" P" G else if(c=='(')' P- H% B. V* ^/ k6 Z
return '<';
( V1 g, @8 F& m7 D% v else if(c==')')$ P. f6 u7 E0 _. O, n& R
return 'E';; R( a0 R2 N8 J4 i5 a
else# i; s& }- O* T4 a8 e/ O, S
return '='; b: |, R2 |% i; j- j3 k! h
default:9 y) w) \" u- N! d9 `
break;
+ [6 e2 ~) ]3 f( P. b" x; u }+ A7 H0 x+ _( X% h, L9 G5 X( F
return 0; & Z9 s6 [ s! T& ?! A7 \
}5 R9 L2 [( [8 z- L$ [
8 l: J. I. `% O1 f9 ~; Lint isOpr(char c)9 F( X8 \9 h4 }$ X- H: L3 Z% u
{
) ]( C$ M6 c6 D! Z if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')7 v' {6 X' p3 U, P. u8 h, q( h
return 0;
/ n% f+ B# G3 r/ D: F7 } O, C. ~ M else
% s) w7 J/ v/ e& S* _! u return 1;
# X9 L) B- L' _/ e' O i}
4 L8 a0 u+ d K; n) k: R
- v( ?" z+ r# U! e7 ofloat operate(float x, char opr, float y)
. I D7 K) z: N8 `4 I+ d{8 {# d+ Y$ S6 ?& Y
float result;
+ D& C; u+ r/ I2 O7 V B# I switch (opr) B0 T \" k& B
{$ @( K- w; u7 f, q" o) S4 U1 K
case '+':
+ w2 [1 K5 I# {$ x result = x + y;2 a; z5 g4 S8 \/ J, u: }" N6 A; w
break;
3 o/ d5 W; X! ~! d* C case '-':
/ d w8 b: s( z# P' ]. Q result = x - y;
" g8 F4 g3 J: v& T+ T break;
& y& O5 a4 U4 x, q9 Q case '*':
% M% f7 Q4 \7 ` result = x * y;
4 L$ O4 e( }! p; y0 g break;
7 @% @( [& B4 t# r+ p. E case '/': " B6 x3 q! l. d1 N
if (y == 0)6 @* R4 [9 l5 O( t
{
/ h, ]& I6 N; |# \ printf("Divided by zero!\n");
4 _! A5 W7 A- E2 Q1 V return 0;; M) J& u ]9 s
}
3 b" |' H) ]( ~ p2 n3 z3 w7 \: w9 @+ J else
! J* n& O3 f$ H! \* d {- [/ ~5 P- c0 u+ c
result = x / y;7 ~- }+ L ^5 Y7 C
break;
) R3 z e6 c' Q9 m; D }
1 S6 g( O$ J% H# R& R default: - _# K& w7 s, w" ?2 ^+ E
printf("Bad Input.\n"); & ]0 Y0 M3 ?; f. p; D
return 0;
$ ?0 Y. Y) F$ f9 d }
1 _- X) N! L& z( N1 b3 ` return result;, P& C6 p& e/ M {* |0 |9 @6 n
} 8 [/ r' k! c1 u `$ |+ l0 |
* M- Z8 x0 H1 g- s9 U ?float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/2 {* _: p: X: s* B
{
) ]: H- J1 c! _5 [& D* U* Z: K Stack optr,opnd;
# U% Q8 v1 B3 ], B# ` struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;: Q2 w% Y& B4 t% J
char c;0 k; \) z* A) H* u( m- U& T
char buf[16];
- i0 k+ v& z3 x int i=0;# \! K' z* \& d6 v' E# [2 ]* I
& z B5 y) d/ M& s6 R! y InitStack(optr); /*用于寄存运算符*/
( p$ z6 q3 [' l; T" p& l InitStack(opnd); /*用于寄存操作数和计算结果*/ B$ Q5 C% I4 T" }) e: U2 j5 B! L; n
memset(buf,0,sizeof(buf));+ _( b; ^4 L9 j! Q
6 Z- S' e: O" u6 W3 ^
printf("Enter your expression:");! J( ], m, v+ Y
1 _% ~: O3 z Y2 D0 s% L& }' }# \1 O opr_in.ch='#';
# @& g* j [, |8 W8 a3 [6 C Push(optr,opr_in); /*'#'入栈*/8 y) W$ D! R" H; H
GetTop(optr,opr_top);' H& G2 Q: n- L
c=getchar();, h$ i# ^4 l0 b( U
while(c!='='||opr_top.ch!='#')4 [$ ?+ {& H" C4 T! B
{$ B0 b( x P3 R j2 E" `
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/" m0 |2 D3 j$ d" R4 w) T
{+ o2 E( V. l5 ]4 c, U9 j2 c
buf=c;$ |! G- s- q8 a! ?7 B" {& e- j
i++;! F& Q8 f. O. E$ F' ~/ i
c=getchar();( f- V) N t6 X7 L
}
4 U0 e$ Q" C2 F! w3 C9 Y6 n else /*是运算符*/
; ]0 S" f! E$ v- U' ` {& @! Y, h/ H/ J, Q
buf='\0';
5 J3 x7 N- w6 l. t7 W if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
. r# v% \8 I8 T2 x9 ] {
/ \. [: k3 B2 x$ ^. Y8 R. R opn_in.data=(float)atof(buf);
( M7 \) I: G1 e Push(opnd,opn_in);
& U3 R) q. a: i( A4 X/ W printf("opnd入栈:[%f]\n",opn_in.data);, M" Y3 Z U5 |# {
i=0;
# w+ k1 |" I, M5 y! G% ? memset(buf,0,sizeof(buf));
2 B4 }; ^- F+ y) r$ C% X }
9 ^& ~5 k5 L) L" N opr_in.ch=c;" r ~( u h1 l0 I. @
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
2 Q: l4 f3 W: L& f {+ c% T/ J K7 m* `" e) Q
case '<': /*优先级小于栈顶结点,则运算符入栈*/) e4 R7 |: l; V6 b9 ^ v
Push(optr,opr_in); d% D% f0 I' r
printf("optr入栈:[%c]\n",opr_in.ch);% W$ D5 j/ Q$ t
c=getchar();
5 s( C; X$ g( A* A break;- U/ _7 j. f& s5 x
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
; A9 M- L% `+ U, Y! I U7 V Pop(optr,e);
) {5 y |0 j8 j2 g printf("optr出栈:去掉括号\n");# p4 n' D$ s- `6 t
c=getchar();- t' @1 [( n1 U( k3 n) w( W8 ^
break;
) G3 i% J, [( i2 v7 W case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
: ~( e, c6 R# ~* z/ T2 z5 f Pop(optr,opr_t);
8 Y6 P) a9 R; K( Y: C printf("optr出栈:[%c]\n",opr_t.ch);3 U: p r3 X7 ?% o3 X0 ^+ }
if(Pop(opnd,b)<0) y9 q5 j& f0 M7 q
{6 j; I5 J- i- _5 S, l2 L! G8 q
printf("Bad Input!\n");! R+ ~$ r+ ^4 E8 i0 d6 r( u
fflush(stdin);; B w7 c! t5 C% V$ `
return -1;* R7 [; t! v4 e9 H* L
}2 O& Z! U. b+ K% n: _4 q/ n
printf("opnd出栈:[%f]\n",b.data);; N9 ?$ c2 j; F% p
if(Pop(opnd,a)<0)
8 s9 a6 m2 f6 ~ {2 Q' c3 H) M3 `( }$ T! T6 K
printf("Bad Input!\n");
/ Z% Y: O! d4 @, x fflush(stdin);
( F% o" r% F" F& K9 u- A return -1;
# N. z% A/ S" l }6 v4 ?6 w# a: d3 B
printf("opnd出栈:[%f]\n",a.data);
( _. V! C+ c1 l3 H8 Y9 r opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/7 X- L* V8 e/ k8 z" o
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/( o J7 I& [ B
printf("结果入栈:[%f]\n",opn_tmp.data);
+ S( E& r9 `1 |6 n/ Z* H0 Y( z break;
; X( ?& L$ U& I) v1 o }
' s, V" h8 j. L }
) H& {1 z) n2 ]4 ~% l* l* D7 z GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ + \8 A: Z- V4 Y& a7 I4 O$ f
}: t9 s+ M! H( J9 c
GetTop(opnd,opn_tmp);3 r3 e" v& U+ Z
DestroyStack(optr);0 ~/ x2 E0 G8 O3 v0 O
DestroyStack(opnd);
- o/ \0 V2 a$ P+ I' T return opn_tmp.data;
( k" l$ z' a% e% L" E) `% n* @}8 T& O& J; ]4 }" b( P
$ [7 t& Q; C- Z6 w
char *killzero(char *res,float result)
4 ^# M2 p! R& Y( f{
$ ~# v- ?' }$ _) T% l int i;
; R. I" L" M f8 i) h8 [. o5 C8 L, O
sprintf(res,"%f",result);. a; m* X' i2 Z! g, I# O
i=(int)strlen(res)-1;
+ D7 ^* ~0 ~$ f" c" q* B! O0 F1 t while(i&&res=='0')8 }0 V- o8 i. e
{- I9 m0 G. V& X$ b2 x
res='\0';
9 Y! p) k' I& m i--;
6 Y3 ?+ k5 S p& g8 ` }! u; F+ l; `/ l+ u
if(res=='.')
3 T' K$ L& q i* U. f4 K8 V# F res='\0';$ N5 z# _7 c1 u" H" E
return res;$ G# Q c/ a0 E: E$ O6 b2 p) ~; j
}
& c7 [8 V# A+ Z5 h( E1 j ?1 @7 r' q! ], M! k. ^% `+ ?. Y
int main()# \8 N- N% I) `, O
{
! f7 f4 b8 e4 }) K char ch;
# W0 G M: Y( ~. c n7 J char res[64];
2 X0 y8 C" f3 a0 B float result;
8 A) \7 }8 y' V5 R: i& s$ ~ while(1)3 X2 A2 K; O7 a5 E5 f; \0 n
{+ @& P8 R/ y" E5 a0 j8 V" f
result=compute();0 W9 ^8 p, O( i
printf("\nThe result is:%s\n",killzero(res,result));
# l! Z9 h/ j% _9 I1 T. y1 B+ j( K printf("Do you want to continue(y/n)?:") ;# l+ y2 e+ [* H$ s" W
ch=getch();
. C; ^* V) k; @+ m1 i putchar(ch);
0 y% E/ _! F9 B* Z& f) O( @1 u if(ch=='n'||ch=='N')
4 w% e# [6 t& ]. M# ?( Z break;
1 Z8 i1 G; p8 J) ^5 J) [ else
. Q' I2 e4 ~: c system("cls");: g/ z: @: C& r, |* |8 V
}. q3 R! h; p7 n/ D- T" H1 Q, f ?
return 0;0 q/ u* U1 b$ k: z+ u
}& ~: o) x; `3 s) a& X) V! A5 J
7 p. o% b$ J7 a, [$ [* k
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|