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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.9 C' F7 `* d4 W0 F7 p
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=+ z* ?8 r" n) D% R- J
/**************表达式计算器************/
9 m. }' d1 F, G Q1 s% T- y3 W#include <stdio.h># Q' q- [# c6 Y0 ^# C {
#include <stdlib.h>
4 E+ l' H/ H& |, s#include <string.h>9 U# \- [+ R% [) o4 V9 S; v& `- F
#include <conio.h>
& a/ q. f4 p7 Z0 G C) ^- F, t#include <malloc.h>
/ x. h2 K4 ` r" z2 ], f b9 \4 ]- T6 g9 h
#define STACK_SIZE 1002 Q2 e- L7 I2 z x5 u
#define APPEND_SIZE 10
8 U- Z& X* q% }3 n- u) V6 A) g( Q# _: L
struct SNode{ T+ z' X1 _4 g. J9 r8 I) f: \
float data; /*存放操作数或者计算结果*/: |6 t+ W- ?/ o7 {2 j8 Z+ ?
char ch; /*存放运算符*/. c% P [ s+ C5 H5 z
};6 a4 g' `% v# i% W
n3 K4 w9 e9 R# a0 F
struct Stack{8 \0 {7 W7 D6 N
SNode *top;& ]( _- v5 X5 H/ ~" @/ Q& P. C
SNode *base;: F9 S! u4 T6 {" B( v0 y+ [
int size;% G* k! R( y% C0 C# i
};( f& K$ p9 i1 I- ]" s! n; R
# Z1 k6 q1 \7 R t+ T3 p2 {, o. J, a9 Q7 R/*栈操作函数*/6 \% S: n1 Z* c) Z' h( r, K) d5 v$ K# k
int InitStack(Stack &S); /*创建栈*/3 A. F$ n+ ?/ z# F5 L
int DestroyStack(Stack &S); /*销毁栈*/
4 O8 p" c! u2 F5 U& Y# rint ClearStack(Stack &S); /*清空栈*/- X5 x6 ?( |' W3 i: m, C
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/0 Q) n ~& S! z. _
int Push(Stack &S,SNode e); /*将结点e压入栈*/' {8 i6 u5 t9 O0 K2 a
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
1 q( ]3 n8 W2 I7 |9 j( F! n8 I2 Z7 }* y( }6 R1 R
/*表达式计算器相关函数*/
0 x* x) D. s& @' u$ M6 Vchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
9 _! |8 T, o; v* M3 oint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
* q) ^( _" z+ Nfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
# D% G) A7 }+ t1 j0 ^9 q# afloat compute(); /*表达式结算器主函数*/# Z+ L4 i; Z, a, s) s4 O
char *killzero(float result); /*去掉结果后面的0*/ 7 A1 Q) z0 x% K* j% q9 E
E( q* W- S; U' x+ L0 S* |
int InitStack(Stack &S)0 G. v; ?* z' `& |
{
8 e# x$ A* V% A! t0 h) A+ g8 e S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));& ?* B7 U- H9 x( s: W3 }& B. J, S
if(S.base==NULL)" s; d# W+ ~7 e" @7 \( X
{) |7 v2 H* e1 F: k3 V" H
printf("动态分配内存失败!");
- f' |4 u: E4 g return -1;4 ?+ h! V1 l9 D0 b
}
/ p" n. Q6 ~) \% A) b4 i9 W9 R. n S.top=S.base;
6 W* ]: a- t2 _% q$ V3 L S.size=STACK_SIZE;
+ p/ R5 d8 Y* [" {# s return 0;: I* O' |+ {3 R9 \- G( j
}
- [" \0 Q6 F; f9 R5 r- l
* [* `+ S O- `+ |9 ~) Jint DestroyStack(Stack &S)$ i$ g5 }. {) ]% `
{
8 ]+ s# p: w/ x1 |2 f/ u' A free(S.base);/ c9 F( o+ i" R
return 0;
b3 E6 z3 {' x. Y6 L1 p}' i% Y* u ^; v4 o
6 f% ]" S7 U& f8 C3 F p! n
int ClearStack(Stack &S)# _5 l3 u( ~: p! C
{" |3 D- a* O# a- {/ F
S.top=S.base;
1 W2 q* Q& `9 B* z/ F return 0;
5 ?! x$ D; R# s}5 |8 i. n' |$ C* w: H
- `, S% R) E3 A3 E
int GetTop(Stack S,SNode &e)5 H6 v1 K, s! ~0 b% [
{
! Z: m3 l6 A! x& ?" A if(S.top==S.base)
; p; O# o6 G2 D0 j/ T0 @ {
1 L* A! V$ S8 ~7 A& x8 r( E printf("栈以为空!");
G- K: [4 s8 M% n return -1;
% a% U5 X' [9 A6 G; [- ` }- h W- z! f* q H( a$ D- m
e=*(S.top-1);
) O; H/ [/ q5 L9 M5 S A return 0;
+ Y5 J2 u4 Z9 b8 N! r8 M9 v3 q* a}/ @- n( q* B9 v" @. j' I l& N
" _ ?/ z; j" Yint Push(Stack &S,SNode e)) k L( x- `. S: t9 ]7 I6 X. ~
{; h4 C2 I* q9 J
if(S.top-S.base>=S.size)* b0 q% x: h5 t6 D3 m0 C" A8 j
{6 j8 N, ]* W1 s
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
9 y- t! E% R2 e9 u4 N if(S.base==NULL)
( E& }) J0 c, C7 L {
5 k' ^" E% N0 z1 x2 a2 d7 w printf("动态分配内存失败!");
, y5 m# V) f* n return -1;) [) |& @, K# R' }1 s( s9 Y9 r& r. g
}' {' H! {; G0 r+ s% ~2 ]
S.top=S.base+S.size;
6 ]1 f3 [; y& z9 N S.size+=APPEND_SIZE;8 h) N. M3 s: J. Z% v7 @
}
7 R b2 Y& i+ q *S.top=e;+ a/ P9 `3 V; ?9 r
S.top++;$ q2 q/ g$ Q* j
return 0;
4 N) W4 S- Y' }5 a}* d! T- }, U- V/ k" b7 {5 j
" `: ^ s ~* ? { z( Zint Pop(Stack &S,SNode &e)8 v6 L1 Y/ I* n( o6 J# D
{
' t8 n/ ^* i$ v* D2 G/ D if(S.top==S.base)* E& I, M ?1 K
{
6 a; A k$ x! }: d* F4 v0 C% ? printf("栈为空!");, ]* n/ |" G# s" I( W8 E: \
return -1;
. ]/ W2 b! R& N" D) d+ U }
! g& k! p" S* A! p: ]* M e=*(S.top-1);
) r& R2 @# n e6 w& f S.top--;
* o1 o' L1 n" y( N% c return 0;
" E& _) ^, S: A/ v- D3 D$ E* b}
7 ]/ Q4 H, \% H5 U' r2 S$ W$ x0 k. ~7 p6 {/ f
char get_precede(char s,char c)
% F! w- H) D. S" }{) e/ B( x. P) A8 W5 F
switch(s)
3 m* O, ]+ ?1 b1 H5 C9 O {
+ [$ o: c4 o$ E7 H! D case '+':
: |2 n# b0 e+ l- f! L; U4 @8 h" O case '-':
" r& y7 W( a# W if(c=='+'||c=='-')- G# Q5 x$ W3 y+ x8 `8 b" I6 M
return '>';
$ V# f8 d" _7 L0 Y else if(c=='*'||c=='/')& p& J3 [' ^4 z$ o
return '<';1 o; a0 D; |5 ], ]! s$ [0 c
else if(c=='(')
- k; q$ Z- @0 C% z7 r7 u return '<';3 O/ h& j+ T0 t, m2 g/ v
else if(c==')')" c* V" V; ~ |* E4 ]' T/ r* v
return '>';& s, V1 u& w2 Q2 c u% S# h
else & l0 v$ F' z( v9 Y
return '>';0 s8 [+ V8 _2 Q" V0 i
case '*':$ H/ I% |: V, ^/ @
case '/':3 w# A' _4 @1 N' z$ j& [
if(c=='+'||c=='-')
/ S: I5 W9 ^. q& F$ \+ l return '>';1 F) E" [! K5 J
else if(c=='*'||c=='/')2 G; Z; X9 r0 u+ [6 g. `* t' L
return '>';- B2 b+ T3 K& n5 M! c
else if(c=='(')
. N4 \7 v5 E: ^( N4 F return '<';$ A) u- ]. Y% Y+ r4 ]# m. H7 G- Z- t
else if(c==')')
5 V7 ^' R. ^1 S S2 Q$ T return '>';" o# A9 s5 N2 S' s6 z4 y+ d
else7 B! w$ H6 b; w, {4 N/ `* m M
return '>';, T$ b% H6 O4 }6 Y" u
case '(':
5 M* v/ M) a' f+ T4 v' H' ]! s if(c=='+'||c=='-'). D* E, {3 D2 E& k# w: I
return '<';% J$ R* B" S2 t* e+ B6 {9 s
else if(c=='*'||c=='/')( L2 g5 K$ L8 q7 |) H
return '<';
; z+ p: T X5 q0 ~8 Z3 p u) U else if(c=='(')
: J3 R2 V* t/ t+ u1 S' k" f+ ^7 T return '<';
{7 t. G" y! I3 [+ C5 G! L else if(c==')')% f6 d1 L3 j, G& F/ s
return '=';
( H- ]- [3 I4 d+ ?1 B& ] else
4 G6 N1 \1 C& Z# z. t# [, b return 'E';# _; r( w A; c; d
case ')':
+ ~4 E* f3 N# d if(c=='+'||c=='-')
" f$ f- @! F1 c1 e6 a3 P2 x return '>';
" i8 a9 ?6 F" i' v& ?. @/ {3 r6 k! h else if(c=='*'||c=='/')1 r) p) ?. A. `3 M+ H- S- {/ t7 k
return '>';
% r3 `0 z( b; }! U' K6 N else if(c=='(') {7 X2 R8 o% y+ P" _" B4 U" W
return 'E';
% P# h3 F5 g6 X; }0 m! O. ~ else if(c==')')
( \/ p4 u4 b. O5 R" [0 P return '>';- i9 g( y L, O0 o2 f
else! i( k, y; a7 Z4 ?- `) x& ?
return '>';$ c) g" h3 d4 y1 E' f1 j+ t3 b
case '#':
+ V0 p0 Z5 t# q9 R2 H' g if(c=='+'||c=='-')
% A0 G/ v( _! H) q) T, i: x return '<';# @+ e/ \3 U, V$ E x2 A" k
else if(c=='*'||c=='/')
" x' T- U2 q4 K$ l return '<';
. N9 i, s, b2 q- R& a7 g else if(c=='(')0 N. s0 d. L4 a( n- [7 O
return '<';8 e. y7 X7 g4 x2 o# u
else if(c==')')
$ ~$ ~8 s, ^- g* X7 Q0 B6 R return 'E';0 j: O1 ?& z: _. Z" z; N
else" j' `, N7 x5 z8 M0 F
return '=';
2 n w) T6 L1 Y' ^; ? default:" B5 W1 L3 Q8 o
break;& b% S8 D$ O9 x1 X4 w* M
}9 g5 z7 y* Z+ W
return 0;
/ e, k/ s$ p, C D6 c$ x, m* F}
/ u( q1 M, j w
5 l* y0 j, m$ O4 K9 q- R! fint isOpr(char c); @. ?" D* e3 R' _) Z0 w
{
9 G$ F! _/ F3 g& ~, N if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='); }* W( G/ i, Z8 u$ Y2 ]! h
return 0;5 e9 T$ I8 [5 b8 z7 S; N( C
else
9 V* x$ l9 I% R. G3 E. M return 1;
* H0 m7 ?0 J+ Z- x2 i9 U% c8 h: m}
7 u% i' q; S _# @, i8 K1 B! C- l) |* `' ~" _8 Y- _
float operate(float x, char opr, float y)
( \& C9 u& f8 L" ]{* P' L- o( H! X% G% b X9 \" n) ~3 D& L
float result;
. q X/ E# S" J, F W switch (opr)& E% \2 P$ v- z0 U) a5 }
{, m, {8 c& F$ K% I2 T0 z9 n' J
case '+': / F, b* ~, ]* A' @
result = x + y;
( M ?* j( K4 X break;
0 D/ S* J: ]+ o! i9 M case '-': / |9 \9 v# I- `4 G1 I
result = x - y;
/ H! C9 q& L* ?5 [( z( W break;
Y' H" l: n+ V: h case '*':
# u4 P2 Y! z6 @1 { result = x * y;
k( ~1 C( d4 y9 `/ b2 w break;) a5 L. o( a+ B5 T7 s
case '/': % ^' l3 K+ o _# m9 L
if (y == 0)
% D9 K4 ?3 A! w {
1 g7 w j* r# H0 ]- n4 V# l printf("Divided by zero!\n");' ^* F7 r3 Q- n3 Z/ B
return 0;2 @) f* b1 R2 D9 q
}
$ e* F* [5 o$ X0 j ~1 d; ` else
( u, Q1 g( L" V/ X( K- L* S {
1 y3 k( ~& U/ Z result = x / y;! p6 O' i; N' l8 d5 K
break;
5 h# m0 s* R7 Q) c; r6 H( X }, X6 U9 H8 n% X0 R% R; m. Z
default: & N* }! L/ q& C U) t
printf("Bad Input.\n"); 6 R: R& Z0 t" J% p% t
return 0;$ J; R# c# m. T8 ^& |; r
}# z N' q4 S: n* V: H
return result;" [" Z+ y- w+ u$ j9 ]
} 8 h V0 J3 E) c: F) o9 W4 x8 P
1 ]; F" _% S1 M9 V( P
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/. \3 {4 E7 u7 }) w8 }* j2 j7 Y
{0 i2 F# h+ Q$ g, }0 h- B- i" U/ e
Stack optr,opnd;
. ^6 E8 r- y# F2 d1 F/ X* B2 X; h. d struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;. M5 x" g5 h8 g
char c;
" t. L# J/ b. q+ G) W! n char buf[16];
9 u* }) w6 A7 T3 j" Q0 t int i=0; W- U1 H( q" l" R' [4 \4 _
, C3 g ~" n! U; }! s* Y
InitStack(optr); /*用于寄存运算符*/
2 v3 _9 z: \( K: k0 a3 e' r InitStack(opnd); /*用于寄存操作数和计算结果*/! h# ~* z# H% ]' M e, }
memset(buf,0,sizeof(buf));& u, M; T3 c% ^
& @/ m) D7 h( d printf("Enter your expression:");, Q* Q& O$ ^. o$ m
- J# G8 K N& K5 V/ J! q" f opr_in.ch='#';4 o: A# y& M: N+ A
Push(optr,opr_in); /*'#'入栈*/
! ] e+ m! G# v0 I GetTop(optr,opr_top);" N, P5 q0 \* y8 m5 }; t9 A
c=getchar();
! s" C* ?5 U t1 k+ d; A" N2 V0 v3 f while(c!='='||opr_top.ch!='#')
' i& X1 t9 Z6 N" e+ H+ r {; v$ m2 k+ a, I3 }, {9 K% \
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
+ h6 q6 c# b0 k, `# T {
" v. C1 K6 ^4 K. @4 { buf=c;
( b' G- j% l& D* P4 ?- b i++;
) k( E1 W x& v! ?/ ^ [2 F1 x c=getchar();
( D O0 v% h& }% u9 F$ q8 }; O1 Z5 q }) \; Z" J R8 X7 R- @5 B6 M- j
else /*是运算符*/% z4 B6 P/ c$ c9 T7 Q+ ~
{
) I! ~% w- Z7 [: `8 h0 Z buf='\0';5 \3 n% I. r- R9 a4 E8 |- G/ ]5 T
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
9 r* e4 z- L! r- H" u; i {, I3 G0 @( X$ w' B
opn_in.data=(float)atof(buf);. }( t6 ^& e7 `# B0 r
Push(opnd,opn_in);
3 a8 m( a. @; T8 p. ]6 i2 b printf("opnd入栈:[%f]\n",opn_in.data);
) w8 w9 m- I! p' n' Q i=0;
6 f1 {8 l8 l- H" {- e memset(buf,0,sizeof(buf));
]+ D0 H& u0 f }5 O' a2 }! E& _( h( ~) I+ F
opr_in.ch=c;, Z+ K* Y: ]# t3 e
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/, @ ]. _' D: `6 g6 Z! e
{6 _$ D- D: Q4 N; l" P
case '<': /*优先级小于栈顶结点,则运算符入栈*/9 [% z" ]) C/ L5 V
Push(optr,opr_in);
4 Z( f7 P8 T, ?1 n7 D& x1 M printf("optr入栈:[%c]\n",opr_in.ch); Y5 @8 }2 ]! a- j8 y
c=getchar();
! o9 h# D% U. c8 S break;) d" z' r5 i3 Q2 g1 a# o
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/. T% q, P. u' z
Pop(optr,e);
, T5 @. U* ]% q0 o& U printf("optr出栈:去掉括号\n");
* o( S/ U# E' g# p4 \ c=getchar();, Z: \/ x s. u: {/ \ N: C
break;
: _8 ]/ Z" k1 e9 O6 ^! K, s+ H2 o case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
0 {" c0 Q2 w# m/ h- q- K2 m Pop(optr,opr_t);9 Z& ]( l% m% l" V5 b7 h6 W
printf("optr出栈:[%c]\n",opr_t.ch);- _/ V T" n! Z1 J
if(Pop(opnd,b)<0)
" K+ c* K+ {) f' d. W1 Z1 | {( i) X ^) {' p( }
printf("Bad Input!\n");; J' w8 _$ }* b0 ^
fflush(stdin);
2 r ]5 ], n, H/ l# a return -1;) [6 _/ r, N6 m' |6 w% a
}
: F% K+ d& m/ s0 q: e% } printf("opnd出栈:[%f]\n",b.data);
4 ~3 W, S: { k- m+ g if(Pop(opnd,a)<0)
+ K, k [9 X' m3 {0 H7 ?. G$ k {/ x) J; `9 n1 k; e% G
printf("Bad Input!\n");
) s" B% {5 _. X4 w" r8 Q( Q! m& E fflush(stdin);7 ~, z$ V, p. Q3 s* z
return -1;# e) K" D m. y- V9 s: @% F
}
+ L. d9 z1 P4 ^5 F' | printf("opnd出栈:[%f]\n",a.data);
# W. B1 s* r, R S3 Q; ~3 J( C opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
. W0 \) a& r2 S9 a+ T6 K. A Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/" P2 @; E( Z- ^2 U" v g
printf("结果入栈:[%f]\n",opn_tmp.data);
" x1 G, F- C1 I: N0 D7 _9 x break;
( X% e9 w: x9 b; X" b6 e }# M4 K4 I; T& {1 i. ]) }
}
) S* j; b5 U4 E) E0 w GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 7 U& ^, p4 {' J0 ~' o
}
) W! q" D7 V) S1 v5 ? GetTop(opnd,opn_tmp);2 \% ]0 `' W/ A& g/ p3 @* Z
DestroyStack(optr);
, O- X8 U6 \& E3 Q, z8 ` DestroyStack(opnd);% x) z0 k! @+ f# J8 `
return opn_tmp.data;) V7 @+ x1 I B0 j8 i
}+ ?: Q/ [$ `5 S7 [; v* Z
; c; ]' F8 D7 t9 e' G0 Z4 @, E9 Y2 b
char *killzero(char *res,float result)1 b2 G& e( F, Y) K1 d. X6 n- }7 U
{
4 A: J1 O" p0 x; v" }: Q4 F& ^2 d" R int i;; w1 S6 _3 F; A
3 _9 q7 K. }+ k6 R
sprintf(res,"%f",result);
% T# l/ v1 p( a9 n" I2 R i=(int)strlen(res)-1;
! r/ l# m$ f& w+ Z% C4 h+ d- e while(i&&res=='0')- u" m% L7 H9 j6 b6 p
{
( `& m, G" b, c2 f0 c4 H res='\0';, ?! X9 t2 H8 n' T% F3 E
i--;; v* `, I% h& J8 T; m
}" V# W" o: P6 V3 r
if(res=='.')
y. X# E: b* f! q5 v res='\0';
1 v7 u4 }* N$ L& W+ P f. ] return res;' V$ \% a9 r2 V
}
: o& Q" o; A4 [% |1 a! @
) w: D" d' R) E! m2 {( k$ e/ [int main()
* g3 A% Q6 g |* R" j* B{
/ D) \5 }2 T4 Y$ M4 m4 `7 i char ch;
* _& x3 H/ ?0 s2 h/ X1 @8 x5 T* M char res[64];
T9 n4 U. E2 L3 G! n8 R float result;+ n: `4 u* O! n, O# j ]) u
while(1)
# T, J5 U; p* [: r {! P- y! [) i# v: J u
result=compute();
2 }8 a; x5 }) _, I3 E3 F7 q printf("\nThe result is:%s\n",killzero(res,result));4 E! ?# P5 ]( [: A
printf("Do you want to continue(y/n)?:") ;% y4 _ a, W8 Q z$ a
ch=getch();7 B; u! L) P% l* v
putchar(ch);
: b1 n9 @2 k7 r, ~ if(ch=='n'||ch=='N'); A$ V9 x. U }+ j
break;, I- T8 N( m$ d. j0 V- n; n
else
7 `& C$ |% T9 R% K+ @/ c system("cls");
% i- K+ C- B2 o' g$ X }0 G( `3 T& p$ g
return 0;
. b) B6 ~1 B# @}1 C! } o9 }0 W" ]; t
9 S* j" R' U* E' A) J3 U* R1 ]
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|