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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的., P( q- I9 y1 H2 I5 V8 T
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=4 P, f, j+ R7 ~! H
/**************表达式计算器************/9 d& m& N9 V& L$ s: I
#include <stdio.h>' c3 u) t' ]. u4 h v
#include <stdlib.h>
, v& b9 u* S$ a* b#include <string.h>, c8 \2 Q9 T1 Z# a
#include <conio.h>
c7 q! G6 m0 w z* ^ E#include <malloc.h>3 B) i! [5 u" g; w( X3 y9 \" a
) i5 L) E; ~2 d$ o
#define STACK_SIZE 100* U2 n* ?2 N' |/ w
#define APPEND_SIZE 10
, }0 v, Q1 G8 \$ a# E% o7 v1 a& E# f- t0 M( y/ F
struct SNode{: G4 O9 h: Q+ w2 i. `
float data; /*存放操作数或者计算结果*/
3 B) |& u% R' P4 N$ e' ?: Y: \( G char ch; /*存放运算符*/
' r' n: w7 @, F" p0 y};& x9 K$ l2 v2 r) q- @: S+ C
* z M4 `3 L/ [* \; } Dstruct Stack{
/ u7 E: M/ r" M0 L; f. r SNode *top;
: [: ]" x$ N5 C( s SNode *base;
" y9 {# O0 j: S; t4 d int size;# S) a& k* l9 C! D( A4 z5 K. ^
};
* L9 h7 d9 Y, O9 m2 u/ k; I2 P1 C% S( I3 _' a# p
/*栈操作函数*/
8 ]3 m0 y7 a* |* Sint InitStack(Stack &S); /*创建栈*/* t/ K7 l& ^# `! T% L' t
int DestroyStack(Stack &S); /*销毁栈*/
5 j$ h% I6 v. e4 |* a6 i7 Jint ClearStack(Stack &S); /*清空栈*/5 j6 a7 C3 U& _
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
( X, M& o! n7 P! y1 w% ?int Push(Stack &S,SNode e); /*将结点e压入栈*/( `$ M! l2 u* }6 w
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
K' v- K4 A& c" f5 ~0 B9 h% u# G) \3 a' a
/*表达式计算器相关函数*/
- `6 ?+ _1 a; Q& M* ~" Pchar get_precede(char s,char c); /*判断运算符s和c的优先级*/* v7 R: a! J2 m" V
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/$ d' G: q9 Q9 p; {! M& i6 f$ S
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/- z" e6 u; [0 h' X# u( R
float compute(); /*表达式结算器主函数*/
* p4 b8 Y/ K. Q( r4 G2 f. j) hchar *killzero(float result); /*去掉结果后面的0*/
: ~1 k4 _/ {3 k, n( a. Q
9 g/ d1 R7 b L( k4 cint InitStack(Stack &S)
" t, [. q2 y4 M6 N; a8 C{
* A- |0 x7 g5 G$ w, k5 r( ^. T S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
+ C5 l5 _( E0 m8 Z if(S.base==NULL)2 A; D0 f! J! K1 ^! Q1 k# |# ]8 W
{
7 f# T* `) n* p& M: i printf("动态分配内存失败!");
$ v5 Z( v2 i) k% ?5 @5 I return -1;) z7 N# S' }, [6 ?1 b
}9 ^# J- I& p2 Z
S.top=S.base;9 S4 K+ w# {9 V) u1 Q
S.size=STACK_SIZE;8 r- K1 {0 U: ?& t2 X
return 0;
4 |$ M7 V; [ \1 Q; [3 w% P}9 V. t3 Y3 k7 Y7 @ I
7 v i, n4 e$ A% M0 Z+ J$ H; X9 u
int DestroyStack(Stack &S)3 g' ~. c% v2 v9 M
{: O; w _& }: T. X- [# |
free(S.base);
, O& l$ g' }! f0 L0 o* s+ L return 0;
# G" S0 @% [) S. _. [5 P}# e# _; ]& M+ k: E
* m0 @$ z8 {6 U: z, c, Oint ClearStack(Stack &S)' U* u+ G: V d. K: l
{+ \3 j5 Y- {% @2 U T
S.top=S.base;6 E1 D9 y- t/ M6 Y2 s8 F
return 0;
# N; W2 z+ p+ F" d: h! S+ w- {}& V& K. D6 t* L. z0 T' ?5 R5 A
8 c" {3 ^3 S% |# q) z" ?! Q
int GetTop(Stack S,SNode &e)1 Y& n" y/ K, X
{1 f) [7 f+ Z. g" d7 S
if(S.top==S.base)2 R( Z6 J* T7 r+ ^: t b
{5 K, t: e# h/ Y% X; T! \, x& U
printf("栈以为空!");
3 f4 O& u+ L% S; j return -1;/ C: D" g& x# T' Q: T" U
}) E0 j; v- k$ Y3 b
e=*(S.top-1);' G" @; T3 I6 _5 o9 q% z6 I+ c
return 0;2 r# A" s2 F8 u! C M$ s8 _1 O
}
, f; l+ J4 a) a& G+ j: r: N6 M# T: h7 {& Y! L ?
int Push(Stack &S,SNode e): ? x d+ @1 I) a% P# p* _
{
9 ]! y) e3 p; p- J. d if(S.top-S.base>=S.size)
7 ? X5 X2 r2 U" f5 j {) m" U5 |1 W B; w; ?* M+ s7 q: g
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
! N: A1 @( P2 r' A- i5 \ if(S.base==NULL)
" i% u# E' ~1 e3 Y: [; r& b {
3 [* ^& q' j! @8 B. g8 e1 F* p5 k+ Y printf("动态分配内存失败!");7 M* T }2 r% c- a9 d
return -1;& w$ O/ O6 y+ V1 @9 ]; ]' E) b
}; F+ {4 |. z6 W5 X
S.top=S.base+S.size;
9 e# D. A/ K, a6 Y# r S.size+=APPEND_SIZE;% g5 B3 E- Z/ z; ?% Y& E
}; X9 S- _, b0 l" Y& M
*S.top=e;
$ A& P6 M$ ]) G, _. w3 z& y S.top++;9 U# t" N% q* s1 a9 _2 t& D
return 0;2 _& P$ P9 F3 P _6 v0 a
}
9 s7 d& o# z4 O" T# b* _
% ]3 x& }* |, T4 ?! \1 bint Pop(Stack &S,SNode &e)7 [! H5 H* w$ M) q- `
{
/ F' c+ e( J# Q% p, q if(S.top==S.base)
) I! H9 T3 V! j8 _; C9 U- [ {/ t8 l1 K: f) p/ R! A
printf("栈为空!");1 m1 E4 v6 R+ j9 T5 d3 c
return -1;, m, n$ {% u7 K! G9 @/ j8 e
}
/ U2 P, B4 S9 U' V e=*(S.top-1);
% l. ~1 O4 o0 z e8 }9 F S.top--;% {- J* }8 ]' [ F% R* {
return 0;- I' U0 v* v7 I6 ~* z
}
4 B' Q" {3 {4 ]6 \% q; x! O5 U4 ]" \
char get_precede(char s,char c); a# Q9 Q( V+ t
{/ M+ j R/ i1 M$ x! M: e% r. k
switch(s)
) g# ]4 U/ Y3 O r( P; L& f {$ R" n) L; V1 C! ~, V
case '+': , }' l6 C$ ~. i8 h' R0 r
case '-':2 ?% l& Q: |/ F" p3 V0 _9 P2 g* l
if(c=='+'||c=='-')
: X- |: S; ?& }, M return '>';
7 s; _) I2 j+ X1 B else if(c=='*'||c=='/')
, n( z2 s+ O/ _0 X% J$ f return '<';
; F/ I w& l- N. Z& J else if(c=='(')& W# o+ R- a! ?) q
return '<';
% P0 _/ _) o7 |- J7 Z) E- q) D# R else if(c==')'): X$ e( i. z9 a, g; O* f6 j, C2 `
return '>';
( J" j1 y. V" Z) P else 0 z8 i9 W# y7 c9 O
return '>';/ F! Q/ h4 ], g8 g: N
case '*':
) a. W0 x" C6 {+ ~* d case '/':1 h( T; y L- i1 z4 S& H5 }' ~( r# U- C
if(c=='+'||c=='-')% j5 b5 J0 F* j; [; U9 G( P
return '>';: o0 A9 j( s- p. B# c: E* ~
else if(c=='*'||c=='/')8 i' h0 i( ?' N# y' `6 v- i0 ~6 V
return '>';& E! d, J8 s+ k& n6 l ~# f8 N) |
else if(c=='(')
6 b4 f) v7 u, n( G. e* \* M5 |$ S/ R return '<';
, L3 q2 P9 s( M5 E/ a else if(c==')')2 V. }$ x: P; Q2 K! }+ |
return '>';2 q9 {! x. K& h: q6 b
else
; F1 M1 {3 a, ~) s0 Z return '>';
+ S9 z& V6 a% `$ U' H case '(':* c" O; q1 R% x* q7 f
if(c=='+'||c=='-')
' W0 u$ z( J) t0 Y8 Z/ y! I return '<';+ j' o+ }0 y; Z, E! I2 w
else if(c=='*'||c=='/')9 U$ }+ Y& \9 C; O# `6 J0 z) w
return '<';
5 L+ B0 k6 Y* |2 [ else if(c=='(')- `- ^ N% C* L/ d8 J8 N$ ~
return '<';
5 [8 e% c5 ^7 O! G; W+ K# K else if(c==')')
0 X$ z. T3 N- C) z) ~ return '=';4 b1 V) R R) W. i5 M- f; Q8 l; _
else
! J5 G9 {- `8 k+ M return 'E';! @0 B2 B& s. h u- O; s
case ')':% ?+ W7 c9 e* f+ I7 S
if(c=='+'||c=='-')
. z; w4 [) _$ k. ~1 v5 Z3 D return '>';1 E k5 J5 e4 @; {% T
else if(c=='*'||c=='/')
+ _/ z2 U3 B( Y, ~6 A. W3 ` return '>';8 }* X; s& F2 j h4 Q
else if(c=='('): o/ l6 T* c4 `- n6 j- G. e
return 'E';+ q" e. [ W/ a: c
else if(c==')')* n: o5 Q; V% K) \5 ]2 X c7 p" w
return '>';1 K/ \6 D$ M1 @3 X$ w
else1 G4 L4 ?0 r4 A _4 m
return '>';/ l6 @: c# R1 M" p E
case '#':; S* U: {. M3 V. Q2 h6 b5 N" O
if(c=='+'||c=='-')6 _; d5 Y% o0 T0 S& {. K
return '<';: I' k, j8 t5 i8 \8 Z/ ]
else if(c=='*'||c=='/')
: D0 ]' n% _3 z4 Q! X* d+ g% U8 L9 w return '<';
/ P' G% D% P* U1 n! N( [' w7 v else if(c=='(')% z' L% u" h* l3 s& E. S' A1 _
return '<';% T7 }: ]0 f) i1 v' Q8 k
else if(c==')')
6 g2 e4 \- b0 R return 'E';8 S J: ~" z* E: r. G
else, D' s6 Z5 r) I! ?! F- t
return '=';
3 c1 B- ~# M' Z. Z default:& ^- Q6 U$ C2 M) f1 Z3 m
break;
2 y" g- B5 W4 T3 T$ j }
9 m& F+ ~- B7 N3 F) _0 c$ ~ return 0; 1 W. s8 o2 A( ]% V/ {8 R2 _
}2 M$ M; S' h) J6 N
" J, I8 e' w# w9 b/ n' Qint isOpr(char c)
+ Z3 A# A, j/ e# E% i+ ~3 J{
- k0 `4 E. O- h( O4 l* L- H! V7 a if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
2 E( ]0 t3 ]3 \+ B4 A4 \5 C2 F) h return 0;
+ b+ C9 e1 A' X) n% O A else
/ r: t4 i: l( J- r/ T, P return 1;) n6 ~- r6 I8 E- L r
}
" ]4 J. y3 P$ M7 \ s7 ^, }4 j. f4 t- M0 ^
float operate(float x, char opr, float y)
9 {+ k0 z& W/ ?, `+ a8 Z{
: n- C1 x# s: n' ^2 N2 T float result;6 L% X& A4 y# U/ r, b4 R& [1 j
switch (opr)
* p+ _. p- ^" l z; O( w& v {3 a: \2 E6 F d& S; d4 v+ R
case '+': / R4 M, G5 X# V( p2 q1 A# y5 W' q2 G
result = x + y;3 [% e! S3 ]2 B& L% y
break;
- G' T3 x0 c, N; E case '-': [) g0 v9 Z p+ _2 d
result = x - y;
, t6 s: \6 m$ q break;2 v. C# k* R1 l& T
case '*':
0 V7 K$ o5 @5 ~1 t, s+ @5 k9 {) W result = x * y;
) y: O; D, ?3 |4 P. Q/ I break;
# J) I2 Q/ ~0 T( | case '/':
) v4 l- X) S. z# m if (y == 0)
2 h2 f5 V) ~0 i( r* Y {3 a, x1 N) B1 q! L/ {
printf("Divided by zero!\n");5 g% f( `% X; {0 R5 N) x' a& h
return 0;
1 `1 q ` R9 `" b! T }
9 \2 T- C: m" G) _! W2 \8 Z else T$ c3 T, d& B6 \5 K; Y
{
' t7 C. d1 c2 P+ u, B result = x / y;
2 s% s' F( m c+ k0 n7 f: j break;0 A4 s& Q/ {: s% h+ \
}0 i* _* M) a+ x2 s% u, z* Y1 p$ s" C
default: 1 v. e' t' F+ R& r' j
printf("Bad Input.\n"); - V7 M% L4 V* \5 z) H3 r: R
return 0;
q" w3 s" ]* F1 l }7 {4 H9 U/ i6 t( X
return result;1 U; P; F6 E& |: ], E \
}
# w& o' X6 K, j9 ^& s2 J
9 S: `' Y* g: b5 B7 lfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
) }3 T3 O" x5 `" D$ ^, ?4 ?; p{+ F5 \7 C# x; u5 O) ]# @
Stack optr,opnd;0 @2 S4 L: T6 q* C+ E& Y" H' P9 X
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
+ k; F# \$ N9 P char c;
B( l2 R4 k4 O. P: F2 r2 ? char buf[16];& O$ f7 G+ M+ g$ d+ d
int i=0;
% @' H/ q! @; p1 [( Z2 M& b3 p' {4 A
: t5 I D9 W3 \4 F' ~ InitStack(optr); /*用于寄存运算符*/. E+ F/ W0 U+ Y: m
InitStack(opnd); /*用于寄存操作数和计算结果*/% n- k, h5 R/ O) G$ J
memset(buf,0,sizeof(buf));% @4 U s R& ]# E, m* X
6 |5 u! _1 E( ?% Y
printf("Enter your expression:");
& ?% O+ `- d- L0 ]3 r3 h * z' H) Z+ Q" w* \8 u
opr_in.ch='#';) o1 @; ]. k( K3 z9 w
Push(optr,opr_in); /*'#'入栈*/
7 C7 L: G7 d7 ~' z. i GetTop(optr,opr_top);* Z0 T3 u U: K5 S. ~- y% N% H
c=getchar(); \# t! e8 X' U/ T; a Z
while(c!='='||opr_top.ch!='#')+ S9 }; J" n1 M
{
6 _/ D; N6 o' N if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*// L9 K. n" W$ x" X% |2 T. r
{
6 m# S, i8 ^, {+ U$ J4 N buf=c;5 Y7 [& p* x1 C3 Y4 F; L
i++;8 [8 {' y, t2 }6 _
c=getchar();
& k9 M8 G0 E! j! \6 | }) ]. M- u" t- g# V* T- p) c% p
else /*是运算符*/$ x( I: e( }5 i0 p- q- X0 A! w
{# d9 p) Q, | [' L- u5 Z
buf='\0';
0 F; [, W3 p$ J if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/* {* d+ H- ~* J2 G2 q+ K+ R3 u
{
2 R. o j) U* [$ Z9 m7 w2 j& H+ I opn_in.data=(float)atof(buf);6 l: T3 O7 e6 p3 Z
Push(opnd,opn_in);8 [7 k8 A* g6 A0 ?
printf("opnd入栈:[%f]\n",opn_in.data);5 q) O( o+ |; y7 \
i=0;
' l5 u x3 K3 J9 m- O7 T: r memset(buf,0,sizeof(buf));
+ y n* b5 C8 ^8 U% [7 |' ^$ w }% X6 C* q! ?7 j! t6 T; z2 P( x
opr_in.ch=c;2 F) m* B' h* r) ]' Z$ @# X
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
" g- N0 [' ?# J {1 w+ A* z" ^. g& _( D8 i8 Q
case '<': /*优先级小于栈顶结点,则运算符入栈*/' [6 H1 w6 E$ B4 t+ s
Push(optr,opr_in);
" q$ s, C$ u: _$ p6 K- y' e8 O, Y printf("optr入栈:[%c]\n",opr_in.ch);4 [4 N/ S t3 z! N+ b
c=getchar();1 i$ S/ x: ]4 U2 w4 F% \, J
break;' x0 |* Q- u/ f+ t' g
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/$ Z2 d$ E+ ]& y+ p: x
Pop(optr,e);
% X9 i+ h/ m0 R0 s( s printf("optr出栈:去掉括号\n");+ g$ E/ E: V% }7 a( X
c=getchar();
0 L. M) b/ E1 j; C+ k break;
" u. |4 A8 [! K7 W) ] case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
% h8 t+ K7 ~$ ?7 P Pop(optr,opr_t);
6 P5 m" I% C; v% }) _ printf("optr出栈:[%c]\n",opr_t.ch);. U- ?* J1 I9 b# c$ u: M# z3 ~
if(Pop(opnd,b)<0)
# ]4 n$ ~6 j' r {
; w& E8 D4 }( I" p5 d/ n* ^: T printf("Bad Input!\n");
: b' A2 C7 I- X fflush(stdin);
/ J' b% ?# V3 j return -1;& h; q9 ^! l* |: z! z8 n
}8 E2 y' n5 Y9 [) H, P8 u
printf("opnd出栈:[%f]\n",b.data);4 l b8 q) \6 A# [1 K$ |! @1 N6 n" K7 s
if(Pop(opnd,a)<0)
- C0 Z; B, s ^9 Z b3 ^ {
! S |% U& I7 h2 j- x) I2 R printf("Bad Input!\n");# Y2 S3 H( o' g2 l" M |9 i
fflush(stdin);
0 \- k1 t7 [- B- e# S' y* F return -1;2 O2 M: b! A1 T! c R* T
}
8 t/ q+ F6 w) W% {- {0 I! l* y printf("opnd出栈:[%f]\n",a.data);0 m. Z1 O" w' M% O' S1 ~& |. T& H
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
! V+ x! {8 F% z! O6 V W- ^ \ Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
4 Z% g; U9 l% m) k8 Y printf("结果入栈:[%f]\n",opn_tmp.data);
9 N+ P/ h) z% V3 ]+ S1 R break;
2 R' q7 g2 V$ ^" a7 N+ m( J }
, M( t( P. A( c) I0 n }
, y) V5 ?/ `; A) H# x GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
/ d5 S2 @0 j' y }4 U" U f+ c1 b1 U
GetTop(opnd,opn_tmp);3 n5 ]3 y( R1 X# }$ C
DestroyStack(optr);) E) U; |2 H& K& B/ _. Q4 b
DestroyStack(opnd);7 m& {# C. z; ]
return opn_tmp.data;) V* s, {- E+ ]/ j4 N; c6 {
}9 b; n2 |% s3 b: Y/ z: c5 ]+ }
6 @6 K4 c7 ?$ o+ Z4 Fchar *killzero(char *res,float result)
, f: E/ n- i( L4 |$ S{
& \* B5 F4 K7 [ int i;
o/ Y( J+ ~; I( }' {3 w# L g5 J6 X7 [ v4 D" S8 _
sprintf(res,"%f",result);9 E, Q2 L: p0 P6 Z" e8 m8 H! T1 i# m
i=(int)strlen(res)-1;5 a" G: Y1 J( Q" `- b" c! j
while(i&&res=='0')
8 H$ `; J$ }4 g; h0 p* |( {' c( ]8 ] {
3 R8 W* p# ?- H% H4 Y res='\0';: o$ T4 F, H) A% }
i--;5 Y' U: Z% [8 u, R8 } V
}) E, I; V: L1 N, U
if(res=='.')% e; q) X& V4 l
res='\0';
6 `8 F) {" {- n return res;9 [ s9 P+ W- ^" X" U
}
% ^$ ]+ k, x8 H S
! i+ I9 N/ A4 a2 lint main()
+ m# R; A! V* Z{% i* h) _% c7 Y5 ]
char ch;/ H& q: f9 m" L _6 X7 a
char res[64];7 n9 I$ W1 G( S* R. i/ U; m
float result;
/ G7 y2 l2 F! S while(1)! ]3 K( l7 s+ R
{
/ F/ U! c: y! ]! J% k result=compute();. J- M" p2 [" H
printf("\nThe result is:%s\n",killzero(res,result));
* I$ m! \4 _* A printf("Do you want to continue(y/n)?:") ;
; L* V3 A9 q# B; y/ r* Y ch=getch();! U( p2 y! c0 q6 H0 @, q
putchar(ch);4 a1 P# A1 d6 y) }( G i2 Z- b. f
if(ch=='n'||ch=='N')
- b# z* b4 G1 ^* `$ j; k! W; v% { break;0 x* g8 E S' D' m+ H# g
else
% c, { g* _/ `3 L0 c system("cls");/ ?1 @. W* j! E% r- K
}
* u% U' i2 a3 j& f1 m return 0;
( u& ~6 E2 L( e0 v# O! ^! Q# g} H3 |# u- @ `7 }0 q; i* p2 O/ U
8 k- v* i3 ?8 g[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|