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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.* `& ]4 c+ L' V+ w8 x K5 S. ~
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=+ }% [4 O' G$ {' Z
/**************表达式计算器************/) f' j2 X" L! O' \
#include <stdio.h>6 S/ P; A( ]. ?% h
#include <stdlib.h>6 T n5 Y/ c) Q+ M, Q$ N b
#include <string.h>
" D1 n1 m3 a$ Y/ ?9 s#include <conio.h>
$ s$ v# D' ?: U: B( {4 f$ h/ z" c#include <malloc.h>0 f4 X0 W$ c0 y: Z
# o: t E9 ~- d' O3 L8 F#define STACK_SIZE 100, F6 }0 j Z( }: V5 m* M+ q9 _
#define APPEND_SIZE 10/ F5 j4 u& f8 }* g) e, g
$ h: R* O+ k- estruct SNode{
+ I9 z p8 p; b6 ? float data; /*存放操作数或者计算结果*/
$ X# A8 Y' z w2 G# Y0 b- I char ch; /*存放运算符*/- L; q/ @" f6 H& P' F1 F! P. m0 J
};
4 S) ?; u! k2 x$ B% f1 S
; W+ B- Y7 z2 D7 R, d Estruct Stack{' O- v- q7 L' Y0 k( b$ s+ \; [; V
SNode *top;
/ t' P c7 [* M SNode *base;
* i* v4 N( B6 q; e int size;* V# z/ N- {* d
};
% p+ \# m4 p8 P* o
" c, I: O% V- N0 L- f/*栈操作函数*/9 T8 `' s* X4 H0 m& k
int InitStack(Stack &S); /*创建栈*/
! _6 X% ~/ H( z9 \0 w4 P0 G* Bint DestroyStack(Stack &S); /*销毁栈*/
8 {! H* d C$ k- c5 dint ClearStack(Stack &S); /*清空栈*/8 o0 J4 Z4 R9 C( e3 E$ \
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
9 R& S8 u) g8 d4 O3 n+ Uint Push(Stack &S,SNode e); /*将结点e压入栈*/ j( B% i4 k1 s) ` M* R
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
6 Z8 A" K% p: D- \4 ]1 n9 I
& q6 s) U, @* }. R( x% \/*表达式计算器相关函数*/
) S; n7 F' W8 ~7 {0 gchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
) H" x, O+ O$ J( H$ c2 L% |: ~int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
3 i2 C, U0 V, e5 G2 Ffloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
! K' i% }% [8 {) P; wfloat compute(); /*表达式结算器主函数*/
2 R" K8 c% t7 T$ ]9 p8 N4 Lchar *killzero(float result); /*去掉结果后面的0*/ " p$ z- y2 @; k$ X; Q
" {7 [+ G1 s o: c; D, I
int InitStack(Stack &S)0 f9 l# m$ p. B% {' o
{% A+ Q1 y+ l$ `! {# [
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
+ d3 Y. S; W7 e- C% {9 o if(S.base==NULL)
1 ~3 q1 M6 B# w' P {) G9 [6 c) M1 K' L$ j3 S# Y& S
printf("动态分配内存失败!");
) n& U5 \2 x, H' S4 e return -1;% `2 z3 N% c6 N) b# q, L) k
}; U+ A; P; N& R/ Q! B
S.top=S.base;
2 S6 G+ p; Z" B S.size=STACK_SIZE;5 u9 J# ?7 ]' o- t# S7 l: ]: X
return 0;
! x. @0 m+ ]# f/ M, u}; [6 t! j5 s! m' R6 S2 a- `$ h; h
- r4 Q! E" D6 |3 R4 u; z! H
int DestroyStack(Stack &S)* k% o$ a& B- U( N" g
{
( Z5 {2 j5 w, {" ]$ C free(S.base);1 g; v4 b5 ]* O: v! V" _2 j/ Z- Y
return 0;7 U# t i8 d) Q2 T6 [
}7 u; M( D- w" g5 ]' ?6 B6 i
8 t/ Z* w7 i$ G" j4 M0 e9 z
int ClearStack(Stack &S)
1 I# ~7 s, M( V, }4 R- W, R* G{7 n' G4 l- a. R! w
S.top=S.base;
6 Q0 y2 Q" W" @3 e return 0;, l* {% Y1 G2 v. p8 a& }8 S3 ~; o6 Q& ]
}
- M2 |9 {( J, M& X$ E7 v
5 U. C8 n0 Q8 F) p# D, ^int GetTop(Stack S,SNode &e): j' y6 y, o5 k
{
+ k7 {. `2 J r9 M' }) ^ if(S.top==S.base)
' a- o- P8 A* U" y( ^3 K' i {
* ?+ I7 }4 M% I7 @7 { printf("栈以为空!");. D. V3 ]! p' p' w) Q6 O; }0 h
return -1;7 }* \) b* O# K& W$ w, b& {+ H
} [8 ~+ v7 u# K, t
e=*(S.top-1);
% L* M$ |+ X/ d return 0;
* }- T' H. v9 e7 ]* P}) z' t( ]" \# {, D
! v) A1 ~4 _; T" B
int Push(Stack &S,SNode e)8 D7 T! y: a$ I5 j. h( ?
{
0 F* M W: v) E; p/ U if(S.top-S.base>=S.size)5 ]+ {& {8 e( m& R. {0 G2 @
{7 H K, ?: |: L
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));$ ]$ U! `4 g3 n- B( E
if(S.base==NULL)0 V4 G2 J7 ?5 r( ~1 ^; e$ t n
{
# s" `4 T" ?8 H9 ^4 H7 q printf("动态分配内存失败!");3 m# ^( `$ [5 u! k8 q2 k- L
return -1;# ?" w" W" l3 w5 `0 y6 k% a
}
$ ]9 W- n+ c2 G S.top=S.base+S.size;% L2 X8 r: b. A' ^& O6 C! E
S.size+=APPEND_SIZE;1 h4 U% l+ c5 J" s! T1 q; n7 n
}$ h$ l! w/ l# \
*S.top=e;% D# `% f: ?9 r
S.top++;
- y9 I0 ~6 e/ e1 r9 q# U return 0;
+ l: g" W6 P4 u}
9 V3 x0 ~( ~# ?' U2 [: ?4 H
6 I) Q$ r# f$ `# |int Pop(Stack &S,SNode &e)
( R4 l7 C, ? L, O( T{
! ?* l/ g( ~# r O if(S.top==S.base)/ X! }6 a/ V+ V+ p, S
{/ y6 R) ^; b/ e* T
printf("栈为空!");& n) c5 ~# D5 G% y" A/ _
return -1;
, G X$ w5 {! o2 H2 d* { }
1 @4 O* U7 [( C3 y* ~; O* A e=*(S.top-1);1 L( f, u1 A0 S/ t
S.top--;
( ]* d( ]6 y$ r% E1 e8 Z2 }+ A return 0;
9 U! O% p1 S3 Y) y+ M0 n}5 t4 _+ X( E; T& q+ t0 f* O
, j. [$ E, E2 U3 a* }5 P" {char get_precede(char s,char c)1 b5 B* O7 J. ^% g! V4 J
{
* ]* x& k/ s$ X! J switch(s)6 F( Z" u9 r4 } b1 C
{
0 a2 E" n- I# v- u9 T6 Z9 L case '+':
0 j M1 i7 K# F) K6 L case '-':! y! R- Y! R% ^( w
if(c=='+'||c=='-')
) z& |$ {5 U. Z% v0 m- q' Y return '>';
& w* R0 a9 F9 x/ \3 O) _: o else if(c=='*'||c=='/')
% K: K. T+ z2 Z( r4 K return '<';1 r P4 [/ U3 s+ K" P
else if(c=='(')
" G1 }' D/ H" U return '<';
% C# n y+ P3 z else if(c==')')4 h$ A' B: b0 |0 w1 n b+ z
return '>';
4 [! m! k$ M. H$ ?( c0 z* U else 7 I/ G* B: f( u1 a2 b
return '>';
# O4 J; i; D: z3 x case '*':
# p; \2 C' m% G' M4 [4 L6 J8 g+ N. n& ? case '/':' k1 ^7 ~% K- h$ x; u
if(c=='+'||c=='-')6 w4 d7 b/ j. v5 X
return '>'; B; d& B; ~1 I+ I
else if(c=='*'||c=='/')4 Y8 s9 l, X0 O: M0 E- q2 s* V
return '>';$ D& d* _3 }; p+ d
else if(c=='(')8 k8 g( W4 s& z0 B5 X" `: O
return '<';
' Z! {: s9 Z6 e2 k+ j* V X! D- T else if(c==')')
- ^( ]6 O" U- \9 |, _ return '>';
2 V9 F( l. C" t. a0 e else+ m; `- F6 f$ ]
return '>';( ~" K, M+ P# K6 g1 B& _
case '(':5 E! } N, b2 s9 P' \* a
if(c=='+'||c=='-'). F; K/ I/ V. }0 t
return '<';
2 L+ H2 P6 B. p7 _0 z7 J6 c else if(c=='*'||c=='/')0 P% R# o7 y( p' v- I+ E9 x! U
return '<';
1 u# G$ {$ n9 h8 G2 d2 }# W else if(c=='(')9 H, N4 o; s8 k
return '<';3 G7 T, T5 M/ q; ^* ~7 M: n
else if(c==')')
9 a8 c- N' y# o7 _& o3 r return '=';5 k" b( C* y1 @/ L& M7 D! `' {% C
else
& } i$ W$ t2 B9 P/ ?, r return 'E';( Q6 m; T4 s& A; r- R
case ')':
% @8 o: |4 N, o V if(c=='+'||c=='-')& h' x# h7 Q+ p6 ~1 u/ _8 E. E
return '>';1 L3 ^: W4 r4 {8 I$ }2 Q( M
else if(c=='*'||c=='/')
, K. [; M& P& H# G return '>';
" a2 e- ~$ Y$ g else if(c=='(')
3 V! }8 l& R& o( M% u2 { return 'E';% p8 K0 Z: ^3 g4 b
else if(c==')')
" `2 f- P2 k) a8 Z+ A return '>';
! h) X- Q( i4 R& J! c6 `% X0 j) M else' A2 W( C. W3 s$ o/ U
return '>';! \8 q+ ^* v7 Q2 ~8 u: c9 T( v5 w
case '#':8 Q+ p) e+ N( j+ w* e$ a
if(c=='+'||c=='-')0 c- t& t6 j% B# Q
return '<';
2 H3 \( Z M% t else if(c=='*'||c=='/')
0 h) }' j: B- e0 M return '<';) T/ f5 G: |; J0 @
else if(c=='(')
# H0 Q' o9 t. z return '<';) Z) v. V3 H+ P: \9 U% Z. }& y
else if(c==')')
9 ]& S8 `* Z! W: W% j return 'E';% Z# f4 {2 A& y0 y8 U# A! p+ T
else
- y6 A+ ~. U4 [0 G; O/ r return '=';- F1 V# f! T% W
default:: \: V7 V9 l {; d; v9 M5 V- g
break;
' H1 L) Y9 f, v3 S0 E- W }
8 }+ W( k' ?' B. A/ x8 y return 0; x5 Z7 ^1 B7 G9 ^
}
6 F2 L3 O, B F, y
- t7 T9 i* T" S6 ]int isOpr(char c)
8 A/ v% X! R- t, z" ]( y8 k{
! ~6 {2 d0 T0 j" L* W, ^ if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')# r8 o& G9 Q# k9 \. I) C
return 0;/ r' D7 [" T+ b& F x: B
else % s5 P) |% I# D! V9 B8 m
return 1;; Z \$ I z& x) C
}/ r+ N7 w( O! B. L% P: X
$ i5 K# V0 E9 M& g
float operate(float x, char opr, float y)! f6 e: ?* q# p: i
{
1 Q" K' y0 g0 Q" V2 T# r float result;5 \, m: N* S3 B* T+ p9 w1 `3 s
switch (opr)' U2 p5 O" n3 t; y9 X1 I6 g( |
{. a( |, o0 a* @( j
case '+':
. E+ k* ]' i: _5 T. F3 \' t+ W result = x + y;
! K$ ?* f- L5 @* m. z( k; k break;+ C& T8 n1 W( A0 r6 e! C! q
case '-': 4 J! M! \" M; B
result = x - y;( {5 ?/ n' i0 }* Y% }0 z
break;
0 P# ^9 k3 c7 y! `1 _ case '*': & p- S+ N# b8 ~) J$ B& ^
result = x * y;, p4 E5 H: w E7 i& W1 n
break;$ g& t- O! k! E; i5 q$ J ~( `
case '/': / S F1 G6 s; K, [
if (y == 0)
+ v/ p+ P, L( v9 V! i: Z2 A# o! U {
' N2 b& P/ B! ?* |/ w6 T printf("Divided by zero!\n");
2 n2 A8 f4 I5 V9 _ return 0;0 w) Q; O ]9 h8 u( h" g! u
}, {: \) G/ g+ x% D b+ |& e
else
) d3 J9 k# p1 U. q" A! M: ^: i {: c. `* p8 _; G1 O
result = x / y;1 p; u, |3 F0 L6 w
break;6 e6 K( w, Y* R1 X
}
. G& ]- {; |1 B6 _ M' C default:
8 ? b5 g& z$ z1 `1 H) g) A% }: M printf("Bad Input.\n"); ' Q9 h& X" U& F
return 0;% ?! w' ^* u7 ^
}) K. o* _% F! e
return result;# I' L; I5 N# N& V7 Q s. ^+ t
}
; d9 T* j& o; ^" P
. S+ b1 X s$ I. Rfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/$ B+ V" ?* ?( r" J3 ?
{. `& }- j, p( g6 @* h
Stack optr,opnd;4 l- b j) M3 f4 ]9 V/ A
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;$ x9 e" }* Q6 e) n, m' w: G
char c;' R* N1 O: Z- Y: A
char buf[16];
7 i& g" ~, w/ k- L" X" @ int i=0;* Z( l) W6 ~/ ?
# E3 ]" D% Y) |! I/ n3 ~
InitStack(optr); /*用于寄存运算符*/
' @9 V4 L5 {9 D" A! e InitStack(opnd); /*用于寄存操作数和计算结果*/+ y/ b% m" l0 O
memset(buf,0,sizeof(buf));
2 T5 R- `8 l8 A3 r1 s p
* ?' T7 f6 i+ l printf("Enter your expression:");: V4 h j. s8 _* [' P( F
/ Z0 F2 s* x7 \, w4 B% i! e opr_in.ch='#';
/ n' j: {/ l7 M6 s! Q Push(optr,opr_in); /*'#'入栈*/
+ p5 j2 Z7 e+ U6 Y N GetTop(optr,opr_top);5 ]' t. P0 E& _* d% T
c=getchar();( f6 I# V2 ]( T' x. u
while(c!='='||opr_top.ch!='#')
M6 t0 s$ d7 S9 ~7 h% O T1 e+ H {- q- ], v/ v; ]- m+ |: [( n
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/: i$ L' Q' k2 g
{/ U2 o8 X9 {2 V R
buf=c;
0 m% n0 \7 {) T1 B% ?& W. s i++;
8 i+ W% a* `9 B. G. b+ E" s2 g! L( {+ Y c=getchar();) \( \- c! y6 {8 o2 g/ c) U- _* a
}
( ?- [+ A2 N( E5 q else /*是运算符*/1 H2 [8 _4 h7 K" M) z- Q: \
{. f+ c* i3 Y2 l# T
buf='\0';7 c/ l$ H# x; z1 L9 f
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
; {" a" P/ B( s2 @8 S6 a {1 ?$ l, Y/ |- T* A4 y) ~' `8 P
opn_in.data=(float)atof(buf);
* H7 M$ p/ q4 E4 l Push(opnd,opn_in);5 J6 n ^, p# g+ N& e" q! o
printf("opnd入栈:[%f]\n",opn_in.data);
: @3 o; b% R& k+ T5 E! M N! D i=0;. p0 l! F/ D( Q. x9 x9 J% ~
memset(buf,0,sizeof(buf));' [1 A, F: [8 \4 m7 E
}
+ T7 S. I% f8 k7 c7 p5 Z6 m: c2 J, p opr_in.ch=c;2 ~8 U8 `. @8 _1 Z6 S6 q, C" x
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
$ u2 m; Y4 T) J& j! g% a8 W4 @( J {
; B D: [. i) D( F' i, n* b1 ` case '<': /*优先级小于栈顶结点,则运算符入栈*/
4 R5 D/ T9 U# B2 V7 B6 Y Push(optr,opr_in);
: I M4 ~" y& s1 W printf("optr入栈:[%c]\n",opr_in.ch);
6 ~8 H: i' w& W0 z5 Y& W c=getchar();
) @ g" ^9 q- P' N1 W) f" t+ H break;
+ }7 U) q# |" V( n( R7 b8 v case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
/ g" K# \# u7 X1 K Pop(optr,e);
. U# T$ A P* [" g( m7 W printf("optr出栈:去掉括号\n");
, \: z H. w3 b- X" N. O& ^ c=getchar();
- U/ o/ B3 i7 X break;# y+ }' \ d. W" ^
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/- x4 d2 n1 J o( O. E! d$ ?0 t. p
Pop(optr,opr_t);% }& D/ h- l& T0 J7 K1 \
printf("optr出栈:[%c]\n",opr_t.ch);
! ^# l: n' a" L' W: S/ Q: d if(Pop(opnd,b)<0)
* u! k) {. ~8 p7 e4 r {; j. V: H, J, ?; p# z2 s
printf("Bad Input!\n");
; K4 a e6 P3 C% H; t fflush(stdin);" H) r# l% J0 }6 m, x4 G" Y+ G
return -1;6 r8 D2 {2 o W9 r* o; I, I
}4 W4 r. Y5 D r, j9 c
printf("opnd出栈:[%f]\n",b.data);: `" P5 u2 x9 |3 L0 |6 |$ U; p1 k+ r7 @
if(Pop(opnd,a)<0)! N+ \2 W D# T
{9 {6 `" e# b, J. c/ l0 h
printf("Bad Input!\n");1 W9 j% Z' L+ D* e- W% r; D1 Z+ Y
fflush(stdin);* v3 O4 ]2 r: p0 e7 T* B
return -1;
& m* s: F: ~1 t, @8 B }' G& o9 L) r' M; m7 \& G/ U9 |
printf("opnd出栈:[%f]\n",a.data);2 i+ `( i1 L9 y% T
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
* Y. `& T' ]6 U Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
) A* Y& O6 u3 C. U g3 g+ _$ A+ c printf("结果入栈:[%f]\n",opn_tmp.data);0 w( ~7 |: B3 z8 v( k
break;) f2 x8 a: e* z" }' N( V" M7 y
}
/ g- P% J% u0 Y' u }# J/ d: y r7 t
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 8 |5 t$ {" b9 i% ?8 F; a& U
}; k' F) i% a2 [% I4 f9 w' b
GetTop(opnd,opn_tmp);, F4 U; |4 `. v+ U! P( ^ D2 Q0 b
DestroyStack(optr);
* C4 A4 j: E" F. E DestroyStack(opnd);
) V7 Z0 h% V( Q# v+ J( P$ c return opn_tmp.data;6 R8 z$ i" q* j- C; g, O
}" y4 g/ q \ u! O9 U# T
% m" }; D5 k5 Pchar *killzero(char *res,float result)6 o D$ }% s. r# s, J2 Q6 p/ f$ F2 t
{' G) j5 S+ O+ b9 d
int i;$ `; u' F( ^0 T5 }3 Q: U
8 k; j4 S8 h/ d) M+ T
sprintf(res,"%f",result);$ Q- `+ Z6 J+ C- b) Y3 u
i=(int)strlen(res)-1;9 \! A' N* h& {
while(i&&res=='0')
: k# C S8 g7 ^/ h) L {
7 t9 D3 x4 v$ I( D- u res='\0';# K0 U7 M" C) ^! @5 e1 J9 Z9 [
i--;
8 ?( b' s; r! ~. y7 k6 w }
; z1 m* k; w, C2 M if(res=='.')
; x9 v! m4 C$ }5 R res='\0';
1 k ^# e/ v3 R return res;
, k- k& o; ~9 r/ |6 t: D( g}
8 H! `# g& m2 r, j
0 k% i" S/ |( \) E3 [% K5 Mint main()& `. {! d: o/ W8 @# _
{
" T k) v' p6 b; P) P7 K, t char ch;
% {* a3 V$ a5 q4 r' b( S+ t char res[64];" |/ a) M" r3 J7 Z( f
float result;
2 B6 v! ~3 a2 J% X5 t* @ while(1)
6 z, V# @( \! X* T% ? {
! a# S+ F5 }2 z% a F! G# N. \+ ~ result=compute();! x% k8 I4 c, z, T; Y
printf("\nThe result is:%s\n",killzero(res,result));- D" A, R3 M; ^/ P( Q
printf("Do you want to continue(y/n)?:") ;
) {( Q3 O8 D1 ? ch=getch();- J% B. L# f' }# a2 _0 W8 X* n# }# I# d
putchar(ch);
+ M, M) W' B3 x if(ch=='n'||ch=='N')
7 j/ ]" v, {5 L: K' C break;) b4 z; U! _+ [! H ^5 P
else% f" R, Y* y$ M% U4 w" S5 X# U
system("cls");' R* _9 r u6 J( }6 s/ |
}/ K/ X; S: m7 L' O% M
return 0;
0 M. ?* l7 o- w7 z0 `; r5 N: H}
, [1 k+ A2 `) d6 \, a y0 o) }# p+ Y2 S
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|