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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
9 f9 G7 Q8 o: z& y) Q% h程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
1 s1 J6 j, A( b9 w/**************表达式计算器************/
! P+ \( ?2 s( u2 k. l/ t. b# G8 t8 _#include <stdio.h>" c. t9 F- `$ k f9 T$ z
#include <stdlib.h>- X8 E/ K9 `" P/ I
#include <string.h>
! Q0 V( w9 G8 R0 d" G#include <conio.h>
+ w( y0 x: `, u# g* U4 t#include <malloc.h>9 M$ a! c% ]9 Y2 {( z: Z. X2 v- F
% N, v5 ?; D: S. D( y( V% K
#define STACK_SIZE 100
' _' u6 o) ?9 G! [ t#define APPEND_SIZE 104 j) @% d: W( _1 }& n; b
. w! B L+ K, I+ Qstruct SNode{
3 y6 Y1 u# l; ]8 m, H# U3 L; N float data; /*存放操作数或者计算结果*/9 L8 T9 }9 v% v
char ch; /*存放运算符*/$ [+ |. L" w/ s& A
};/ H/ y) B+ t9 `/ l" v3 g
: j; _4 y% ]7 `" ostruct Stack{: I; V" H$ Z9 Z$ s9 {
SNode *top;; ~1 M- e$ V) K( n( O: P* i
SNode *base;
2 w" b$ i! ` C% x+ o$ c int size;
' V* R6 k) }9 C. D/ z: N6 q};
4 j$ |$ _+ _+ \1 L1 x! c$ W/ _/ X: p7 _. S
/*栈操作函数*/
% I. g$ E# b( h1 }& Q' wint InitStack(Stack &S); /*创建栈*/
& O" p9 |5 o8 z) l9 s6 \8 W7 Fint DestroyStack(Stack &S); /*销毁栈*/7 y, N2 t5 _. E! X4 ]. P
int ClearStack(Stack &S); /*清空栈*// n$ R% g4 _$ \
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/& e ]# `$ Z0 b, e
int Push(Stack &S,SNode e); /*将结点e压入栈*/5 O! ~# c% G* f1 Q9 N9 F" v0 K8 A
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
# P- A0 ~: h: i( [6 g9 k' E6 J$ F1 [" U. c6 m% k5 U
/*表达式计算器相关函数*/
/ f8 O" T; a9 ]8 O4 S" Q tchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
" u) ~& _% O4 \" n3 Cint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
2 a" O& _% D3 W3 n a- sfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/( S, ^3 h& w1 R$ }7 i' q
float compute(); /*表达式结算器主函数*/) A! v9 q" l$ Z5 h ?
char *killzero(float result); /*去掉结果后面的0*/
; a4 O) u3 n8 O2 a
Z; R0 X* b) }. e2 J% g+ uint InitStack(Stack &S)- N7 i5 J: }* l- a+ I$ D8 z
{
0 w8 W+ y% J' @3 q; I# a+ a% @ S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
/ i4 D) N) z1 O3 l if(S.base==NULL)
+ v1 q% I( G; \/ z3 A k: p {- i4 j* E9 O' i. t) [
printf("动态分配内存失败!");
& f$ u6 v# F+ O, g return -1;, O/ W& p. ?- ^# F8 s
}- x5 q* P4 \9 a |/ x6 D
S.top=S.base;2 n$ f7 r: y$ X; b7 P/ w9 l) F7 e
S.size=STACK_SIZE;6 W& J! V: o* H8 V$ y4 V; E
return 0;) J" e6 F5 n/ ], q& I: u
}
/ x: d( }- }" P. Q( L+ S# u& T) c( ~1 }/ ?1 a2 p7 z
int DestroyStack(Stack &S)
6 d/ L1 j( Q7 N; j" ~1 [; z{
1 {( i( w$ X4 w: z( L free(S.base);) ~( s5 B" k, f- C1 R% g/ h
return 0;6 R/ E* ?0 H8 g* U; Q. z
}4 p) E# S1 I1 z7 T+ ^5 M- I6 d& t
* l6 @4 r0 V9 _int ClearStack(Stack &S)' ?* H2 l3 P) X- p+ c
{0 s3 ~8 {' U# H& _! V6 @
S.top=S.base;
' c; ?: f9 h4 i) X+ i8 h* P/ k9 y: y return 0;5 f8 d- h0 Y" r$ |- D$ }( w
}
; ?* I$ c1 ]* k4 B4 O! t- D: f" S9 ?" w4 d- R8 z
int GetTop(Stack S,SNode &e)
& G; a1 R0 ~) [5 K7 W7 e{" r A2 a+ D) t/ x4 {% Y
if(S.top==S.base)
' R: m9 h7 q- L7 a [ {7 s3 l1 j0 l& v# W( V2 n# I
printf("栈以为空!");4 J! f( b2 g" Q0 r
return -1;- Y [# W" D+ x R/ W' H
}
7 ]) D+ |. A8 i8 F5 G/ A& b e=*(S.top-1);, Z9 W- q: U! j+ O/ w
return 0;
4 b# E% f# u% f2 O/ S}: A4 \" s( [9 `* |! H
; z" N" C: Q& f8 Nint Push(Stack &S,SNode e)3 @$ }2 d) `) k
{
& q. Q4 P, S( x/ n' S$ N/ l if(S.top-S.base>=S.size)/ q2 v" q1 v3 l! k4 H
{3 ]3 o3 U0 }4 o. ]4 c: I
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
/ x, m) h! ]6 X1 ?" ^2 H7 V if(S.base==NULL)! ]( i1 f6 ?6 M2 d& U8 {
{
1 x! W- K! r# m4 T: M5 G/ P4 p( x printf("动态分配内存失败!");
' L2 w8 h0 O' w5 { return -1;# {8 C- v$ E" Y9 {: i% m; S
}
; r( w8 D5 E" ?: j S.top=S.base+S.size;# t n( P- x5 _4 X. s+ ]/ A
S.size+=APPEND_SIZE;# |- ?& h: Z3 A
}
( V0 Z: |/ F" |7 P *S.top=e;
2 _9 |% @8 L. I9 O1 Q) l2 `' } S.top++;& m3 F, ~. n' \9 p
return 0;6 z- I# I+ Q, r2 q6 c/ K3 Z
}
6 j* L p5 h W1 T! B5 M U: e& S. y
int Pop(Stack &S,SNode &e)
, O3 o" }3 F% N0 H2 O{9 P% d( \! E4 H
if(S.top==S.base)' O! f6 N4 ^# L# w/ u! A: [
{+ b9 p8 z. Q; `# i
printf("栈为空!");
9 f0 i% B" h. r& F* [& P8 w return -1;! _' b/ R7 x5 Q; W _
}3 `/ W2 F$ l+ R0 x* o
e=*(S.top-1);
4 X+ F- e* t5 _* @/ f S.top--;! Q) j2 C% X7 k2 u) P
return 0;
5 ?5 M1 W6 I6 s0 A6 i% ]9 F}4 f7 ~; Y2 S9 A1 F- z, @- R
8 j: V, G( o0 f- Q* ichar get_precede(char s,char c)( q* c. T9 z; b4 C; H
{( S# N1 ^2 {# O
switch(s)# Z4 E$ Q! v y. A' }5 H/ N# a0 Z! O
{
( L4 N+ A% `5 u case '+': * i$ F; I2 S& }' e
case '-':
4 Y. z# f. U% `! u1 u, A T if(c=='+'||c=='-') ?( Z" P% {5 K H
return '>';
0 t* v. q, \/ a7 p/ \ else if(c=='*'||c=='/')( X, h' ^& }7 q" p* G c
return '<';
2 T7 |# G7 o' T! [7 G$ I6 | else if(c=='(')7 \; @4 s1 O( M( m: D
return '<';
/ |0 p$ t" N6 U1 M1 m4 ~. P0 S# l else if(c==')')
' f" {5 \& V- E5 h return '>';
% _, J* D, ~ q else ' o4 K# S$ N4 C: J
return '>';
! H2 n2 ?2 V6 D& [ case '*':$ S W* k# B2 g" ?
case '/':
* k' v1 O6 L! u5 t$ k5 m* h: ~0 | if(c=='+'||c=='-')8 X- Q: w2 h) q7 s2 q. |
return '>';
( ]- k8 d+ _0 O' x4 U; h else if(c=='*'||c=='/')$ d+ ~. C6 U; e9 P
return '>';; w; G, ?$ M/ P4 X; t& N! w. m
else if(c=='(')0 \) w& T* m2 Z6 W
return '<';4 y- Q1 @1 w( U: Q1 M4 D o
else if(c==')')
2 U$ ]9 }4 f1 ?1 c* U return '>';4 `0 a% ^5 q7 F3 @5 Z
else
- [% Q! j" g8 M- d return '>';
( T/ i8 l5 A6 J8 s" i0 o& @7 O, p case '(':
. R! W R3 d$ M0 U4 b if(c=='+'||c=='-'). \5 t9 O" ]2 v% j( o: g
return '<';! k% \. L5 m5 M7 N% Z' L
else if(c=='*'||c=='/')0 T+ \ t3 {+ {
return '<';" F5 ]8 i7 N4 t5 z6 n! |) k
else if(c=='(')
5 l# |; Y, G8 q: Q return '<';: j5 F% Y; K4 `, e3 q$ t) A
else if(c==')')
; j( m) d) w* _1 a' X return '=';; \" X8 |/ C2 k# P7 F; u2 J1 {
else, a& I9 p0 W, Y, m' B
return 'E';
+ Z# I4 I0 \5 I# W/ J case ')':- ^' G, V8 y/ |6 a$ {
if(c=='+'||c=='-')9 O% L4 M: _0 z6 O# y
return '>';9 m% ?) [3 {- ]
else if(c=='*'||c=='/')5 W/ C' N5 o! Q' X
return '>';) e* Y+ i3 o) z
else if(c=='(')
* D# s: J( w* H& m( E return 'E';
6 V5 ^' W7 ^- d! k2 _, Y' o else if(c==')')2 R6 w# s4 ]# i8 W
return '>';
! V/ H% H# X" @1 e7 j else! I" Y+ U4 A: L, }
return '>';
5 @& w- z' ~7 g" u. X+ v# `& { case '#':$ L h5 k' ^" X1 e* E8 P" n& {
if(c=='+'||c=='-')
: L3 u0 _: L- ]- P return '<';
X( j5 K. L( v5 w$ x: q& X else if(c=='*'||c=='/')) o f# u/ z5 e
return '<';" a. K, r3 T1 E. ?
else if(c=='(')% i& ]0 ]3 D4 V% _
return '<';
3 X+ Y9 ^/ v$ o. _/ p r$ z. x else if(c==')')
, Y* I9 C+ ~+ {0 a5 o, Z* _0 y% t return 'E';
- E- n: u7 D. ^7 U& E& X else
" Y7 m |, a) ]" c return '=';
! {# _. G# Q; o: i/ y; A default:
: _6 P" V* j9 X break;+ V2 x! `: R( G1 y) W# T
}5 e# n) D. \4 M. {
return 0;
+ m% s8 v% b, e' Y9 X: ?& U, r}
8 U5 [+ U, k7 p3 \) g/ i. ^
5 Y. z' M4 R t# ~6 r" d. b4 O: ]int isOpr(char c)* P) k7 ]; y+ F) } L" m* ?6 o. A
{, N% h' H9 S$ v1 E# ^; a
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')6 Y" e. C$ ~' t4 b" L' _, C3 j
return 0;( ]5 o% y; l8 P8 o% M- B
else " H) g' `" B/ ]
return 1;
8 T2 z3 G8 c6 K w, p- G0 ~- h}
+ `. a4 o# Q8 f" D" @4 v2 p" S; R& `& v; C' A( O$ @
float operate(float x, char opr, float y)
8 ?0 q( B+ ~( I9 ]8 u6 k% k{
& ?0 i# t$ \& i( @$ j5 K2 F float result;
. I0 Z4 f4 i( C; a+ i switch (opr)
& c' F, {* A0 C9 m {
2 r* U7 w- S' h9 ^* u( h case '+': 1 s, i( `% T5 m2 ?1 k
result = x + y;
( z1 p1 e8 W: }7 ]4 T+ b, @ break;: z* M8 f3 i! S. ?$ l9 c. v+ c
case '-':
8 A5 J3 x6 B/ |( s! l$ a' U- t# T result = x - y;% s8 ^0 D9 o! y4 R
break;
& W2 r% @% q$ e3 d& ~5 G% c case '*':
% P1 N) C7 P1 s. I3 r result = x * y;
4 M2 v) C9 B) F* E2 [8 ? break;2 l6 ~, \/ c# o# e
case '/': 9 v! n& N' i& H I4 G$ a
if (y == 0)
& c3 T& | i+ T5 P6 V* C! Z- e {
( B! y1 O* z t' s$ }% a8 v6 k printf("Divided by zero!\n");( `& W5 e% N8 M# S: p* W7 P8 k
return 0;9 B/ B# O. l8 B- ~' M
}& l) z6 k( ?( T: x' `
else2 T/ d, x6 m. A) ~) W6 k' I
{
% Z1 ^( ^: l: Y) s result = x / y;* H+ f+ I) z% O
break;, ]9 ?( @ _6 O0 d- x: Q5 x
}# d9 a, u/ M- S8 A
default:
9 }4 Y0 ^" h [, C; _5 k* s printf("Bad Input.\n"); + ^$ E6 I1 Y4 N% W. ?& I
return 0;& \1 u2 { L2 K& ~! ^9 G! l6 T
}2 h' @6 p6 ]' {' L2 s4 }
return result;1 N: e8 z6 G4 O
}
$ B' j7 k; |, _+ v$ a& I6 R* L% S# ~* i0 f
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/& I, r0 X% V$ R0 F) x
{
4 [7 a9 w# z; |4 A7 d Stack optr,opnd;* U3 e% k5 q! o) m
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
- y6 V6 f3 n/ M3 K' ` char c;
4 _9 N% N3 l/ S* y4 ` char buf[16];
& W9 ~8 F. W9 n& u8 C int i=0;
! ?$ T' F1 n: X2 \" i6 \
% x# M4 A1 J6 @( i# B9 z InitStack(optr); /*用于寄存运算符*/
: P* s# F- R/ |7 E. v, S' o InitStack(opnd); /*用于寄存操作数和计算结果*/7 J& P9 _5 A+ d3 h
memset(buf,0,sizeof(buf));7 i; w* b) J: j$ V" M- q* x" S
6 W. j4 l2 o- G: ? printf("Enter your expression:");
8 ^$ e1 J& P) F( r6 E, w; {4 n - Y) O, ^8 P4 i, I q/ r; k1 H
opr_in.ch='#';/ ?4 i% S& y% P" X
Push(optr,opr_in); /*'#'入栈*/
9 W" U3 }& }; t+ q GetTop(optr,opr_top);
8 \! i. }# o" ]7 D c=getchar();0 Z5 j1 L4 S. M
while(c!='='||opr_top.ch!='#')
( l& M/ ]/ Q# a0 |4 t+ d: } {
m: C; m$ o1 Z h) f if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*// a+ W7 v% G1 H; \
{
/ D8 g, x y$ A3 l! Z buf=c;' p- b1 D' P. A" j( e
i++;$ a& }3 x* T5 a$ O
c=getchar();8 P1 L R! f$ n- i
}: D5 N, G" T0 `8 r9 D
else /*是运算符*/
0 j, i: w& L! o4 X- F {& I. Q3 G( n. n# b. O3 G' H
buf='\0';
, T* r( Z2 L: m+ p" i if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
+ K1 x! c3 ]3 j; i1 {" j' s {
# E$ R9 y, N* L, w. l opn_in.data=(float)atof(buf);
2 ^" L. ?) m3 F' ^* c7 R m7 K Push(opnd,opn_in);
) g C. W% {" C! {4 K! N4 i printf("opnd入栈:[%f]\n",opn_in.data);
; i% Y7 Z0 s) C# _ i=0;( E3 W0 q$ ]9 E6 R/ m2 u( l. e
memset(buf,0,sizeof(buf));4 l% W+ s e% R2 X* ~
}3 Z% i+ S! W3 n1 |
opr_in.ch=c;0 }2 ?7 c/ |% r% Z
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/- t' w% ~9 I( |5 |
{
8 g, X- A% ^3 h' _6 @# }% a% B case '<': /*优先级小于栈顶结点,则运算符入栈*/4 h- N8 }- v) G
Push(optr,opr_in);
4 g4 v4 j, I& f. v4 g8 L printf("optr入栈:[%c]\n",opr_in.ch);
. b. [9 a9 h4 y- X" g+ l2 Y c=getchar();' b8 I7 P% v/ j
break;; L, o, d1 {/ v( B6 Q
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
/ N3 t6 r( d' L2 W! E Pop(optr,e);
8 x' |$ I" C5 n8 P" @ printf("optr出栈:去掉括号\n");& T# K; V( b( ^) y7 ^3 h
c=getchar();4 x4 h7 _1 F7 o Q: x& i" t% N
break;/ V- {: @" e! g( I* z7 E
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
1 ~0 t8 d6 F+ b7 h Pop(optr,opr_t);* P+ [ r3 O" D/ d) B" q+ B
printf("optr出栈:[%c]\n",opr_t.ch);
; s& R$ N; L$ k, ` k if(Pop(opnd,b)<0)- z0 e m7 b4 Y* e" ^5 r7 {8 |
{- y. H9 G4 f; I* M
printf("Bad Input!\n");. r0 ]" W4 z% A
fflush(stdin);
) Y( q5 ]5 b1 B return -1;
" y. S9 x! N. E# c9 A }
0 i) s7 B# e' t' E printf("opnd出栈:[%f]\n",b.data);! _1 c4 _$ R$ R5 t+ ?! V; U
if(Pop(opnd,a)<0)
- n3 T5 O! h+ ?, N2 C+ E% w/ U {
; L+ c' c9 v* s printf("Bad Input!\n");: r' y8 ~5 h3 O! _
fflush(stdin);: y6 m; b% W6 Y: o: g
return -1;
3 G/ v1 I. L! _& L, T }! j* m8 d, C! q' F7 T
printf("opnd出栈:[%f]\n",a.data);
: @3 `; n% y+ |5 k opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/* L/ Y6 b( G+ U4 {. J% {
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/0 j9 K. D/ S% \
printf("结果入栈:[%f]\n",opn_tmp.data);2 B" C3 {6 P, F* z% m! H
break;
e/ s4 c3 b% M2 {" c5 [ }
0 E- u @0 N1 F+ C4 J }
; P2 f: b! B! }$ J9 K GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
- s$ }2 @1 r# l# m7 T9 T }8 n+ q0 I$ D% ?# T+ S
GetTop(opnd,opn_tmp);8 N1 @- P& ] ~5 m" X' b
DestroyStack(optr); R3 Y. G, E/ B
DestroyStack(opnd);
) P5 f- d c5 A/ x: | {) _ return opn_tmp.data;
5 H. e( m& v6 u0 @; n5 n}0 C! M4 R0 P5 o! M2 T0 c0 P
' @0 a" V% r, Y* L; \# O: P5 U
char *killzero(char *res,float result)8 S& Q |+ n+ J$ D
{
. H3 V# m. v/ K- E int i;
. m* g% y! ^" e+ k, K$ ^6 K7 _
) ^5 t4 n& ^: N3 [+ ] sprintf(res,"%f",result);+ z* F6 R# {3 ?. g$ V! m1 \
i=(int)strlen(res)-1;
; F' W# N$ z* L- d, V; T while(i&&res=='0')0 Q6 [1 _2 @1 _& i, a0 x
{
7 s0 h2 P5 S7 ? res='\0';5 I) @1 j: [3 Y0 a( f
i--;
, _: {$ [' l) Y3 K+ w$ Q. ]$ [ }
7 L& z) T+ h& F; ?1 i! L if(res=='.')
' d& V* o. l1 }* V) S" e- Z res='\0';" p: z) m$ A& d9 h4 T% ], Z1 ]- |
return res;( U. i6 C. N' f
}
, s; l* O, _9 Z4 A( O' k6 e# D+ z9 w: C- [4 f
int main()
% r5 K m2 l8 h7 n{9 H: S/ c* x5 H6 {5 Z$ |1 d
char ch;* g& C# D1 z8 b, g# L
char res[64];. C0 c9 t8 {8 F, M# X5 j h# `$ O
float result;
9 H& l) W, }) J8 M0 g, [ while(1)
2 }' O0 Z) t3 t2 x* Q {7 E1 j% V% T; S+ P. Q
result=compute();/ s# ]; F" G$ q+ A& {! v# f
printf("\nThe result is:%s\n",killzero(res,result));
$ M; _. l+ v( E$ B0 a* Y0 t9 Z printf("Do you want to continue(y/n)?:") ;
7 |1 H1 e4 z, V/ w5 N) O ch=getch();- ]" e' ~7 s$ E; n0 N2 j6 e, c
putchar(ch);
' ?6 K; s) I/ `% B, K5 C! ^ if(ch=='n'||ch=='N')
( D6 N8 K. C% V( L break;4 s8 Z/ ^+ R; C
else0 D5 [3 ]3 N" f$ S
system("cls");
( p' i1 h1 s3 M$ _# o }' B2 w! }$ t0 V6 e/ N# B! Z4 Z
return 0;
( n# e+ h+ v4 M3 I- W4 [}
3 k9 ^+ o5 X% O: y( i
, K* q/ Y5 d, N- g% @[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|