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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.5 m8 F3 P0 |' }9 t
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=: E: X0 B. M$ d+ L8 _0 e! f
/**************表达式计算器************/4 r! D1 _2 K8 }% V( d
#include <stdio.h>( r2 z# c, a* U5 C
#include <stdlib.h>
7 S4 R& B, I' ^9 c0 A$ O#include <string.h>
7 {/ w4 f1 d& z! F0 n0 F% h1 Q+ H# i#include <conio.h>6 o1 R" P- h6 t# H8 t* ?6 N
#include <malloc.h>
* e) Y+ O# j4 S7 d9 M/ a+ Z- [- O6 h
#define STACK_SIZE 100% R: S0 s' e( I/ }/ [: ]
#define APPEND_SIZE 10
$ g* D& Z4 g& }& ^" f
6 v5 S: z9 n5 X. H- g4 D* T/ Fstruct SNode{) Z" O6 ^: }) f* ]8 w
float data; /*存放操作数或者计算结果*/" w9 X' u, E( L! R, i
char ch; /*存放运算符*/
, n& @4 t: O2 }5 L) Y2 z: ?};3 J; b. P% j& R+ l
( e* B! v% A# j* X5 E
struct Stack{9 U7 s- `, z6 [% h. j0 A
SNode *top;5 F ~5 s. g8 o1 X1 j3 M
SNode *base;
6 Q% ~( l' d, B int size;
. h' h4 m: n* y) q};
6 P0 Z- \0 o9 {9 {" ^* _
# D2 o4 a! C) O4 c4 e. ^/*栈操作函数*/4 H; O5 R. Q$ c4 K8 v, V7 E3 `6 \
int InitStack(Stack &S); /*创建栈*/
$ j, ]3 w' |* B8 \6 I5 d) a+ G Cint DestroyStack(Stack &S); /*销毁栈*/; A& |" m% P0 q( l0 M3 F6 g
int ClearStack(Stack &S); /*清空栈*/0 c4 t5 o8 G; {9 t. U( s
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
8 F. j. O# V% Q: }9 N. U+ Dint Push(Stack &S,SNode e); /*将结点e压入栈*/
+ g; o9 Y# J/ B' D8 y# H: W* Y8 w. Nint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
3 [8 F9 v/ h* G1 b f2 K
4 B2 D) f/ g1 L' M b8 |/*表达式计算器相关函数*/; S3 p# r6 Q+ i: {% c+ z2 R2 o
char get_precede(char s,char c); /*判断运算符s和c的优先级*/' g; U8 l1 G; I8 k b- k
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
$ w7 H" X! s# z* nfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
+ J% q7 H' k7 f5 i8 I- lfloat compute(); /*表达式结算器主函数*/
# G4 K9 F5 m$ |4 ]1 n9 H7 F# Bchar *killzero(float result); /*去掉结果后面的0*/
; h) Q! `0 F! e' t! q i$ X- Q; O
int InitStack(Stack &S)8 q+ \ `2 D+ K1 L; ]' [: F
{
4 n% M! p- H$ Y5 ~! ^6 K0 J S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));$ B/ o" W* z& A0 v q( y7 i
if(S.base==NULL)1 c1 V: @% i* N3 {" w
{
3 q' J" g& J/ }4 n9 Y0 _- `) G, t7 B printf("动态分配内存失败!");
/ E; Y$ B6 Y& Z. N) S. A- ^6 ^$ w2 Z# M return -1;
) d5 j5 B3 |* P' a, L# P; v' C }
3 c6 Q, O2 T! O! W, } S.top=S.base;
+ C2 X' R/ I2 q S.size=STACK_SIZE;: V) B0 Y* B, Y6 A* x
return 0;
: ]! Z& N. F3 X' T9 N, J+ y! p}
" a% x' @% a& |1 l
" n% |: X% `& jint DestroyStack(Stack &S)$ s& E( H* u2 f/ ]2 e
{
/ E9 L5 r) u j* `! X free(S.base);
* u" @# \5 v% {9 f) h1 p& x7 ]) u$ ] return 0;
' d6 V) E( u, W: f! V9 I}. q9 S, A% `- d1 z3 A
" e2 Z/ Q; I( h! S7 q; O
int ClearStack(Stack &S)
, l0 J, T, ?3 K- U) g{
/ E7 e9 D; ^6 ^& A8 R S.top=S.base;7 Y7 V# Z0 S% p+ [% K" A
return 0;0 v$ W2 h- j9 Z1 H9 Z H: w
}
& P3 j. q& {& q# S2 H/ Y) [. ~* m: z2 N# w
int GetTop(Stack S,SNode &e)- W2 i) m4 o# Y) n% c" T
{ K6 E; }$ ^! w. `
if(S.top==S.base)* x" J6 ]0 g, z9 d+ @
{
O. H" Y3 b/ U* D7 \5 { printf("栈以为空!");( u: u1 O0 g$ A9 C- w; w
return -1;, x s6 U+ ~9 a1 D6 L2 {' a! S
}/ J5 ^+ a0 I( M, C( [
e=*(S.top-1);
) A- g7 p( m1 D; ~$ Z: w return 0;
9 S( B9 Q4 k9 O7 v/ B3 @}. r2 A9 [' M3 V' C, @$ Z3 T
0 R; H' _! b9 H" Y5 hint Push(Stack &S,SNode e)
$ e( q, }+ s) @, W{+ X6 g) }+ k" r& V$ {' \
if(S.top-S.base>=S.size)
( V5 }* b; w0 ?+ \% Q" ^# z; H {
5 I; a% @% J1 _7 d% c& s S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
$ f% U! q3 j. ~2 P if(S.base==NULL). A$ f: b. Y, u- k1 E- V! M! s" J
{5 c- e. X# j8 C
printf("动态分配内存失败!");# T! U: A! @3 B2 E, f4 d0 {, T
return -1;1 m: U7 a! E# W; G1 t7 j
}2 ~0 f1 S0 j- l) N; D* b5 W" D
S.top=S.base+S.size;: T. s- o+ }/ Y$ Y. A" V* E, Q
S.size+=APPEND_SIZE;* e6 ]4 z3 i# R! W# C( c9 Z6 y8 @ O6 K
}
# A' q- e8 D3 ?! i1 r- V% D *S.top=e;
! D2 k, y2 y8 x ~0 v2 z& m S.top++;! j3 Z9 e$ \( T) N, H# v5 q1 W
return 0;. c4 Z$ k; w9 V$ L/ W4 G
}
$ j+ ~8 o' V a4 G$ s3 P g ?, V7 G- n3 a$ w$ Y6 n7 Y! F$ c
int Pop(Stack &S,SNode &e) V( T: C# A+ `; k' W
{
* U' e- T4 B. g if(S.top==S.base)
T9 b' b# G2 t, ^3 @0 e! S( m! W {
8 u1 X/ l3 j, h8 ]$ o printf("栈为空!");& h2 h4 _1 [" w0 Y( a
return -1;' y E/ T" e P/ \* ^8 M) y2 H
}
, O, A: x8 J5 o0 P1 n2 ] e=*(S.top-1);5 q9 W5 e7 F& p: j5 k+ R
S.top--;& O3 b5 k/ X) ^5 b
return 0;
' W, r) ]9 O4 v/ i; ~}. `/ o: B4 R* T. Z! E ^6 o
; T( Q4 Y [7 U2 T
char get_precede(char s,char c)) }, |8 T8 ` d j
{7 t, A/ v9 F% v' V* Q% S
switch(s)
/ x: Y- T: N- E _ { g( ?/ t3 s( L
case '+':
' A0 j v9 a3 B: b/ V case '-':% S5 }# Q* k0 t0 E/ s; s; }
if(c=='+'||c=='-')
+ U& k' H) m% P1 Q return '>';4 d7 A' N- s4 k4 R
else if(c=='*'||c=='/')9 Q4 R$ x+ X6 ~9 z0 V- R& R2 B
return '<';" B2 E7 D# J x# B5 h/ A
else if(c=='(')
; U9 ~: l9 R4 `1 f# S, S return '<';7 M! o, g" \; I' T2 k
else if(c==')')
3 w7 r% @8 |. w& t6 g# F/ v return '>';
$ m# |/ A% ?; Y$ Z2 P# C* n$ @$ } else 5 d, T7 G# _5 O0 d# D" r: ]
return '>';
: F- I2 j2 v( B; S: k9 d case '*':
5 e% }# \6 i: \. J/ b6 c case '/':
6 a ?' K I, Q+ }# s if(c=='+'||c=='-')
" U( O$ Q/ W4 k2 e6 N( W! s* | return '>';
, o& `4 p6 L# v: ?5 H0 H% @ else if(c=='*'||c=='/')
+ C5 Y& `8 y, c0 [; \1 ^# O8 r6 \% K, x return '>';
( ^. I: T$ c+ N else if(c=='(')
: |, K! T5 u$ c, E' i return '<';& J* H' m) T9 x* b( P, X
else if(c==')'); K( S# c6 I# G. _ g, C
return '>';
7 ~& k/ [- A3 o' X: r7 ]) M else. T- q, k! c$ M. d" D
return '>';
F, s5 I/ W+ H5 R$ L* j: o) j7 |& ` case '(':" g$ ~# P- P' [' q+ \6 Q
if(c=='+'||c=='-')
& q, @! P9 {7 X return '<';! q) j+ p# p ~& f2 A" M: Z" e
else if(c=='*'||c=='/')
9 `0 t+ P: G w. K# s0 D: Z return '<';& I( l V. A" ^7 P7 y
else if(c=='(')
7 Y( M2 V+ K, }0 j* v return '<';1 q; X1 Y9 l6 e7 l$ W0 t
else if(c==')'). R6 \/ M3 ^& N6 ]1 n0 X6 S5 Y7 I
return '=';5 E$ x& c' p j, c8 Z* S' L9 u6 H
else
8 Z2 f/ X6 \! a* I2 @! S1 T0 @: p return 'E';" f7 T2 x& B1 a* O; N
case ')':7 K2 L' e- R$ `0 ?; k
if(c=='+'||c=='-')
/ i: ?1 L( d6 W return '>';
7 b) n3 W3 j V else if(c=='*'||c=='/')
& z4 W1 m1 M5 y1 |1 T& V return '>';
# l4 {8 R6 D) f u; q4 z else if(c=='(')
$ V; G: z! i7 ]3 l) h8 @ return 'E';. U7 f/ c% M+ t" x4 f
else if(c==')'). `+ h. j. Y, |4 u& P) A# J- R
return '>';
. k& f' W, C/ l) A. F' _ else+ R3 b) [+ u$ _0 E
return '>';
2 w+ C. |# j! q1 b: g case '#':3 Y5 P3 Q- A& h5 ]7 z X/ O
if(c=='+'||c=='-')
) g% J8 _- t% R0 t8 L9 C# X return '<';1 f5 z. D$ a0 d! P" |! s/ }1 ~
else if(c=='*'||c=='/')( o/ V. ^; G: k0 L. Z
return '<';- W4 a. T! L- a9 S$ q. e
else if(c=='(')
6 v; R; n ^+ R4 a% e8 ?( j return '<';
1 e: C) S" b: ~* p% M; ^; R else if(c==')')
; a% F; w2 r5 A$ o6 z N return 'E';$ s# N4 f7 K; U
else
& g V6 I; |3 d# D( d, A b return '=';
; a' Q( v8 T: |/ r0 P4 q4 Q, V default:
6 B2 s1 c" l2 n* M1 [. ~ break;6 J) W' e ~/ c8 d4 N. l5 \! x' G
}9 W0 _, l5 W* F i# U& G. @) B- A
return 0;
$ ]4 u: f m/ h4 j9 |" L% h' S- O}$ ?5 a6 O( O0 M: `$ J3 z# ~! [+ a
0 K# Y0 A" d8 c. @: D- S2 @6 ~
int isOpr(char c)
% {5 e- s6 L8 Q3 v' m; U4 e{& M8 U* J+ q& y
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='). ^( V6 ?0 _* W, D
return 0;
* T; V4 a" f2 J% {* ]5 G else
5 y$ S$ k6 Z! e- w return 1;+ K! F: s/ I7 W# H U7 ^4 |
}
W3 [) @6 [7 |& b1 B: e& i4 b' C; i9 ]5 c# I
float operate(float x, char opr, float y)5 z# d" n. \' s8 u# H, }
{6 _" F" p, c$ P% L6 @
float result;
2 V# e( ]8 {5 c+ c) O2 J switch (opr)
, p' V; k, t0 i) [9 O {2 n2 J% W+ ^& u$ R n
case '+': / x% h+ V. m1 Z3 z. z( Z
result = x + y;3 _3 o9 w P" O& ?
break;5 l1 Z" o2 @: k. X6 Y
case '-': $ b/ k. P& z1 _( t$ G2 G
result = x - y;$ m9 h/ h6 c' O: X$ e
break;5 a1 k" c2 C a3 L# ] q0 K
case '*':
7 o% T' |# H0 r( |3 n result = x * y;; ]# C% x& [* i& {, ^$ e# h k
break;$ i4 H# B3 F) M# ]( i+ f6 j8 q
case '/':
0 c: ~5 S% v; l {, Q if (y == 0)6 k6 V' G1 ?# A9 d
{
+ E$ S& @; E( F7 @. H1 v printf("Divided by zero!\n");
8 H. w1 u6 H8 p4 v. |( G- F return 0;% F6 Q; N9 c% m
}, N4 K+ x% t' X* p. J9 [
else
4 p/ }2 A0 D5 d7 O: z {
3 |' T5 M. ]* h0 @/ ~0 `' T9 t result = x / y;% [8 q- ^5 |0 x; w. W, |! U
break;
" z8 Q g3 ~* Z/ g( J, G0 w }* |4 T0 Z1 h2 T" \3 v" `, h
default:
/ }" B2 W8 K \( G printf("Bad Input.\n");
' r$ V6 [2 p, ~6 U5 N, J/ F0 C return 0;
0 T' }1 E# }) G; \/ N+ K& R }
0 b: [/ Q7 X/ _- l6 }2 } return result;+ N, O7 A: F$ a1 j) A7 F; @* w
} + @% I* _3 a3 C9 s2 }
}' U5 o, J0 E% F( j" a, [float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/" f7 r/ V7 c! @# V
{# V2 [3 B, Y2 M# r
Stack optr,opnd;
7 H1 y# t2 e$ Q4 b2 k( `9 ], | struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;7 A& U; p) ~' k/ D- z% @7 Z
char c;
) r: @2 s" U2 y& A char buf[16];- F7 C" d2 v' `6 R
int i=0;
1 m# U8 I( d8 W# M0 h" ~
! U6 ]+ i7 s' | `$ S InitStack(optr); /*用于寄存运算符*/+ l+ G/ E& I0 V
InitStack(opnd); /*用于寄存操作数和计算结果*/! Z; r% o. G! F# y$ U. W; p7 y
memset(buf,0,sizeof(buf));
$ g" T+ a, L- ^+ _# B2 z7 v( l $ N, o. q- y- t# [- ?" W ?
printf("Enter your expression:");
3 z& a' p- q' R' y. P9 B( r D
0 Q0 s/ Q; [0 K* A" f7 g opr_in.ch='#';
* O) w7 E: H" y. F Push(optr,opr_in); /*'#'入栈*/' w& U# {% @# p& q& p
GetTop(optr,opr_top);
2 u) b1 K' O, \; r5 m3 r c=getchar();4 q7 o, Y9 e7 i5 ^
while(c!='='||opr_top.ch!='#')
3 j+ ~ {3 p+ ~3 q# W" p3 d$ w {2 d' T7 p) k/ o9 s
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
) a5 t6 h, l9 i" ~8 E- i0 ~) e {& f- j! @( f0 r, i: }; o
buf=c;
1 |; |5 O8 U+ l8 K' t2 r; t! L8 i i++;
' V; J) @6 H* ~) ^# P6 p3 G% J c=getchar(); f3 Y# j1 q* j6 P+ `& h
}1 x/ U# C7 ^6 o b% L! |/ m; r9 `
else /*是运算符*/
3 D1 r2 D8 J- p4 U# g+ L# y0 s {
7 Y/ r0 R2 d4 l; l; \ buf='\0';
$ T0 b2 q+ o8 Q" N" e4 s7 S! `4 H if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
8 h, x3 H5 m& p& k( t {
' j" o/ P I# q5 V+ } opn_in.data=(float)atof(buf); U7 S% x8 t) B; H- F; u2 {0 p- G
Push(opnd,opn_in);( M$ q) Q3 @) F. s) M0 e
printf("opnd入栈:[%f]\n",opn_in.data);
% Z( l. U6 z$ q' z# E i=0;
" v# f- I9 O9 ~* M3 U" b8 B) K$ p memset(buf,0,sizeof(buf));% D7 |. U& M; h% s9 Y5 k
}
( X3 X( ^$ R3 M opr_in.ch=c;! y) _8 o0 A- z# {% h
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/4 f. C5 A" ]0 c% s8 S# x, L6 W. T
{! a+ `( U) V( n1 }2 d8 L4 s; X
case '<': /*优先级小于栈顶结点,则运算符入栈*/
2 ~ S, a: h4 g4 x8 t$ q Push(optr,opr_in);8 ~% \% a( B) \
printf("optr入栈:[%c]\n",opr_in.ch);
, W4 @+ A" V! w1 G" H/ r% b. {+ w6 U, ^ c=getchar();
. n# @& a, m4 ?/ [" `& E r0 B break;. Y/ d- B5 q% ~2 ?' `
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
; c/ R- W; r5 x; t0 P) U* G Pop(optr,e);
0 t9 O3 h' e; M: T8 b& c printf("optr出栈:去掉括号\n");
3 F2 N' b4 {7 s( B b c=getchar();; b) k/ ~+ t' C+ {5 S4 O5 I: g9 O
break;! f! x! |- {. o& ]5 h! b6 _
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
. W' f7 `* ` H, V9 g C Pop(optr,opr_t);+ I* P$ W" d& U" S& v
printf("optr出栈:[%c]\n",opr_t.ch);7 ^. N T' `- ~6 k
if(Pop(opnd,b)<0)% v m! O+ ~' N( ]
{6 @+ r: _ T! K6 `1 j" w
printf("Bad Input!\n");# W- g* l2 x9 }3 {" I' J/ L8 v
fflush(stdin);6 l$ x2 Z3 J) `5 _" A
return -1;
8 D9 l+ c; P8 u; x }
- u. _& a4 Y# d( l* K printf("opnd出栈:[%f]\n",b.data);* G# g- W/ Z" V" p" h
if(Pop(opnd,a)<0)
5 Q% j+ B* i. s! A6 p {1 P8 q& Q. W. q
printf("Bad Input!\n");) M' { S% H6 `* B
fflush(stdin);
6 Q" c# L; j7 x9 F! l return -1;4 ~9 I5 E8 Y" X$ i1 o& v
}8 u$ n- S8 k" T: U' z M
printf("opnd出栈:[%f]\n",a.data);1 H+ F* W U% H; v
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
4 @5 K/ |* k: n- M Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
& D$ Z6 {7 A/ j2 @6 j" [ printf("结果入栈:[%f]\n",opn_tmp.data);
G: h: Y, A( x break;
& W) u. e' |" \! j. H. q8 R/ E }
: P- ?& V5 u3 ?) c+ k }
Z( V4 ~/ L7 K9 J; Y GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
. X$ _, _/ z% K" p G3 t. d }
2 U; P, @( R7 o; u d# f# d0 w GetTop(opnd,opn_tmp);
3 b3 E7 d! u. M; O DestroyStack(optr);: f9 L3 W4 M& h
DestroyStack(opnd);
4 l5 @9 T7 U" `; q+ v3 U% k6 v; r return opn_tmp.data;
. q3 q6 L. c0 M& i2 P& n C}
$ o3 |+ E7 W* E6 H, K& l2 A4 d; i# s. t8 d5 ~2 S' k h
char *killzero(char *res,float result)2 t4 Q& l" m2 S4 y
{) v8 t" J' z1 ~/ t8 {+ e
int i;
/ \% J" h1 z) Y4 a/ o( K" q. G+ s. e5 x
sprintf(res,"%f",result);2 H8 G) v, \) y, I! x3 i/ d0 W
i=(int)strlen(res)-1;
$ a1 s% A# A) A, ]9 f3 `6 l while(i&&res=='0')
7 u, n O3 D9 {. j {8 I+ k0 _' P) ~6 j7 V% C3 k
res='\0';6 o8 H1 R4 |) B4 l. W6 M
i--;* N/ z4 d V* i! k. h+ A
}8 t& D5 i) Z/ c
if(res=='.')
& }) g. L( `/ ]! z0 ^4 y ~ res='\0';, F7 ^. D7 O- h4 U
return res;
2 s6 ^# x1 k; R1 D+ L}
6 `& y, T6 v3 @4 e2 [% }5 @- ]( i* j- V e: f2 Z* N/ F" R
int main()
/ \6 h4 U5 S' ^$ c5 w5 n- H/ m{
0 P' e# r/ ?, P7 K" Y8 P char ch;' a: x9 D- m! h0 W$ |$ i8 Y
char res[64];) a3 s7 [3 J5 y6 ]2 T( W# g
float result; Q4 l5 k$ A8 \4 [
while(1)
3 D# ~7 T+ O( V# D {
4 y. f( i4 G$ `7 v2 `, y: j# G, Z& F result=compute();5 i4 Z d5 W& D8 m; x2 l, T
printf("\nThe result is:%s\n",killzero(res,result));
$ ?* F. J2 D! J/ o" B3 \" ^; A printf("Do you want to continue(y/n)?:") ;
' b7 P( T6 ~! H" G7 _4 F ch=getch();$ ]9 }, H8 U1 }2 p: U" b& [
putchar(ch);8 a( m0 H. C9 }! @; h
if(ch=='n'||ch=='N')
* G" ^# W& D& M: S. D6 X break;) W9 K* x* @2 M; N' X1 N
else
) U. ~. E& I; Q4 E( \9 m system("cls");7 l. L, C5 d( ~8 E7 _8 X8 c6 [4 `
}
: X6 L, [. s/ W- L, B% u/ J+ x return 0;
; S$ y; h! z, {* t2 H9 a}1 m# g2 x" \' ?% y
) o/ P9 ^' d. Y+ L5 {: V% E% C9 S$ Y( m
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|