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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.1 `7 \; p7 m3 t/ S) l/ T
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=# v9 S' \- ]# W u; U: D0 e
/**************表达式计算器************/0 R- e t5 ~8 U9 `$ j7 L+ B* [
#include <stdio.h># g$ W7 P, D$ |! i! A. w
#include <stdlib.h>
6 A; o! @7 R9 d$ j! n#include <string.h>
5 i( b8 a7 z; A! P# H! `8 u* L- e#include <conio.h>: [1 K) _7 p9 S2 I
#include <malloc.h>1 T) `1 c7 Y9 T J
/ L' J' I- ]3 @, W& | }! }1 q$ n
#define STACK_SIZE 100' W: W* R. Z3 i+ @: [
#define APPEND_SIZE 10* T/ p% z5 i. \( w
. C. o0 N s! s, x
struct SNode{
$ C/ [. K) e. D* y; i float data; /*存放操作数或者计算结果*/0 M) x J% R" N+ X) _; l' z& N
char ch; /*存放运算符*// Y, C/ Q: K- _- m& _
};
}0 G" f2 W5 h& t7 N
/ Q" ]% d; S8 u4 E. S- Dstruct Stack{/ b* u. |: u# C# m9 h- n' @
SNode *top; {1 k, d# E% I8 j; u& l/ o, R
SNode *base;+ K6 z' z" U2 K% \$ J4 c
int size;% T6 E( [) R" T7 ]& W' A5 K
};
6 ?: p& _, @. Z2 V* [, _& a" @ i& K, k2 R
/*栈操作函数*/
( H4 t7 r x$ n/ p. Tint InitStack(Stack &S); /*创建栈*/
- R6 v6 J |7 L* a1 N Gint DestroyStack(Stack &S); /*销毁栈*/
- `3 K* L! A: |7 W7 j2 [2 \int ClearStack(Stack &S); /*清空栈*/5 P1 C$ Q0 {* t& G
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/" K2 _# E" |9 t# I r+ E
int Push(Stack &S,SNode e); /*将结点e压入栈*/7 H! E, ^- Q! S
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
( P. w8 ~ `9 s4 h9 l; ?8 R- m {3 u, L S
/*表达式计算器相关函数*/: A1 g1 @, F1 a& Q
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
: f1 w/ d3 x/ I1 H: z4 dint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
' g+ F* L5 x. J; }9 O* M: mfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
- |. q l$ |, l& vfloat compute(); /*表达式结算器主函数*/3 N2 j( v! v' g; f$ `
char *killzero(float result); /*去掉结果后面的0*/ * x, n5 i, g" ^) V$ \
" C# H3 H# X6 w: }3 m, j& ?/ Sint InitStack(Stack &S)0 {$ ~5 q0 Z! O! c {, X- c
{6 q3 x3 {0 M* N# u. v
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));. b& G' {+ \, K1 ]# z" W3 p% X/ ~
if(S.base==NULL)
0 ^1 v, N8 C9 @" l! n$ `- J! t {
4 m/ L, C# `! N2 Z; Q4 [6 A printf("动态分配内存失败!");6 s }1 i/ [2 s0 k, ^5 P9 p7 V
return -1;9 _" N" ^8 x4 \% L2 s3 d
}. K! U8 T+ ^3 C$ @, l* g& k( _* m7 \
S.top=S.base;
# c* \( O, D) Q# W S.size=STACK_SIZE;
" b1 U b* u( Y: M5 P return 0;* n5 Q. m8 [" L( }1 |% Z9 [
}: V6 h' E1 T, ~3 s
) W. z7 O+ |+ i* l8 k9 p- M7 b
int DestroyStack(Stack &S)
8 b8 m# m7 d6 j5 d4 H$ L, |{! T2 v- |- {& ^9 J
free(S.base);$ S: g. B; y4 S N6 F& c% V
return 0;
6 O) Z) }$ C& h o% E* o}/ e7 z0 F8 q, W
8 b% \4 T: Z: M& P+ ^4 o: s2 dint ClearStack(Stack &S)6 @4 m, A' w6 w' Z
{
$ L+ |% W/ j" K8 } S.top=S.base;5 y/ w; W/ |2 t* I; e
return 0;; U/ o( c, a* \
}9 @' ^9 V! |3 Y
# {* a) a4 w" ~1 e" {int GetTop(Stack S,SNode &e)! D' Z/ f3 [ j- r) C+ Q, N3 t
{& R+ y- e* p0 {! |9 q% ?
if(S.top==S.base)* @2 C) \' K A; y$ U! Q
{
5 ^* Z( ^4 k. o i4 ~% R' D+ K printf("栈以为空!");
4 r+ y( ?! J% l9 |" ~7 T return -1;
+ ]) N" S g8 ~8 U- N& i }: [% n; h" F$ v* A
e=*(S.top-1);
4 K" S; v; z4 V) F, t- c8 V return 0;
9 A* a" D- q) n5 l! i% _}: k- R1 Q8 q$ W' |0 {$ m8 j
) h E }8 Q7 T8 Y8 {
int Push(Stack &S,SNode e)
a+ G$ ~ a+ h' G{
$ S t1 j( j+ I! }/ x+ @" U0 ~) @% L if(S.top-S.base>=S.size)
( \3 h6 f( y$ G7 I; F. t' n {
( t% i- l" {/ H1 h4 y0 A S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
+ P% ~1 ^6 H: O if(S.base==NULL)! n& I- O% r4 ]" p* m. s
{2 L+ b% s) X# _: `, U8 ?0 [
printf("动态分配内存失败!");3 y4 L+ x' D2 {0 R2 u9 F
return -1;) N R9 w2 t+ G5 |3 \. V9 J5 X- ?( @) q
}, j" U; i- Z3 P) d% [
S.top=S.base+S.size;7 c1 I* L# B8 I$ ]; D# D% |
S.size+=APPEND_SIZE;1 R3 F2 H: F! A
}5 M; R! ^+ F8 O4 Z9 e
*S.top=e;
8 u; _4 L+ L+ U+ Y3 O) t+ E S.top++;) p }) Y" O) y3 l
return 0;$ b8 Q) W; U3 o9 [3 m
}
* ?5 _6 C/ I' F9 | S4 @3 k; O' d) P" y1 Z
int Pop(Stack &S,SNode &e)
4 v p! J! U- N{
1 B8 \9 r5 M: ~ b) |1 ^ if(S.top==S.base)) l* H4 z4 x/ {7 _* i' L
{; v# U1 O2 \& E9 X: g7 C
printf("栈为空!");5 G' l' O% x' B5 m+ N( Q0 _) |
return -1;
0 b) N* o3 c d, v4 }, e% q }
* v; U6 k* S: t& i e=*(S.top-1);/ u9 g5 S) Y2 I- I3 n
S.top--;
7 H) G) i. ]- O& V' i6 B2 T return 0;
, u2 ^, J8 }9 f% L# j}
8 ^' b# G$ m5 z0 W3 c$ v
; g8 [7 F- p9 zchar get_precede(char s,char c)
* M3 m& O2 Q1 x% x( t9 l- {{& A2 l) W; B) J, e' D& {% c
switch(s)
" p6 y1 i- ?' b" ]3 `8 Q3 `- H {! g+ V2 L; W2 a4 ?) Y9 e! X. l
case '+':
% O. Y Z/ G/ T) c B0 [ case '-':
/ |. _5 W, d/ c* C, T- q) O1 h, e8 ? if(c=='+'||c=='-')
b5 b3 _+ H/ Z* k return '>';
! I4 m8 f5 }4 V else if(c=='*'||c=='/')
% _3 {4 z. m4 E return '<';! F+ D, s* F, E: F4 c: J
else if(c=='(')( J3 ^5 y3 h8 @& n$ L
return '<';
8 E3 y8 [& V9 Q# t: d else if(c==')')
( G7 X2 |9 `. t6 @ return '>';6 Z, ` N+ I) C0 @! V; j+ {
else 4 I6 Q) A6 G! e3 Q% }
return '>'; r) J4 ^; [" Q* C9 }
case '*':
8 W- S$ W+ w) v4 l$ V case '/':
Z( I- v- L% `+ f% E if(c=='+'||c=='-')
6 X: W9 Q; D8 q' c5 {, k return '>';
1 w# @3 l7 y6 ]& I G; r' y, i else if(c=='*'||c=='/')
$ R8 M& C) q$ P, k$ u& J6 E1 j return '>';
/ t+ O2 _8 {# f! N" v/ M0 Y( S else if(c=='(')! {& G( A4 G1 @4 Z; n: M" t2 S
return '<';
8 h3 e" [0 |! z4 r else if(c==')')5 ^+ K3 j& E8 N% j
return '>';( f) u" u" Q1 S, ~* P- I
else |1 ^" k' Y( D$ _
return '>'; u: }2 _2 W1 p* U
case '(':
: k6 H% t0 ]7 c" w7 H if(c=='+'||c=='-')# P* r7 o: N* a4 W5 C
return '<';5 g# {. u; J A( n+ K! e2 J( S3 i
else if(c=='*'||c=='/')
8 M0 `1 R1 a1 h, x return '<';4 N) i5 J: _$ g( a. K
else if(c=='(')
t( B2 E$ j' Q$ f) v* n. ` return '<';3 R! ]% o3 }, I
else if(c==')')) Y4 Y2 N% ^% Z' \
return '=';/ ?7 c8 q1 G& u
else
: [' T0 \1 C( c6 y/ E. H8 N return 'E';0 a+ r/ G/ ?6 ]* _
case ')':
7 O s, c3 J) u if(c=='+'||c=='-')5 O$ n& c2 V7 v0 i# y/ `$ t
return '>';) ~, o' Q/ S$ \
else if(c=='*'||c=='/')
( s9 G, H. J) q( x return '>';& j# {! ?, Q; A
else if(c=='(')
, |' \+ o/ X; z8 p) b+ N return 'E';
3 @9 v/ D1 i7 ?( ` else if(c==')')
D) E: r! Y" m$ I return '>';
# V- c( [3 P' P* m) f; z3 X else
* k% J0 K3 G# K# h) n5 M$ @0 w' N; w return '>';
' Y- n6 `% Q9 b" ?$ k# K! W case '#':' _$ d+ k* t) o
if(c=='+'||c=='-')
& X: G2 e8 m8 X4 l$ z return '<';
. D' X- L% N1 h# ^ else if(c=='*'||c=='/')
- S8 N9 @; V4 f8 w" Y2 `8 L return '<';1 v9 W- | y9 p
else if(c=='(')
! s2 g+ U9 L% i) V/ a0 B0 y: h# s return '<';% z0 M+ C: F# L7 w9 e Y
else if(c==')')8 i" R4 {# Y; b
return 'E'; h: @, x' r: g% M' t* M' {% h
else
! V6 @. h J3 p+ S. u1 M return '=';
( }7 {2 O6 U& ]/ ?5 W3 p7 M [ default:7 _7 @, H& K( [
break;; k9 ]6 |4 B9 ]( ~' }
}
& ^8 {( Y& f6 } O s return 0; / q9 g. b1 n/ S% ^; ^) m$ V8 K
}
! ?/ u9 O- d' I& I% n
5 w; h/ t+ h% k- L* Xint isOpr(char c)4 K& s3 w4 Q/ \
{
* d: [# ?6 p' ?5 Q6 a5 g if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
, a" _/ E5 x6 |* h% h return 0;5 E) E8 W; g; m$ \$ `$ @. m
else
1 X2 c+ e% _& Y* y+ f( q1 R return 1;
3 d8 P- X! l/ `2 i" H; Y}
4 A% I$ c& V. @- Q- J' ~- q' [. n! c2 h4 i: u" e
float operate(float x, char opr, float y)" E( \6 D# x7 G) g
{7 G( i3 I& u& |6 l
float result; Q* a2 q2 `1 c; O1 j1 z
switch (opr)
" P, ^ i5 G0 a+ e5 [0 u {- F4 Q& d. h: e$ _% P" [
case '+':
! |* \6 _ B) G# k result = x + y;# K- r: L+ ^! n4 ^% y, x; _% [, e' k
break;* E! c0 p& U a x
case '-': V9 B8 _! F; I
result = x - y;
1 ]$ c, n7 S) F* [4 [% U3 w. t break;0 ]! k! |4 @; E6 M
case '*':
1 D6 b0 D% U/ N0 o) o3 j$ v) b result = x * y;
: E- F. P# [* Z" n5 w7 `" \ break;
# b3 l' P6 _* ~+ q( T$ k- q case '/':
' \3 f/ b: g& u$ A& z if (y == 0)0 O4 f' f: Z' W+ V
{
4 L. I7 L/ F. U' L8 U$ a printf("Divided by zero!\n");
% Z4 @0 o! S: F" z return 0;
. [' O7 w" N2 c* r6 Q }+ |' s, d0 e# ]
else# S+ M* u2 Z: ~6 r/ P1 G2 ~3 M
{
( p0 g8 P. U: Q& w5 s result = x / y;( w5 }; t9 M" t- k1 y
break;- {% P9 H3 ?$ ]4 w
}
: g( i' `) u& x7 [1 u2 A default: % s9 {- Z( ]5 @6 J7 L* _
printf("Bad Input.\n"); 8 u1 d4 f' g: I6 T2 V. p9 X" \
return 0;
' }( Z/ ~- |; Q" t" Q. A7 G }
& r6 `1 z8 s: s return result;. ~+ y. f) ]1 q: l8 {9 L$ Z( z
}
0 q1 K. x) L0 r1 n% W9 g3 ^9 U, K3 m# k1 u% m8 F% p' F
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
2 E% o5 v2 V; {{3 s2 y5 r) Q- [" Q$ o
Stack optr,opnd;
* A6 Z! d1 m4 E: u& X% r struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;$ Z4 a2 o. Z: J1 N6 `
char c;
6 P n3 m4 G* N% k& w/ _ char buf[16];: B: L6 i( T8 g8 Y) D Y& q. Y
int i=0;
7 u" D! t/ m# z$ u% i 1 T: N6 x1 p$ y6 m' I+ Z, }5 W
InitStack(optr); /*用于寄存运算符*/- v6 x2 l, K. ~1 K3 g2 e, S
InitStack(opnd); /*用于寄存操作数和计算结果*/5 G2 c; \' a! U; V
memset(buf,0,sizeof(buf));+ t7 M; U7 t+ p+ X0 u
# q3 `9 h9 k' T# _ printf("Enter your expression:");9 S( z0 D1 t3 q: P/ Q$ v# e. g
; |1 c1 D: `3 ^- _5 ?8 y T
opr_in.ch='#';6 ^# i4 [; V6 ^- Z, q
Push(optr,opr_in); /*'#'入栈*/7 {0 N6 T6 j& B: O0 W
GetTop(optr,opr_top);
& y/ ^* z; Z; z: g3 ? c=getchar();2 R- J7 Y; M# ?* t0 e
while(c!='='||opr_top.ch!='#')
* Y- m1 K3 A. ^7 t0 i {# {% x" q% ]1 K% ?! m4 s
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/. v+ u X+ R' r$ B, r
{
* [" X p! j* H$ N0 N! r4 r0 O, K: D buf=c;' e7 F- a3 J9 ]
i++;
8 W! r4 w, f9 Y5 L8 d5 s c=getchar();
: E7 G5 ~1 z& W }
# u. ^ I6 ]3 t) L1 L7 v else /*是运算符*/, X. L; z' y! B1 U4 F
{; p+ t" [0 E: c/ y
buf='\0';2 z$ I0 u% `3 j7 B8 q4 P
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/( E8 w1 {1 k$ f3 v, r
{" u* A6 L! J; w8 l# t7 L# [4 }
opn_in.data=(float)atof(buf);
, Y6 B5 g0 V% C( Q/ q2 @4 y Push(opnd,opn_in);
1 I) d% @" y! P0 K# p printf("opnd入栈:[%f]\n",opn_in.data);
8 _% A) L- A% e# R6 E, \+ S! T: R i=0;
8 R1 t4 a4 z) V6 M! b; @ memset(buf,0,sizeof(buf));, }" n* P4 `0 y
}3 i# k* F( L) a s, e3 l8 k
opr_in.ch=c;" x: t5 f+ A" s
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
( {& }& @9 @5 Q( j; H {2 {+ {9 d7 b& ^& }8 f4 G2 o
case '<': /*优先级小于栈顶结点,则运算符入栈*/7 Z, C) z, |/ V$ w7 q/ p( Q5 E. K
Push(optr,opr_in);
6 q. l; _) ]( s) w b printf("optr入栈:[%c]\n",opr_in.ch);
W. L0 U4 e* u( n) t, i6 H c=getchar();
: ?, V4 y9 L: Y- F break;% r8 z" N" }' X- H
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/$ W3 f8 U; T, I$ @" Q- a
Pop(optr,e);
; I0 M, p5 r4 G7 O! D6 Q printf("optr出栈:去掉括号\n");! ?% e! Q( \6 M% z& T' [
c=getchar();
9 Z2 K5 r9 X$ D# B- y break;
4 U& B/ r. j1 J4 H# \ case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
y7 H2 ? s9 [ H Pop(optr,opr_t);1 L9 v3 Z- M3 W, l9 H0 H& u& J
printf("optr出栈:[%c]\n",opr_t.ch);9 Z# V$ [& c( b6 k
if(Pop(opnd,b)<0)
A1 |: e( Q/ u {
" |; t$ u) j7 \! D9 m* A printf("Bad Input!\n");
1 C- Y0 m2 p' e( T" G+ w4 p fflush(stdin);
) Y. b- c% y' N/ T4 Q return -1;
& ^2 t9 S% J, I/ z2 K }
3 j* V( w% i9 W' n2 l4 K printf("opnd出栈:[%f]\n",b.data);2 X1 k x l% ^! f4 I
if(Pop(opnd,a)<0)
" v6 G4 H( Z) x4 {8 w+ C {4 i8 A+ s& v! A, Z3 A
printf("Bad Input!\n");2 d) j* q1 [4 F
fflush(stdin);/ h* @5 a' c" t5 o2 H& j
return -1;
8 q2 y! C9 A: _: w1 G: v }
7 r0 s/ Y$ ?1 [. J6 K% E T0 `- L& } printf("opnd出栈:[%f]\n",a.data);
. T* a0 R! t0 W2 O5 h opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1 n; Z4 G1 e1 S! @1 |0 h- n' f Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/4 t( J, \1 ~& ?; s( R5 c# w
printf("结果入栈:[%f]\n",opn_tmp.data);: l8 f8 `* S, y Y! @
break;
0 J- U2 `: Q' m }
, S, m% T6 r" b! M- V- o }
7 Q5 h% U4 j! N Z1 Q GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
2 I. `0 y$ t6 z- U6 L/ t }2 d* V1 W: g+ R! b/ a/ x
GetTop(opnd,opn_tmp);2 S, P q: _, {+ }, ]* `
DestroyStack(optr);
/ C5 s& ? F: M; p- u% ^* `1 ?3 i' J: S DestroyStack(opnd);
, ]1 a: R6 E3 G: u return opn_tmp.data;1 P6 |) L1 J$ K x
}
; b# T G, ^3 \' x# e6 r% ^0 `+ |: e4 g
char *killzero(char *res,float result)
8 ]' T Z {" |% e9 K$ @{; N6 Y" n7 }4 Q! C* R3 {7 `
int i;
5 _1 x( x! |9 e& T3 X3 _0 W" m3 v& W
sprintf(res,"%f",result);) y6 `/ Q, `' }# Q5 P1 g7 Z
i=(int)strlen(res)-1;
: O5 x- r8 J! z; X- g# t6 m while(i&&res=='0')
% Y p0 h3 h, b9 f( N8 U {
6 R9 X, m6 f# V3 u4 n, R res='\0';, `$ G+ |3 B2 {
i--;
/ T& x$ |& F* V& x/ y- U" [9 A0 O }. ?* s4 k& j* J, C8 o- D
if(res=='.')
# Q# V1 C# D& g8 X/ Y( c4 F' B: M res='\0';/ I6 y( o4 z& l$ g+ k. N9 ~" s
return res;
% R$ [; V- M% c# ^3 ?6 L}
' f3 a0 I: k4 D, j6 R
2 o! T. f1 d" ?) M; Mint main()
) x2 r2 E+ g0 W{
) u- L# h! b5 }1 X char ch;% J- g5 w% ~4 a$ `# O
char res[64];
$ U: t, i1 K( P/ [5 j3 B float result;* e9 l: i; J0 _
while(1)
! S6 e+ {4 g# D; H {6 H" E; t& v% S, u
result=compute();6 ~& n7 E" Q3 ` G: ?: v. s, X
printf("\nThe result is:%s\n",killzero(res,result));
" o+ |- b& L1 x/ @0 n! m printf("Do you want to continue(y/n)?:") ;1 t6 {* w1 f! t! _8 D
ch=getch();5 n d+ O" u6 m- v7 N M" q# c2 _' s
putchar(ch);4 y. y0 J/ G1 K/ M- `! @) T
if(ch=='n'||ch=='N')
/ {! d7 `5 w8 a3 v6 H8 F3 o) P; h break;3 n0 U4 D) E& m, }, W
else+ Q- q/ F9 q) Q! l
system("cls");4 ^$ }4 _3 z8 t) t& T% Y# r
}, T! [( I5 V/ h& ?1 f
return 0;( H( h, ^" {$ X$ R3 x0 E2 q$ E
}
2 M) I( v# G! Z4 M' L B1 c4 {* Q0 ]# H: p
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|