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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.; V- m. H( j9 g2 A( w
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=. M' ?7 a9 w0 z' b: O) z9 t
/**************表达式计算器************/. h! s/ F; X+ @8 f/ e0 D$ T1 g
#include <stdio.h>
3 w% P2 Z4 ~4 k& S4 s#include <stdlib.h>
?$ k1 a0 x$ ]& p7 o" L! k#include <string.h>& f) J7 W! Q/ d0 @( z
#include <conio.h>
8 M) ?2 {; s5 s( i, ?2 X4 j#include <malloc.h>
( c' J: M9 I: ~) _) l6 i+ y" A6 b7 X8 `& c; S% h; j
#define STACK_SIZE 100" i0 i2 d9 |* }. \) A5 M
#define APPEND_SIZE 10( V q; R% W& g8 K2 t% X
# Z7 _( [$ W" s/ h* P" s! xstruct SNode{1 K" Y" t9 y- \# J, J
float data; /*存放操作数或者计算结果*/
( t0 \/ S/ y! K7 _; t char ch; /*存放运算符*// g1 v, @# X1 v" I: U
};
- s# L1 z3 A2 F7 \2 t$ i1 ]3 V: M. N, o+ Y0 k
struct Stack{
$ ~# L" X ^6 g- I# m SNode *top;- a4 E% x ?4 C$ {# ~* V9 W
SNode *base;
1 {1 p8 t# |5 W2 j+ c/ u. S int size;7 {7 [9 j Q8 s P1 G6 ]
};
) N9 K/ \& f _/ u( A# `$ \
/ Q7 Y7 }, N4 S* ^0 c* L/*栈操作函数*/
O# q, n; {% x! v* ]5 k# mint InitStack(Stack &S); /*创建栈*/. X4 A8 O: Y+ D, z) F
int DestroyStack(Stack &S); /*销毁栈*/
! f) X; x% N" p7 oint ClearStack(Stack &S); /*清空栈*/7 k+ `- t( X' J4 k% b" T
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/2 w% K) p; R/ W; f# |& O
int Push(Stack &S,SNode e); /*将结点e压入栈*/
- w2 s& l6 }5 r# W* Yint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
) O# c! G& ], h
6 I n3 S' a- {. \1 o+ h5 G/*表达式计算器相关函数*/
7 q+ d% z, |) v2 e- c# _char get_precede(char s,char c); /*判断运算符s和c的优先级*/9 b1 [: L+ f8 n$ q% ^ n1 K
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
; I. s* Y/ h! ]float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/: Z: ]" @- O( ?6 V% Z
float compute(); /*表达式结算器主函数*/
5 i E ?* Q* G7 m+ V2 r( _char *killzero(float result); /*去掉结果后面的0*/
* U+ ?' |6 S! F2 m* a
9 k" e- S( r, {$ P5 x- mint InitStack(Stack &S). s! j) X! P. ?0 a
{
0 s+ s7 M/ ~; g. H! Q# V4 [/ u S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
) [7 l) B& s. G* f6 ] if(S.base==NULL)
& X# S( {3 ?0 z {
' Z, ?5 h- \7 S, x+ g printf("动态分配内存失败!");, k# h: n' ?& W, \4 l9 R! R4 u( O
return -1;
5 l% s9 Q& d1 L% x, r' c, Z/ p; A }6 W. v' z3 D! O4 O( V; a! H5 }2 l+ t
S.top=S.base;
. h/ g0 y) Q& u3 g% K( y S.size=STACK_SIZE;0 F/ f( t9 f5 H1 ^! I: w
return 0;' I$ ?- q' L* p# h
}
! A& D. p# F' ~+ D0 f& @6 l5 j" ~- q6 u+ O: D# C4 h2 h( f
int DestroyStack(Stack &S)
/ C' @$ l& S$ _4 n* e6 k{7 [' E6 e4 v# M
free(S.base);
6 h1 z) K' X# X& u return 0;
% ^. [) n6 G, m0 G}6 O% E5 B5 I* `; v
7 n" I9 y- R4 [& Zint ClearStack(Stack &S)( P5 T9 ?1 m3 W( p) p
{3 J2 d) t5 O' K& _, B6 I
S.top=S.base;
% _; D$ U/ f2 d# B/ K0 g return 0;$ q, v9 h6 ?8 _9 O( z' V( y# ]
}
" f! y5 q' T9 a# e
6 H) m7 K2 G- oint GetTop(Stack S,SNode &e)
' z% _: x# d6 o" a{3 ^3 q9 d/ {4 ?8 A
if(S.top==S.base)3 g4 H' ?1 u0 ~ h8 C! i
{6 A$ a8 S0 t3 j4 k5 d, I8 X
printf("栈以为空!");1 e6 |6 U6 ?* E4 g
return -1;
5 U6 n& ^0 y! ^* @ }2 G( ^2 W" r/ b% X Q
e=*(S.top-1);
0 g' B* Z% n$ @7 {4 ?" J1 v' M( I return 0;/ U: R1 ?% f4 M- U K
}
7 M: l! x. \8 N# _5 i1 Z7 {' T; v1 Z$ }2 `7 c* [
int Push(Stack &S,SNode e)
$ J. c1 J. r$ t# b# v8 s7 ?{: r6 k& p2 O. _7 `* A H) u1 D
if(S.top-S.base>=S.size)6 q6 q0 p7 z; [& l8 B* |: @* y
{
+ P( J2 ]5 z0 k1 f9 t! z# U S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));/ L/ P7 B1 q: D% w+ u
if(S.base==NULL), D( j/ \+ v6 g
{$ c' E' u8 f& u7 n
printf("动态分配内存失败!");2 P1 S$ Q* X, M+ J' g1 N2 P& v
return -1;: L4 W& X4 S9 I0 w0 |- U& f. J
}
0 M8 J4 V% `/ m5 T+ _, d& T/ N S.top=S.base+S.size;
! Q% t5 a' E6 |3 q r S.size+=APPEND_SIZE;+ o8 D3 k P. i) v
}
+ U. z" ] [- A8 T& v" L *S.top=e;
! s2 C8 b8 q2 ~9 a" l* e S.top++;
* O: w( ~# s% j: \ return 0;: V0 h1 x# S" F5 |- `
}# M. u2 A1 M! r# i+ C1 O
5 O0 E) Q4 s! x1 ^9 ~
int Pop(Stack &S,SNode &e)
( i" S+ }* ~ a" O- L0 K' F{% ^, N& S* ^' `6 y3 }& O% b
if(S.top==S.base)! t$ h+ i- H! ]8 s7 D7 {+ P- R# _
{) X0 I9 @' M& O1 v* p3 ]
printf("栈为空!");: O" e% N: ^- s! l" Q8 N
return -1;7 F+ m; a2 k& q; t# A6 C
}$ m a4 ^( B( ~: Q
e=*(S.top-1);
8 ~0 M1 ^ `' h( T0 I. C: z S.top--;
2 Z& D9 _1 C9 L; d return 0;6 I5 U7 `2 U7 b# ?% y" l( L$ z
}3 s4 I' Q N" h8 k
# k. X$ p, f% i( `5 I+ Ichar get_precede(char s,char c)
, R5 G: L% E' }, o4 x& c* A{& h* L* D2 F1 V, K2 ^+ G
switch(s)
% {& [" A8 ^7 \3 f {
& F6 R/ L; B0 o8 [ case '+':
8 X7 a+ f: z& v8 h' A. T1 H case '-':6 q3 l0 }9 \& t! R% p8 j3 h. A, S
if(c=='+'||c=='-')
( Y" F& D( C* |% X5 n return '>';9 {6 l4 K" |, ]( B" B# C
else if(c=='*'||c=='/')- ^: S3 N$ v% \5 W
return '<';- ^6 L6 L6 ?. B- C, ]+ g, a
else if(c=='(')0 } v* \- H. ?4 P, O
return '<';
[' ]- e/ m& O+ ]$ X/ |, y else if(c==')')
2 S/ H) R8 |: A' E return '>';
' F; k( W& ]0 L! T5 x3 c else
+ @; M" U) r p3 V; f return '>';
, E: j( |; F3 s4 H& b, _& n case '*':7 u) j( x3 G. g$ v ~ ~
case '/':# O1 r# `' }# @5 j& y$ o
if(c=='+'||c=='-')- k# ^* t5 Y. g
return '>';5 y3 l( d1 ]2 R1 P% l ?7 M' `
else if(c=='*'||c=='/')
# M1 z1 x; k. Y return '>';$ p9 Q$ z" s4 f, F, k
else if(c=='(')
) S/ n6 w8 [5 d8 }# O! c; y return '<';
3 \" K8 y, y: F; c else if(c==')')
7 q7 }- J4 O8 Z/ d0 C return '>';3 P- O; b! W+ v2 e7 h
else
% H' v9 q. K7 w% S8 ?& b return '>';
Q& l2 r( C( e1 _) } case '(':) N( Q( x: o2 v; N
if(c=='+'||c=='-')# N) w3 u2 ]8 z! `+ G
return '<';9 O1 ] H1 @: Y6 W& c( D
else if(c=='*'||c=='/')' I; S" R3 ]. {- P
return '<';/ r: | [4 g' G4 a3 n1 C1 G
else if(c=='(')* d: J0 _) f: p* e
return '<';# @" g; z7 G- n1 |2 d( `8 Z
else if(c==')')
) b( j" H1 j" ^ return '=';) E' c: _7 S; c: u/ f" u
else9 j& f, c" `, z6 a1 f3 \
return 'E';
6 @1 Y: B) m( B$ ]" [ case ')':
; ~" g! a0 _- g$ A5 W& w2 `4 z if(c=='+'||c=='-')2 Q) C- Q4 g8 b3 E9 [
return '>';5 a- V' W& M4 a/ s) B
else if(c=='*'||c=='/')
/ Q, v- ]# X6 L return '>';: W+ s! V$ @, @; K4 x
else if(c=='(')6 c5 f/ ~+ C% n
return 'E';, x B6 l2 e# v$ j) Z' `
else if(c==')')& }; S! L, G% u5 j% }/ {
return '>';
! \$ O. n/ E! E$ F else) o$ c/ y7 n' b$ m1 o
return '>';) o; H" G6 _: x, T4 ]: y
case '#':
1 R$ y" i7 r% s if(c=='+'||c=='-')
' m8 j% V6 Y: g, t7 T& {; W return '<';
6 z$ m; r o' b& I6 A& X else if(c=='*'||c=='/')
6 ~2 w2 I- E( c' d/ ^1 J( J5 }- W return '<';7 d3 }3 z- R8 i9 Y3 \: `; l) ~) H
else if(c=='(') Z5 Q1 l+ v* H' r# f1 Z
return '<';* k4 e, U" Q- ]0 w( W+ W
else if(c==')')! Y4 h7 o8 O% _# R* t8 \% c. T4 x
return 'E';8 n% l+ X, N% o9 M7 u
else
7 {' L t% \# f% ]5 t. G f: i: z return '=';4 u+ ~, p1 O: {% P: R. U
default:, y* h7 P& D, C/ j' z( U
break;4 v- z, t' o: O6 ^0 \' R1 m. r
}+ }) a/ {0 e; ~5 s+ w7 a. e: m
return 0;
; @) T S5 a+ a6 K5 V}
1 p8 u3 G$ i0 [- U
5 W8 m$ S9 `, qint isOpr(char c); j$ F, d5 ^' K/ s% Q" a$ f/ F6 k
{% o' Q4 r/ Y7 k4 o3 x4 }1 u
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
s o$ t3 q" ~) z( f return 0;( w+ Y+ v" p8 h1 p% k8 @' L6 C5 ?/ c
else
, P- o+ l2 ^; Z e9 P return 1;
; c" O1 L( z* E) s0 m}
; o/ d2 T' g: ?# G0 K# e, V. m( R6 O; L" @$ j$ ~* a9 d/ t% e
float operate(float x, char opr, float y)
6 D/ a7 ?+ h3 N) M4 n. f" I) u{ K& Z9 U1 L& Z9 h! B
float result;
1 U5 M7 R. I: l& G( S* _# ? switch (opr)
8 P9 M5 V. q; R. [ {) L+ M# G6 D" n4 d
case '+':
; t4 n" F, J( `4 _& F$ v result = x + y;
( F3 N6 @2 ?: K break;
% U3 R- M* z5 a( n; S9 f case '-':
* v8 {! B: s% Z( c8 z) [" \ result = x - y;
8 F- t4 T4 j: H9 A0 d7 p9 L# {- ?2 F break;
7 i, Z5 W3 k5 @0 w* G. C case '*':
# R$ j H+ r y; M4 h: r7 I result = x * y;
. |4 \0 v) j: ` G( \' B- K break;
' I6 D- ^; p; T) L z+ O5 q! N4 C case '/':
# E( X x9 ?8 Z5 @0 b& v if (y == 0)7 e: g( K. y, K" R! o% _' s% e
{: P" ~' n" c/ e) ]; j9 e: L' x
printf("Divided by zero!\n");/ V) q5 `2 K% C
return 0;4 ` Z! w: ~# L8 }4 {' h6 d
}" w3 u) e7 p4 d
else! O Z; c- i2 n- U" l, H9 _' ^+ y6 o
{
* ^, N0 m6 {" U7 E' K, C result = x / y;
% J8 T) N9 y, Z7 s, \8 y break;
$ L4 y& L+ W' H/ a6 o& _ }
0 V% K* h$ f+ d3 o+ x) r default: ; J K" V% ?) |
printf("Bad Input.\n");
7 F- x% A# ]# w9 d( j2 l/ b return 0;7 @, _ \1 V" c+ Q) d* I- I" a+ {. q
}
( `% @* I# d* i; x/ f8 U3 g return result;
! I$ a/ a7 n2 O" H}
5 R4 T' S' }7 W
" _: [1 N, H4 U* i' Y$ Qfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
2 B4 L& c$ E+ F{3 T. y( [9 }! W8 ]2 I/ Z5 N
Stack optr,opnd;
6 {, y& p0 ~/ }+ ] ~" b struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;+ W# \4 C9 t- q6 c8 E- d
char c;
( y6 H* \& g& e' v. [ char buf[16];& j. ]& z7 C$ I) \+ c
int i=0;
. D9 Q( Z9 d/ P2 @* d" k 9 h; k! m, J" ~1 C- P" y
InitStack(optr); /*用于寄存运算符*/
4 U5 h i c& @1 C: [- l InitStack(opnd); /*用于寄存操作数和计算结果*/
. H( I. P$ C$ Y' o! n& ?$ e memset(buf,0,sizeof(buf));
9 ]0 R. b! `6 v( H$ ]9 J; l! ^ 0 c3 n% a6 x7 q# H E! |1 Z0 A9 N
printf("Enter your expression:");* u) {1 V# D0 m* n+ e. x! d
; `; z5 I7 Y- I% N3 Z: X" l& L opr_in.ch='#';
, V0 Y, X- ]( e; T2 D Push(optr,opr_in); /*'#'入栈*/( R+ d; _2 k. U9 _5 ]4 g! [6 I8 k) y! X% R
GetTop(optr,opr_top);+ C9 X6 h9 c2 ~' [2 [6 v' y) E
c=getchar();
" [! z* \ f+ f. M; \6 C2 b while(c!='='||opr_top.ch!='#')
$ I# l! g& u; `0 Q- t$ i {; y: G3 [2 I/ h, Q; W
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
5 e9 q3 @0 Z$ Q: w# {4 n {! o" z# A/ c( L. f
buf=c;
6 {# B: M" g8 K& [" s W% w) O, S$ Z i++;
: [( q D" l$ _) u, J9 X: ~ c=getchar();
9 l5 Z; w/ M9 X/ P4 [3 R }
% M: R, ]4 V4 E else /*是运算符*/7 R7 i a. C/ D" g
{
/ y8 E1 N# W! k' C5 G8 F buf='\0';
1 l+ p2 O) e+ [- }( H if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/0 c8 w' [7 n, m2 ?# B
{4 ?5 i4 o2 `; @8 n+ Y8 s
opn_in.data=(float)atof(buf); v+ Y- I9 I/ o0 q# T; o0 k
Push(opnd,opn_in);
; }9 h. ?$ W+ q! x- J printf("opnd入栈:[%f]\n",opn_in.data);
# g9 j$ u8 ~ e i=0;
% H: f- a7 T+ f4 x memset(buf,0,sizeof(buf));
0 a7 u1 j( r: P* |$ M }
6 w# W; P8 }8 x' |6 K1 Y0 I opr_in.ch=c;
8 X4 _2 z/ N& |5 G @7 z+ c switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/4 b/ C9 M" O; T9 y
{; \# K4 _/ e2 c k7 ^( X) M
case '<': /*优先级小于栈顶结点,则运算符入栈*/4 K2 o0 P. ~* M4 \: y P4 B
Push(optr,opr_in);: y- G* H' }& t: }& K1 o
printf("optr入栈:[%c]\n",opr_in.ch);
6 @3 e3 e& O7 J% Q% S" s0 _; N& H c=getchar();
4 O( h) l% S2 C( w, Z. g# [ break;
0 I1 H, Q) ?# ^% e* [4 l% Q case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
' J" `0 p1 b3 H* M- V: o4 ?# M Pop(optr,e);
' ?: F8 A _$ P* [ printf("optr出栈:去掉括号\n");
$ ?1 X/ O, H! q9 h) U% ~( | c=getchar();
9 m# I% Q! c& X9 j% z$ \- ^ break;
& f0 U8 P% q+ ]# l1 g case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/) r1 h0 N7 Q+ m
Pop(optr,opr_t);
+ n2 `' _( x4 w6 {" G) {( N printf("optr出栈:[%c]\n",opr_t.ch);/ S/ k' R6 \3 Y
if(Pop(opnd,b)<0)1 Q/ l8 w4 P" ?( e
{
* B) q# R' D ?3 F( h: ? printf("Bad Input!\n");
% u7 t' F# Q1 g) \$ ^* Q1 q w$ p fflush(stdin);
8 M& R( ]: }3 v! F: g return -1;" }, z# {' f% H
}+ d. M/ [2 w- l3 c0 ^' c6 F
printf("opnd出栈:[%f]\n",b.data);: f$ S$ V( n! ` b
if(Pop(opnd,a)<0)
7 p& o v1 ?' Y0 E! S* W( B {) T0 R" x" g6 F7 ]0 j& A: N+ V
printf("Bad Input!\n");
- G, U; m8 j' v3 ? fflush(stdin);
, Z4 J: u0 w: ^9 j, e3 [# l: ^ return -1;
E. F/ {+ N% w) ~ }/ \; H6 N/ ?; q1 u+ e' O
printf("opnd出栈:[%f]\n",a.data);5 |" _% G' _+ e3 E
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/, }$ f7 J$ z8 a" Q' j6 c; L
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/- X8 u+ @- G! s4 l
printf("结果入栈:[%f]\n",opn_tmp.data);; n# c* |7 T- B) X% n9 Q: x" e0 B$ A, p
break;5 N9 l* G7 j; Y J5 W
}* g M; C( U* O! s
}9 l' U9 y* h4 S8 I
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
8 U9 x( a8 H; _! Q& {- J }% p g& d$ w q5 S
GetTop(opnd,opn_tmp);7 v0 V* O" e+ C3 e3 |- x
DestroyStack(optr);
. n8 @3 n+ f: @' S3 l4 v7 [/ ` DestroyStack(opnd);5 G8 r/ T8 G- G: i N& R5 y
return opn_tmp.data;
: G: O7 K! _* h* g. w) G}
* S1 y0 W9 @/ f2 ^- t' b# V; T# A. b" `3 f9 |- k
char *killzero(char *res,float result)
. W) U6 a3 O- ~8 p" k) s0 o" y{
5 `: B- i0 Z5 B7 a1 h int i;, J8 n6 I4 V: Z* t+ n
2 L5 [ p) U* D" _$ m sprintf(res,"%f",result);% S; ~0 n+ X' |; I& G) z1 e
i=(int)strlen(res)-1;
- |- E3 c4 o" o' u }8 q7 N" k while(i&&res=='0')
' l" I3 ]* f) K# r% j {6 q, V; {9 u+ r C% F3 Z3 T7 E
res='\0';7 d3 N' F# @; h$ \$ m: U
i--;/ h1 d$ ]9 s. F: S2 l" Z9 Z
}
2 L5 c, h# ^3 M$ ^# e if(res=='.')
0 b* n& h* T0 D, h8 P# i r res='\0';
8 W, a! f/ S* ~+ [6 L return res;- e4 M* @ m' j* c- b
}
! A9 \% T. V& a: p, f4 U
?) y) e6 `5 iint main()
" G) ]0 Y' U' q, N! E{$ w: f& s: k, O- n
char ch;' _$ m! p& J( ?: h ?
char res[64];' r2 i. O% w3 l8 ]3 v2 O% K l) Y! i
float result;* M- O. d7 w: }" k' v$ S# ]
while(1)
& ], T7 b: X$ C+ x* l {1 N9 J/ n4 u) M, ^' r( N
result=compute();* `6 m8 \; f' p! |/ [) m
printf("\nThe result is:%s\n",killzero(res,result));
# |4 E. O9 V' q2 ?( D& m printf("Do you want to continue(y/n)?:") ;
3 P/ i1 P* i7 q* u; y' z9 T7 g! r ch=getch();0 s- a& c2 a: r5 q( A2 Q
putchar(ch);0 w* t) e" w! I3 D- _, s9 [% \
if(ch=='n'||ch=='N')
" R! G9 ^2 W7 a break;
: T, W6 W& U" u; C! S9 ?4 X else
2 v7 C- n: {- z0 f5 D% Z6 Q% d5 ~ system("cls");
9 F- H1 I5 N2 O7 a! P( Q; i }
- k' g7 {8 H8 r9 D9 ]/ k return 0;
& }* L; ?0 M3 ^7 |* l Q. G}
9 i. w4 W5 C7 G) D7 K* t/ q4 p4 s5 I/ ]/ L2 @: A
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|