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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.1 U- ]7 a( O* \ ]
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=6 e- ]8 P3 C: r4 e
/**************表达式计算器************/2 U8 k3 N1 \) \+ g% e
#include <stdio.h>$ k4 c0 ] `/ Y: K4 @
#include <stdlib.h>1 N, e' K$ U' ?- Y6 O e; p5 `
#include <string.h>7 M6 M! r2 A4 i3 K, X, s# M; ?
#include <conio.h># Z6 x n p e/ y( E
#include <malloc.h>1 h6 y/ D, [* d+ M8 r$ r8 r. }) {& }
3 E( ]0 f Q! X x# q: W2 V#define STACK_SIZE 100
+ w3 ^* Z6 ~# S' u#define APPEND_SIZE 10
: c: T. b5 {# P6 W
4 R$ T' U, N1 P7 H C& a8 kstruct SNode{
( t y& [, {& }( r$ r: `& G, f float data; /*存放操作数或者计算结果*/8 [! y9 q# k! K3 `" m
char ch; /*存放运算符*/. E/ A+ O( T8 I7 C. C' j
};: d" y! r1 |6 W% E! G
' H, ? W, a n" ^1 G! D) `struct Stack{* i( E2 P) h8 Z6 h% _1 ]
SNode *top;6 ]# @) @; m- Y9 Y3 h
SNode *base;
" H& a+ z# ^% Z3 m& h int size;- x5 ^. |( E2 g3 i
};
/ p" `$ b& f; t t J( v9 r- l/ N: V" J/ @& N _
/*栈操作函数*/- m1 @7 @( g( u! ]
int InitStack(Stack &S); /*创建栈*/
0 K% f' w2 `0 q/ s! c7 @: wint DestroyStack(Stack &S); /*销毁栈*/5 s& C# O- ` E" z1 x) p
int ClearStack(Stack &S); /*清空栈*/
% R, x8 Z" i/ b- H( |0 [% U Q& qint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
- s3 d8 E/ o. w1 S; z0 eint Push(Stack &S,SNode e); /*将结点e压入栈*/2 P2 v) M% o' w2 ]4 v2 {
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/2 n. S7 n5 ^: S+ x4 ?
# P8 V1 S0 i5 c
/*表达式计算器相关函数*/
# t& E; W0 R& I( i$ k5 Bchar get_precede(char s,char c); /*判断运算符s和c的优先级*/. h6 c( q- l6 p# @, g7 x
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
0 l7 v' D, `2 B, i, Nfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
& L' J! F/ q8 ofloat compute(); /*表达式结算器主函数*/
4 @0 {1 z5 n7 N+ y! D/ B9 gchar *killzero(float result); /*去掉结果后面的0*/ & [* |: C. k, L* @7 ?: ]
7 a8 f; n8 m8 x" M) I
int InitStack(Stack &S)
- M2 Y, r4 S( s. m{% T. Y5 g& s5 j2 a! T$ n" I- P
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));- v! m8 {# y( L% ^; G/ y
if(S.base==NULL)# g' V. R9 ]5 b: N- A
{( P+ e6 l+ `2 v1 R7 @ f
printf("动态分配内存失败!");! a8 |; ]( G( H
return -1;- s5 m" y: F% [ P( j* I
}
0 E ]1 U& D5 [) V0 _, y* g: t S.top=S.base;
+ P9 B, f3 e- O& ^ S.size=STACK_SIZE;# ]0 V! C1 [* J# [) ?4 P2 Q
return 0;( g- |+ ?: ]( d
}
& O4 L Q% F# n
4 Y: \( q& D( z/ [' Uint DestroyStack(Stack &S)5 f2 W6 j+ @8 O
{
7 b/ |/ k% }1 \) T9 O free(S.base);
- [! v2 ?- _4 W) |. n return 0;
7 A$ Q4 Y2 B, @% l }5 V2 y; g}$ f( w9 i! z. ~! `2 L6 i& _
' ^" l; z0 `5 @/ Eint ClearStack(Stack &S)
0 b3 d; y! I" E{2 @% W! d/ f+ n2 u7 a7 H+ g8 W
S.top=S.base;
3 p0 p3 K+ @. E return 0;
" F0 n% s7 b6 Z1 L' n}3 l A. t! |4 u9 F7 q
2 t7 X% m! K! a5 r9 J) R( Lint GetTop(Stack S,SNode &e) n2 O T' f: ^8 z4 G. ^& o6 g) {3 _
{+ g" N0 C4 G+ |1 f
if(S.top==S.base)4 V F& |4 Q4 [+ L% z4 j7 ~
{
" m8 A; z; ?' h* H$ W6 h printf("栈以为空!");
0 i# `2 I. m7 f8 V/ F# Y return -1;
% l$ n$ Y' R* l8 r- K }% Q: P6 ?( G. ?: ] `
e=*(S.top-1);
* O4 k7 x8 ?* P+ ? return 0;
5 y5 x3 U8 @( X/ x7 B}
* g9 U N- I& _6 t; W, P7 |8 k! W& v
int Push(Stack &S,SNode e)
* r0 u& U0 `( k1 a& G{9 v# ]: `/ }3 ~( [4 i; T7 F
if(S.top-S.base>=S.size)
_1 L/ Z F+ A' m) z {
6 R P4 ?& D/ g2 I4 A S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));( m/ S6 n6 S) R h, I' X* Y
if(S.base==NULL)
. w) C0 M g2 q9 A& y {
( L9 d5 U8 a% j1 S# u0 ` printf("动态分配内存失败!");
: [; t& i" n. x# i return -1;
! O5 {9 s8 e3 |0 ]* ]8 ^& b8 } }# K* `( b* r$ U1 d1 w3 w1 |
S.top=S.base+S.size;: [+ `" P& ?3 J6 n, ?- _6 D# D2 a0 r
S.size+=APPEND_SIZE;2 f2 _, q5 V% t
}
! }5 m, y/ H' f+ n& \ H *S.top=e;
5 B2 W" U m' [. h( E S.top++;
2 q3 j1 m) x# n; y1 G return 0;
: d5 }4 u# O! d8 I" B0 {}
: N( V; B6 r( J4 K8 V% B' ]' J+ U2 v' N
int Pop(Stack &S,SNode &e)6 f( W* b$ q) r5 e' E K
{
; v3 K8 [# F0 @; m) k, E# i8 g) y& @ if(S.top==S.base)
1 [, @$ Z+ j, E' T% Q {
! h. U2 Q' W+ a/ v+ z& I printf("栈为空!");
. I) g' g( p& I4 v% g, _. h return -1;
* A+ l$ ?) k& J* Y$ ^& T0 M }
7 A6 H; l- V8 Y4 _ e=*(S.top-1);
1 Z& v8 Y! d; O5 F+ ^0 x* m S.top--;' h! l1 @! y* n% r# y' d1 W9 g
return 0;
$ E! \+ F6 I* s$ b1 Z}' K" H9 i2 T1 F5 h* u' b
5 N) [2 M% ~4 R0 r/ b/ p6 Wchar get_precede(char s,char c)
1 |- r; i7 B2 f% S$ H0 L0 y" n3 b3 x{+ T; V- U k) K( w$ f
switch(s)
2 W& Z, l6 W2 O' Z- X {
. Z* s6 z# h6 D7 q, | case '+': - C- b! k0 l5 c8 _1 ?! S
case '-':# c' o+ z" ^; t- ~: w" p8 \
if(c=='+'||c=='-')1 Z+ W* s0 I7 D* _3 m% e, D# ]
return '>';; z% z2 U6 l! M: u# b; D
else if(c=='*'||c=='/')
' n$ P5 ^" {( h: o% v return '<';) {) S5 Z$ q& v' U1 U3 L
else if(c=='(')
8 W7 Q4 T% d/ p4 c" d3 ]% D1 V return '<';- [1 f& J7 |' B; q- d; P+ _
else if(c==')')
: y; E0 E' }2 C4 C2 }1 Y& i- b% m return '>';: P2 w( ^& |& D6 O. l! @: w- I
else
9 h P2 h2 I& r! a5 y) [. b( { return '>';
4 C' ^) P1 @' w& E: U" w case '*':
' K w. n2 q, m* K; K6 j5 f0 [) x case '/':* w) r, H3 w3 S/ Z; F
if(c=='+'||c=='-')
* o3 @. g' h, Q+ M, f return '>';2 A0 B. r6 L, P) E [' ^7 p
else if(c=='*'||c=='/')
7 F6 }% x7 |0 U2 }) l return '>';7 x$ ?- b' q' K- X' w, o9 g1 |
else if(c=='(')
: u, U8 R( e1 Y3 I; l. l return '<';
0 s% I0 E+ s/ R4 a9 F" r2 h else if(c==')')+ v( J# F* O5 R0 l# n
return '>';/ r* ?1 I' t$ Y2 _$ Z8 f3 g) ~
else
6 h' X& E8 z! ` return '>';
+ k1 B2 K2 c& u. g case '(':
/ V9 U) R7 ^( v! z if(c=='+'||c=='-')
V% J) _" E+ h. A) c return '<';( j9 J% a6 Y5 W! } b+ |/ R: q4 s5 L. u
else if(c=='*'||c=='/')5 p ~0 b* E! ]
return '<';
b ~, p4 r# U* n6 H7 B/ Q else if(c=='(')9 \% u/ `4 x$ f; s' c( `( J2 a
return '<';
, n a) \$ g) Z/ N8 \7 q else if(c==')')
4 t1 U9 c7 r2 X. c0 \1 P8 d/ k return '=';; O, ~& \6 [, G8 R: ^! h, a7 k: m2 ~% n
else" a$ b% m: ~$ V# f! \% I& o
return 'E';
+ b) O8 }% `. {1 k case ')':6 K" y- _7 e! m! {' v
if(c=='+'||c=='-')
# F7 P, g- V" f% h, `8 e- ? return '>';
b7 n6 ^7 Q& h else if(c=='*'||c=='/')
- K1 M+ \8 r/ [7 r5 T4 V; O. I return '>';7 }5 p6 Y$ ~/ Y V$ I7 l4 M' ?& {3 `
else if(c=='(')
+ W. E9 P* v: } z6 ]- r return 'E';/ {; ?4 I+ n/ E) q7 H4 Z
else if(c==')')! i8 P; p. I0 `' g3 {
return '>';
1 }! X6 B+ o! ?! D else
& K3 l9 S5 }* O' g; C return '>';
! w! h; K; ]9 t5 g case '#':4 ]3 z! E7 X6 m
if(c=='+'||c=='-')0 q) M" R b [' D, |/ m
return '<';
; k/ z. [* z+ e0 I else if(c=='*'||c=='/')
0 @' c( {* @+ j3 X return '<';
6 e/ {& z J3 t* Z( T0 W6 W else if(c=='(')
3 a9 V0 O, a S4 w return '<';
: i4 H' r9 r7 E* r else if(c==')')' b* w0 E( s6 _- g5 L( z
return 'E';
( J9 Q! x3 v9 Z, ?9 b, ]! c else) `6 q8 Y5 U& [
return '=';
" Y5 B8 N: ]+ P$ o L7 R) }4 o) X default:
- H. r" A$ @, t0 B break;, k( k; V) a0 O5 N
}
6 r) Y; i" F7 t, ]/ n return 0; E8 P9 N' C% ]' d
}) ?* G h A" A3 G; m! v3 ]! t
, \' G7 s9 L7 n: o1 N" w
int isOpr(char c)
3 e( Z- W) p( J0 E4 A5 l{
% k& `% W) Q' J if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
# b! q7 H/ E) |7 b return 0;
& n9 h u& o. J+ J) ~' L( x3 ] else , X8 ^& o8 K# J I
return 1;
5 p; y+ N Z- G X}: B5 R9 Z% p3 b, u
% w: z7 b+ L5 q9 ~
float operate(float x, char opr, float y)
3 c& ]1 L3 z9 ]{
% s: ]( ]0 n8 G0 V% F& L5 c$ l float result;
T- C6 @; W5 x! S. {2 s8 \ switch (opr)
. T3 N" ~/ _' G) p7 g) C# f3 D {% w4 g9 u0 R; \" Q- m
case '+': * z- u3 ^; x [) C2 H. _1 `
result = x + y;
3 z# ]8 B, C' l9 E" { break;
, W2 Z1 k" ~; w& Z7 W. z7 @ case '-': % o2 _, F. h$ k4 P
result = x - y;. b( y4 M ]# H6 @ T8 }3 Q
break;7 u2 Q6 ~; c1 }3 Y+ W9 L
case '*':
8 B( y: ~, x" q' U9 L3 c result = x * y;
: }+ V2 r: \1 h9 ]8 b break;5 P+ P1 u6 P3 w- p; f( M
case '/':
, J* f; y& V% j" o- F! X if (y == 0), g, ]8 M# Y# h
{
5 c+ [ h' z4 Y- M4 D printf("Divided by zero!\n");
3 c. ~; a! c' m N return 0;* Y7 q' Y( `" e: B7 e
}
' Y% I9 g) Z: N* |, i5 o$ ~ else/ D3 w2 p1 ^8 g5 e# b& }
{
) u# g T4 q; v' K4 X% F8 }, z result = x / y;) ], ~* s$ w9 r+ \# i- w2 A$ |2 b
break;5 ?; M- j# ? B8 v/ w' Q0 `
}. j/ {+ B1 u. O3 B2 h) z
default: ) ~, J \/ e& O! L- [9 z c2 }
printf("Bad Input.\n"); 3 O6 B0 Y9 V/ f3 W) v
return 0;
' v' Q: r6 C! \5 L- {" d }
" O, z$ R: o/ M9 i- B return result;
* \ W$ J3 u' ~}
8 S. g2 E& c% |. k4 |3 p4 k6 b" h" k2 P
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
: ?! k& }- m+ N: k) p. m0 N{0 a9 H* m0 A: ]
Stack optr,opnd;/ t5 w" Q& i* C! g1 f9 p1 K
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
1 w4 @2 F5 A4 G3 T$ V char c;# D" r+ t t/ J c5 a
char buf[16];, }3 b1 Y8 E6 M
int i=0;: j8 Y, d* |1 ~$ X" d# U
7 Q! O5 I ^& ]6 h, m1 ^ InitStack(optr); /*用于寄存运算符*/
, n0 T; t) c+ d InitStack(opnd); /*用于寄存操作数和计算结果*/9 o: e; M9 T' g
memset(buf,0,sizeof(buf));" I; }- U3 Z2 ?+ X( \% G: `
5 U9 A% {% c1 t* k; b* F4 I$ a printf("Enter your expression:");
4 u, | r3 f. u( Y
% N0 ?/ ]' K4 w6 J# H opr_in.ch='#';
; f- p: M a3 O' C$ E Push(optr,opr_in); /*'#'入栈*/5 S9 W* I: E9 q% ?; [; v
GetTop(optr,opr_top);5 W) m& D8 ^, {: s$ h/ o
c=getchar();
% s; U6 ?. @( o$ V: D while(c!='='||opr_top.ch!='#')! e4 A# i. q) o
{; f: W2 W$ V9 E
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
. T4 ^) w/ w" K" L& u! H {
: N' l) q' y+ [6 D buf=c;" U K o( X; y( q3 x6 F
i++;' t$ f P, G t5 g' @
c=getchar();; X: h2 E M( H' E/ @
}
; p! `8 r! |) d1 {6 e ?4 t/ V else /*是运算符*/3 o1 b/ a$ U! C+ E; Z' E) i, {1 a m
{
6 e9 V' H1 c; {0 q. y8 L0 Z2 v buf='\0';0 K, I. O2 T1 C! T
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
7 b# M5 f5 y5 O9 j {
1 A6 u2 a9 ]0 S7 H% {% x" L opn_in.data=(float)atof(buf);
) c9 u9 Z& K4 w3 H* \2 y Push(opnd,opn_in);
6 W" M+ p7 C. h& R9 q printf("opnd入栈:[%f]\n",opn_in.data);2 A2 h; H8 V+ d; K" s+ D& P
i=0;! ^3 b, I! g! B, X6 z% k& z
memset(buf,0,sizeof(buf));$ x; V# t$ U( c# V, @" B& A
}# v2 @4 u. _& s# v
opr_in.ch=c;- h. U8 Q, K$ i. d9 o( p- {" j
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/6 t- v& G$ f6 X: d
{
. l" d3 d& X, p5 I/ ?( R7 X4 W case '<': /*优先级小于栈顶结点,则运算符入栈*/
, B* d6 _, |* o+ g/ Q% ^/ @! w Push(optr,opr_in);0 T/ b, |* I, ]
printf("optr入栈:[%c]\n",opr_in.ch);
2 p5 E2 u! F g/ l) x6 H c=getchar();8 v3 R& E& |+ a4 u- k
break;
$ y0 a% J3 J# i% i# _$ z case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/2 C( S g1 G& S( d: i3 Z; h
Pop(optr,e);. q( b0 m) |- L+ \0 [* y: l" H. O) ^
printf("optr出栈:去掉括号\n");
8 t$ A+ | N l9 O8 x ]6 | c=getchar();
/ y$ B, m# B% ~0 p- N break;
. l8 ]: [# h$ m0 P2 F+ |4 ` case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
7 c$ n4 w! V! f Pop(optr,opr_t);. Z3 m* P# ]: V' n$ A9 D! P
printf("optr出栈:[%c]\n",opr_t.ch); t$ z# Q& t; c3 g1 v5 j& H/ X
if(Pop(opnd,b)<0); w1 }8 K; S& u4 e
{
7 X) U* `+ L. g, y# g printf("Bad Input!\n");" {3 b+ m" A: [2 n t: D
fflush(stdin);. m- F0 W2 m9 N! p
return -1;' _+ U3 B, a. ^, K. F
}3 e1 _* T D' P
printf("opnd出栈:[%f]\n",b.data);
4 `( h1 Y, w' C' m! _" ~7 L if(Pop(opnd,a)<0)$ Y- S" A( C5 M
{
" D, G6 z! c0 Q printf("Bad Input!\n");
1 W0 h9 I1 U8 _! E3 A fflush(stdin);/ q1 p2 ~& ]# p* I, P* L
return -1;0 p2 q6 S: l P' l9 K" F
}/ z) l' T7 O3 o( x& u. R* f
printf("opnd出栈:[%f]\n",a.data);9 O. x$ s, L9 i& k* o$ b& t$ T) T
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
$ R. w$ G3 d8 ?$ I( O# ]7 S Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/3 e& b% P% Z9 o, N2 \. A. F, I2 K. t! R
printf("结果入栈:[%f]\n",opn_tmp.data);3 G1 x! T! y* l6 |: K
break; g. s% C( ^8 r
}8 l3 {: X; A" A7 c/ Y
}3 b' ]" e1 R1 v8 J# u
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
) D+ f6 Y8 g$ v! T; m" q2 h }) A& e* c; S+ {; h' z5 B7 V1 O
GetTop(opnd,opn_tmp);
' g. y* E- b6 g( }+ J, w' o DestroyStack(optr);- o [, X. Q$ n$ p; G/ B8 H
DestroyStack(opnd);
( o3 R: T/ M3 `8 i3 {# h return opn_tmp.data;
8 ~3 ~% c5 D, y N. h0 v' V}
; O/ ]# e6 Y. d8 l1 f9 X9 {* H5 k M# d c! F' a, d6 O
char *killzero(char *res,float result)
* L7 }" e" O- f. Y$ R5 W/ u. O{, y/ F* g/ p% h( A9 _
int i;
0 D* E1 [9 n: w; v
1 _ |+ J5 }% \) B sprintf(res,"%f",result);
7 U" y; c. f; y( d2 t7 N: K i=(int)strlen(res)-1;
( v7 c- ~6 y6 y m5 u while(i&&res=='0')
: S% e+ d5 {6 D" D {
* I+ N9 X) ^- }! A4 w2 n res='\0';
& k) C9 n# P& u! F* a i--;% }7 G9 V1 w; O# H1 q9 X8 A
}/ R! B+ V1 c, X' z( x$ P
if(res=='.')7 o8 G1 i' _8 u' N" [8 r0 `3 a+ ]4 P1 w
res='\0';
# f4 C4 y1 V$ ]9 B; @2 h: N- G, Z* k0 O return res;
, n. @- Y F/ R& e2 m) P}6 E. A0 ?3 c% R( Y
" M4 `+ [; Z, Q' P' k9 d9 k
int main()9 U9 r$ H( G: G7 j
{
, S% W+ i2 _7 @* Y2 O. Y) { char ch;
4 x1 p2 l+ U6 N" k% ?. |& v4 J char res[64];2 J( p: F" k* G
float result;
$ r8 g9 k3 }: q while(1)+ Q% u0 d& h" V; o( {: I2 o' c: j
{
$ }+ X, ^% s2 _6 Z; Y/ Y/ W result=compute();2 g* d: G* M/ A" A S1 O: t2 ^1 a
printf("\nThe result is:%s\n",killzero(res,result));
% X' [ e3 X/ |3 v ^5 b. y printf("Do you want to continue(y/n)?:") ;
1 n! E: }" U" x6 e* T- Y ch=getch();* S) a% }/ C: V3 ~# W' m
putchar(ch);
8 R* w+ h# n* o( V3 i d if(ch=='n'||ch=='N')
' |9 c3 B( i, X# G `: Z3 A8 [0 | break;+ p/ W9 @! y; J! T9 Y7 X+ z) M
else/ B5 \( U/ K- }) \& J
system("cls");* M/ O+ d+ Z4 X: x1 \8 O
}
6 l9 p$ _, }: j) B7 T) D$ d return 0;! }: O0 ~: u. h, h
}
. l& n* t5 Y) k3 m/ O4 P& ^; v8 X1 G' g5 k$ i7 E$ ^5 W% X3 }
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|