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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
. @* L7 [7 i B, h! e5 ?程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=+ b2 ^! c# T! n( s/ e) w
/**************表达式计算器************/% y- U2 c/ U, ?7 ]8 H+ E
#include <stdio.h>
' c' B7 }/ L: i, b4 ^$ ]/ l# E#include <stdlib.h>
4 U! o3 P( O$ {) r5 j+ B* i$ ~#include <string.h>
5 U) H4 A/ c" m) B#include <conio.h>
1 e6 X. z C# ?: B6 }#include <malloc.h>6 K+ |! W7 L" h# X4 }
9 O" ]8 {1 o$ A* P" z; J#define STACK_SIZE 100
; x, K2 P$ D- g5 u3 X% ~#define APPEND_SIZE 10
( ?: M1 z9 p# A+ }: u {$ u2 R; j) @
struct SNode{* d, V. s, q( N l: f, {
float data; /*存放操作数或者计算结果*/* P( a7 ?' q k* k" V! |
char ch; /*存放运算符*/
* ~+ y% z+ ^7 p0 i};; Q* P' W1 P* k0 M
2 w: `# c1 e* B3 R( @" Astruct Stack{, @, ^6 r, a U- w# ^" t
SNode *top;
* X4 u8 }/ q6 T. X SNode *base;
: ]* X. H6 d3 w. H4 v; q- x0 g% j$ O int size;
% R# |" ` W8 G! C};
. i4 w( b/ D" E9 K
9 h! g- I+ e% K5 c' I/*栈操作函数*/- Q6 O U" F+ T+ }* K: C# }! a
int InitStack(Stack &S); /*创建栈*/% a6 t3 g! I7 j7 ~# P
int DestroyStack(Stack &S); /*销毁栈*/
% l1 {- \- P# C( S7 Q) u tint ClearStack(Stack &S); /*清空栈*/2 @2 U& B: S7 Q. L3 t% g u6 |
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/0 w, H) p+ d+ @, Z$ j& r" j4 L
int Push(Stack &S,SNode e); /*将结点e压入栈*/
& u" g* D$ v; R: O' r1 fint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/1 l2 R" E7 d6 l2 N4 S7 q
y1 p4 b5 q( d% w" t
/*表达式计算器相关函数*/* S' N8 Q8 [) g1 p9 A, w
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
+ h; ^6 G9 o6 r+ X& gint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/ C! V' w1 T% ?' S1 \4 g
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/$ l) y9 h9 {5 e2 R7 ^
float compute(); /*表达式结算器主函数*/6 U. u+ X$ k% r) j$ s4 N
char *killzero(float result); /*去掉结果后面的0*/ & G# r- g* U3 L" n: \
2 u8 {/ w; X, S6 H. m0 ]1 _. a
int InitStack(Stack &S)+ N5 C/ f+ r; X, @- G g/ l
{6 s, f3 v/ Y k; }( c; N& _' }9 ^
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));& ]- I* d4 p& N: y7 z
if(S.base==NULL)
2 j" K9 o7 |$ @% m) G3 B {
( ?* c4 Y" D4 W) ~ printf("动态分配内存失败!");- _7 X8 M# M e( L9 f
return -1;( v. \5 ?7 f- A# U1 J3 q9 v
}" N4 S/ B% f7 H! S
S.top=S.base;0 X5 ~: O+ u7 R
S.size=STACK_SIZE;/ @, }3 \8 i2 r* \% w! d7 {
return 0;
1 `) d) ~3 ~ @! N: i x- Q}
" n* p/ Z2 ?( V( ^+ D/ d! A0 j# z) @
8 q" Z" |: B" O( J- B* `int DestroyStack(Stack &S)
) V# a2 N \: l9 `9 y{/ W. `; f6 J( Y* B! X' ~# D% `4 }
free(S.base);
5 [4 o% @& A: S7 v return 0;% O) W+ c' v+ T
}
' ~ j' k+ u2 T$ L2 e; ^3 V, K5 F/ w; B
int ClearStack(Stack &S)
$ ~3 J. A6 G- y! \4 i- \; U( ^{# |2 h s6 p$ q; I, X- _" k
S.top=S.base;4 G3 }, C+ Z6 N0 z' a0 a
return 0;5 _. U7 A# ^4 ^5 q6 C( k
}
" p* ?* C9 @ ]! @+ H7 p+ [/ U8 ~* p# t0 h" I
int GetTop(Stack S,SNode &e)
4 b' e, a) W$ r7 U/ Y( H+ B2 Z{( b( I) o e$ O5 R0 l& j
if(S.top==S.base)( ~9 \6 [0 a' a+ X
{
9 |. r+ H8 D( q" A( F' ? printf("栈以为空!");: @) M8 ?3 E5 f/ j
return -1;$ O4 A/ f: v' K/ S3 v: n5 f
}2 s8 N# M- O$ `/ Y5 x
e=*(S.top-1);% R" b- K) `4 {9 N) a5 z5 J
return 0;
( e3 l2 }7 y+ }% q3 ~8 k! |# Y}
( S1 y! _- ]! `2 P: ~2 F# ?$ l( w! A7 _, J7 G
int Push(Stack &S,SNode e)
+ @& u9 |3 _0 l( q8 R! u0 q{+ `( v5 e' U' C1 ^, m9 e; X
if(S.top-S.base>=S.size)
* P4 v5 }) d; D) o9 B {8 o0 d; p2 t8 I8 y" h* U5 C
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
6 ?5 Y3 n5 ^/ \( @ if(S.base==NULL)
5 L! N3 X# ^9 s% p. N" L6 ] {9 ^$ k: S- X: J9 \5 W9 u
printf("动态分配内存失败!");
$ \8 Y$ o. J; O4 h# R5 I8 x- ^0 b8 ~ return -1;
4 c4 q8 D" }5 i% j w ^ } r: K% P, r u( g$ O
S.top=S.base+S.size;" c" j% U, s, Q) g
S.size+=APPEND_SIZE;
# {7 l7 }# |' ~/ l$ w }6 q' G4 J* d$ f& v; I# K6 Q1 v
*S.top=e;- s# j6 j( S% P/ ]; Q: R( ]8 t
S.top++;
" o; p' ?$ P! e- M- \4 C return 0;
9 x2 M8 m g& S c" g}& h' l; Z# _. ~# r Z) _/ V
) h8 T, i$ P# A1 u; gint Pop(Stack &S,SNode &e)
L7 o4 C* A! v5 v7 ^! ]! q: R{0 k1 F( N! [8 n. B0 ~9 F& q
if(S.top==S.base)
/ }$ `% X( x0 e) n {- _4 W5 v8 J% r
printf("栈为空!");* u. s4 R* B6 h! ^
return -1;$ Q5 S. O. W" h/ ~0 e, n
}
$ G# t1 X. w9 b2 |2 ~ e=*(S.top-1);. X# b: Q% }' r: L3 Q
S.top--;8 ?! \8 f8 s9 d; w) J
return 0;9 l [5 ]8 H( b4 N
}& U* G' G( l3 m( }
1 U. e) Q% ^' Y, ?6 f
char get_precede(char s,char c), D5 A O2 f: M8 s. x& c( B$ N
{) ~$ e" D+ ^. m, t: [5 C
switch(s)& q. ^- ^ _3 Q* _
{ R) Z3 r, ^0 x1 w& i- X/ x' J
case '+':
# @8 W+ f5 P! o/ F, }$ q& A case '-':
3 q+ ]& r8 ~* w1 x$ \0 F! ^! e if(c=='+'||c=='-')
/ [ @9 A: M& c9 u! H u return '>';6 a) ?; ]' B3 [( p. U' k
else if(c=='*'||c=='/')
% P o8 ]5 C0 J* @* t return '<';
8 ?1 x) o% i9 G) c! z else if(c=='(')
# W3 C: Y0 O- x. h return '<';
6 B9 h- D$ z, D: D else if(c==')')
+ ^1 Q8 C' w; b9 Z- G U return '>';' m! ]. g6 l6 p/ N8 S) Q
else 3 F9 B9 Q( q6 l7 m
return '>';) E0 v# U+ q a; Y
case '*':2 \% n; }; R, V j u' G/ M
case '/':
7 C& K5 i! i9 ?+ K, v$ i if(c=='+'||c=='-')) ~, }7 D, [6 M. |2 \, z6 c
return '>';
x1 c" d( a$ w/ G4 S else if(c=='*'||c=='/')
: |/ V2 ^6 f* C% W2 l7 I/ w return '>';
% ^0 W/ c7 s0 o: U6 L2 e else if(c=='(')
9 D+ Q# u+ F( Z return '<';
: z: Z0 H* b& k- e6 n else if(c==')')
5 R" }/ ~4 ]8 r1 E/ m& J return '>';
# Y+ y5 {4 p8 g4 j0 V' | else( m, Y, L' M! x$ ?5 x
return '>';
4 z- z; T. J+ g+ w* w case '(':2 r( |8 D% s" ~ [7 O
if(c=='+'||c=='-')4 r/ Z/ F5 Z2 ~, c A* s& `2 \
return '<';
3 c/ N% d+ a% o4 t) w, g else if(c=='*'||c=='/')
; l3 v! B0 ^% K- _ return '<';+ S6 m2 o! N8 a7 ^* O
else if(c=='(')1 B$ k0 o: P7 Q
return '<';$ d/ A/ T7 X: s0 U0 G7 m
else if(c==')')6 ` q1 j6 [2 O/ K8 t
return '=';/ A9 I/ _* h) N5 O* I) C' ], C* M
else/ P! j, _9 W4 E8 Y
return 'E';# I) e( p0 @- A8 o
case ')':: F# O5 m/ D9 g# r7 S
if(c=='+'||c=='-')) U0 o3 Y! h% Z$ F( }
return '>';
4 G) {! z( _1 c9 j4 R' R8 c- M _ else if(c=='*'||c=='/')
7 d; }1 p0 d) \, u+ F4 Y return '>';5 @* f! }. ~* q/ `" B" X7 ?! w
else if(c=='(')
' |5 z0 t; u9 w& I9 O& T4 ^ return 'E';
9 x3 m( m! h) m+ ?8 M, u else if(c==')')
( H8 Q3 N( e! p% g: F8 W return '>';
8 |, `( I" p* q5 I6 F/ x else# s3 t) o/ N+ G& X
return '>';8 c2 M& ]/ v& ?6 w
case '#':
, g" d5 t- d4 Y) L: ~ u; V! c if(c=='+'||c=='-')
+ T, @% ?6 p0 ] return '<';
; |7 ~4 ^4 g" J else if(c=='*'||c=='/')8 m) ^1 F, O% y
return '<';
3 {% x; O) ` G8 A, \- a2 _) P' o else if(c=='(')! C* X5 N4 n2 W, a& L4 r
return '<';
! Y: a/ D& b4 O5 p; \% y% c else if(c==')')( G( g" M; Q7 ^5 [
return 'E';
. L; } E, P) O9 `. f C else
; `& e, O Z9 B) k0 U return '=';
, ?/ ^! i" T# s default:
- B+ f* l3 a/ u. I. L" \ break;1 J2 H% `9 q b2 ^
}
. R& g7 _: K0 Y3 X; V. c return 0; , z# g# D0 Y0 B6 f1 f6 Z+ O
}
, q6 N; \9 u. S3 {- k a6 {% f2 I5 J& j% K- d& D8 a- ~
int isOpr(char c)& o1 E5 f% i) T: Q# q$ E
{
& z/ K/ b2 Y+ A8 M if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
( f7 A- V- E6 f, w( G! g/ m! e return 0;
) R) \' r( { J. p else
4 T2 Y! i, D! N) | return 1;) w( ^( ~% S6 i( o* }
}% v% e" G3 m; ]- R3 P5 }: z& l
: R# q% f# ]7 ~, e8 u* @float operate(float x, char opr, float y)! n) b( t; s" L$ @
{
" e, ~+ ]: ~7 u5 y8 _( |# o float result;
# b$ H% X3 t/ O2 P switch (opr)5 r7 U9 D8 e j+ O, B. ^6 ~: I% L
{( R% X: S& Z1 I
case '+':
: q, g z, `* D/ Z' W, s* R. R; l! k result = x + y;
. U+ W" @2 J4 R h. D: C2 X break; ^% [ X. s/ h) i
case '-': 6 k1 t$ k& O. y3 O2 x, K+ E o" k$ t
result = x - y;, N7 M1 J; R7 @/ P+ J
break;
% E- T: l5 p3 M4 L3 ?+ @ case '*':
s" Q+ H: K& ~+ L+ h result = x * y;- I9 r5 o1 z5 D. }% W: p2 [
break;: \9 \% z5 c4 {/ j8 J- I$ k
case '/':
9 G2 O! G8 I* L( X8 w8 w if (y == 0)
( S; D8 c9 t+ }, {- d( y' I* B {
; }4 Z. z4 X P- E+ D$ i printf("Divided by zero!\n");
/ Z0 T9 L1 z3 W0 D: a0 l return 0;. G; t& |6 i5 ~4 X( t `3 ^' Z
}
& n/ [2 T8 [" o6 t ] else
, l3 a5 s3 |3 I+ D/ \4 x {
& ^! W; l! H( |) `' R result = x / y;5 L/ F4 _; f8 T! x6 Z
break;' ?8 R3 {& y2 z5 d* ?
}+ X7 X3 x! H' ~9 r; _/ T
default: 1 }+ [ _3 d5 |( _: L, A
printf("Bad Input.\n"); , G) E. _: c% u2 y& S$ B* y
return 0;7 c1 c6 H$ L b# d8 d3 ^# b
}
/ N- Z/ L' E2 D+ J3 r! q( S return result;
; d# K1 V Y' _1 n+ h* `9 w' z}
, x8 P( L }3 h2 Y# a
2 H# `* b4 ?4 {( Dfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/6 J2 L6 B; ~# C. o$ c
{$ p, C, H, O6 R2 e3 o) b
Stack optr,opnd;
8 O* j0 W7 k t8 `# _5 D! f struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;' W8 N6 R" Y" @
char c;0 a) F$ Q8 q" ?) I% U
char buf[16];0 T, c0 O; k& R6 F- g' Q9 h" o! D
int i=0;
3 Q) f. b1 {; h# W
& }" \( W) T$ y InitStack(optr); /*用于寄存运算符*/4 J, `$ N: u1 n; a
InitStack(opnd); /*用于寄存操作数和计算结果*/
1 y' m. ?9 K4 U+ X7 P9 c memset(buf,0,sizeof(buf));
+ A& t( {7 O: l; x1 q0 J 1 y, V. x" W4 c; p3 a/ s
printf("Enter your expression:");
) _5 D" Z: M. k6 [+ }7 j 7 Y+ q+ H7 P/ c" Y1 z
opr_in.ch='#';' q0 j5 d7 ^3 f$ Y9 L/ u. U
Push(optr,opr_in); /*'#'入栈*/9 w+ U- {/ t; A+ V4 p0 F
GetTop(optr,opr_top);
, S6 Y- n9 N# h" f$ _% }4 E c=getchar();* `) ~" X8 p; z2 O8 t7 ^
while(c!='='||opr_top.ch!='#')
% p' T r: l5 n5 H {4 B1 s2 H9 n; w5 A
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
1 ?1 ] g. I2 P* D* _$ } {
i0 m# O- r8 Q) g! e6 A$ S buf=c;' E' l& P/ r; A) V
i++;" H* e+ W9 B( Z+ ]
c=getchar();$ y! g. B% f" l, C0 `$ w
}6 u! \. h+ |- K* F5 ]
else /*是运算符*/7 y5 c; P* U7 c$ q
{$ S0 O" D! i9 Q) |# _" q
buf='\0';: I) B! Z9 ]& }" v5 J
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
, n: N @ A& P* s- W { u2 X1 \ F& I/ G
opn_in.data=(float)atof(buf);
& I' ?$ F/ k* f) F7 M Push(opnd,opn_in);
7 z- ^+ z2 V1 r: j+ a5 ^) C printf("opnd入栈:[%f]\n",opn_in.data);
# v6 ?& d1 q% s' ^% e i=0;7 d. j* \3 L, \7 n1 t
memset(buf,0,sizeof(buf));0 F$ ?# y( l3 C( S9 l3 a1 c2 P: S0 X
}
& B- P+ v# J1 e9 Q" y- W' E opr_in.ch=c;
: \4 e( l; ]" e+ t switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
0 ~* S# B& X6 p2 y4 p1 N9 Z {6 J$ w$ N4 s h
case '<': /*优先级小于栈顶结点,则运算符入栈*/3 ^: l5 I. ?; D) g, @4 D' h
Push(optr,opr_in);, J) v2 V- T) X4 t! y p
printf("optr入栈:[%c]\n",opr_in.ch);
0 d- c/ U# ~$ z3 f8 R c=getchar();
0 `* a3 ^1 S3 N# P break;: N9 h; c G _; [2 a
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/$ N4 F x$ H' H/ b) q$ ~; Z5 {( w( ]
Pop(optr,e);
8 C3 X3 B: d7 A" C4 u5 w printf("optr出栈:去掉括号\n");
. S1 k) o) Q) b& O2 u* p c=getchar();7 f9 p( X% a/ C. X# M
break;
$ {3 |8 s9 r& a" U case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
5 T" l8 h9 g0 ^( f Pop(optr,opr_t);5 t! H5 C/ K. \) \, F. `
printf("optr出栈:[%c]\n",opr_t.ch);
; e- b. O( U0 d3 Z# ~% w6 P7 j if(Pop(opnd,b)<0)/ o# F1 w) @8 K$ }" v& f
{
3 C1 u$ p2 j% ^: [ Z% e printf("Bad Input!\n");
. x( s }2 k B3 Q9 N8 X' [ fflush(stdin);
* E- R2 i; P" n$ K% ]! p/ R return -1;
- w* z# ?8 a4 Q7 [# m) J* } }, p. X' }6 D$ `8 j
printf("opnd出栈:[%f]\n",b.data);! h0 }/ h- K! c- g7 Q
if(Pop(opnd,a)<0)
3 T9 _ A& b- ^7 D {
6 P: p/ l0 R# ]1 l printf("Bad Input!\n");8 E: m) c1 b, P" a; p3 f( G6 u
fflush(stdin);5 N' S" w6 X' C
return -1;
0 `4 |4 G7 s1 D+ S, y7 u }% p& V3 @+ d3 F) Y6 C& A3 t3 ]
printf("opnd出栈:[%f]\n",a.data);
h+ y; a% Y) w3 x# E ? opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/) v% m" W/ T2 i/ \0 R' G
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
4 b* [: l6 Z! ^7 B$ R X printf("结果入栈:[%f]\n",opn_tmp.data);
* H# K8 _! ^: F5 K! E8 z break;3 K( `, j0 j; _2 p$ r
}
# g/ L* h! c- R% B }
9 V6 W0 z O3 b) w) p5 A0 z& j GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 8 R# J' H2 K1 `( B# _( w
}
# q$ R( F# {1 }5 |! U. } GetTop(opnd,opn_tmp);
: e$ n+ A; F9 u DestroyStack(optr);' Z5 W/ w% y7 d' w/ E7 }8 O
DestroyStack(opnd);1 ^9 G& x# N+ ?2 w6 L4 D+ p
return opn_tmp.data;
6 b- C/ `1 W, U}# A/ y* O+ t& f
8 v8 B& ~9 I' W) I) E! m
char *killzero(char *res,float result)
! ]0 q9 J e1 Q4 r! ]% }{7 [. N3 G& `. i. t
int i;; ~. R* l3 W% G
; X; N8 Y6 ]* G: `; z9 } sprintf(res,"%f",result);
. B( B9 H: b( p+ N/ V9 ^ i=(int)strlen(res)-1;
/ v% q6 x. g: p' W8 M( h$ z% P l while(i&&res=='0')
% G: W# @9 A2 q. L# ] {3 P6 X9 a9 j% H8 Y: k
res='\0';
$ H$ O! u U, u" u* i i--;
3 a# C; s5 d3 @0 o$ M' n }
( b% x; E. G3 C9 h3 n# m9 r/ y. D if(res=='.')% j/ m$ _! i% A
res='\0';3 M9 q1 o; u: X6 [. }+ M) M
return res;
2 J* X# Q- }, d7 p! h7 P}
1 F" M* a) D, @ U
$ }3 l4 l* E- S4 W' ^6 k! R7 }" Eint main()7 q' H! i0 M, H0 r2 w
{# g- C& P- f6 N5 G; _) }7 x- S
char ch;
( q" }5 w/ H F& w0 N! N+ [ char res[64];
# i- ]) h* d8 q4 g0 z2 I& L' Y, ?$ v8 d float result;
! [7 N6 W) A b/ k. b while(1)
) ]" O5 S; x% r. c8 \8 ~5 h {' K3 G. p; U$ M9 F# a/ `: P
result=compute();9 l8 o) k, A) m, F* |
printf("\nThe result is:%s\n",killzero(res,result));
! u9 s/ ?# A! v3 ~9 ]% G- O printf("Do you want to continue(y/n)?:") ;
$ w' l: u0 o" A ch=getch();/ ]7 ~/ ^* C% [' Q) V$ d; l
putchar(ch);
- C% i0 }) l6 [7 s4 v ^ if(ch=='n'||ch=='N')
; g6 R$ |; `- {7 ?* N* Q break;
9 e- `& M* R/ N% k) G4 V9 t else; b# I: R( P0 {$ ?
system("cls");
4 q, }; V# [6 y, A7 Y8 ^6 L" Y }
) z& M; ~) I2 w* z9 q$ A( q2 L return 0;
, s! |2 {& P/ j) @- z2 a}
& Y7 j8 w) ]0 i3 @" C7 i2 k% m. t& f) F# T: h% |4 w0 m
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|