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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
" `$ Y" ~: z+ P& ^程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
: w# V2 I4 [: h1 N/**************表达式计算器************/9 s# i8 t' G* F
#include <stdio.h>
; |# V4 E* f6 J3 y7 a#include <stdlib.h># ^2 ~7 S; r) b, O6 J6 g
#include <string.h>
) s7 a5 @2 h: l4 r& P: J3 P* P0 G1 J#include <conio.h>& o& l4 V0 Y+ P, D0 Z! l; _
#include <malloc.h>( K# l8 A. T% R# s7 M
8 o* A. N: g; M. e5 }; }
#define STACK_SIZE 100
2 G" e1 K5 n' B4 E#define APPEND_SIZE 10
7 [9 g# }/ X6 ~
; ?" z7 k; W; e* W0 a3 zstruct SNode{2 K$ C, I; v& n$ {2 l \
float data; /*存放操作数或者计算结果*/: R8 K0 D* c7 e: q/ ]' v# ^ z
char ch; /*存放运算符*/
" y& h( m2 N* p" I9 I3 U+ X/ J8 y6 y};' o) H) L, y2 o# O: u a
/ e( j/ _7 x' A& Y; X k+ K
struct Stack{
9 `# w1 ~2 Z1 _% z G SNode *top;$ ^7 q6 `: Y6 B% S
SNode *base;( d; l# d* X1 y3 D$ o0 h
int size;
" j6 R3 b; q! B: D+ I& C6 S" @}; e1 ^9 }1 m+ L, x2 b1 o
1 i2 H1 o% F# t* q
/*栈操作函数*/% @* K5 l1 F9 _
int InitStack(Stack &S); /*创建栈*/
; |2 H: M3 ]9 u: O# mint DestroyStack(Stack &S); /*销毁栈*/
3 b$ A' z+ d9 V) x1 Hint ClearStack(Stack &S); /*清空栈*/9 w4 R8 |) K1 d" [! m& T
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
" q& n/ d, D9 C A# q6 tint Push(Stack &S,SNode e); /*将结点e压入栈*/5 n1 v& `& `9 D% ~9 o% i
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
; K, b6 B2 K2 {. u! y. O0 w2 X5 x/ h# Z3 ]* ?
/*表达式计算器相关函数*/
. `1 m) F/ N1 Schar get_precede(char s,char c); /*判断运算符s和c的优先级*/$ @$ l. D9 r( W/ ]& x
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
: A2 k/ c# n- y. u6 m2 Wfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
1 z* v2 x! q! N% X* |! I- {float compute(); /*表达式结算器主函数*/* ? H* a0 ~, h$ S: Q, t
char *killzero(float result); /*去掉结果后面的0*/ ! a* p/ i7 d7 @+ K
) v- s9 c! ?8 u# |0 r! t
int InitStack(Stack &S)
3 @4 Q: z V/ ?$ ~{
( l# g- y+ b0 G/ V/ z4 U S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
! f& A- q* c4 f9 `0 o7 W0 W if(S.base==NULL)
3 f. f/ s: P' Z, T9 O1 b, A- Y$ S# \ {/ l0 a! k4 E4 u& b
printf("动态分配内存失败!");1 h' z8 i3 n- V8 A
return -1;+ b4 C$ a/ | r2 T( P# x
}9 W+ e u+ d' L
S.top=S.base;/ m+ p O7 J/ _ g0 z- E1 r2 O2 [
S.size=STACK_SIZE;
2 g: b5 m6 B6 h# M: V return 0;
; m8 Z% q0 ~7 j+ K}
2 M: _! n1 k$ v: m+ h( O. H9 N
; [" e8 X# g4 D8 f5 K iint DestroyStack(Stack &S)0 y5 Y! \, I% f; ^; @
{
0 U0 l$ V P. x- n9 z8 m free(S.base);
( a5 j6 w' M- O$ F$ J3 j. D% a return 0;
* {; ^8 @) I+ p}2 C+ b, i3 ?- E; N
, J- e, A7 O0 qint ClearStack(Stack &S)
3 H4 g4 E% Y: E7 A{
$ ~2 D; W' c& w/ c% l S.top=S.base;6 l( D+ b$ S* t
return 0;; d7 h7 r) y- F0 W( m
}1 {6 } H) T, t% U. h0 R
# X0 A. b+ g& X. M# Y& _
int GetTop(Stack S,SNode &e)
- K) G0 X, M1 c: l) Y7 b9 ^{. a! |, S+ l% m" z* W3 z8 \
if(S.top==S.base)
, ]+ Q! I7 y3 |+ r- X( D H7 Z {2 x; c: l$ E' i4 {6 \+ A/ j
printf("栈以为空!");
! ?; m4 G8 M( t! m7 k7 r return -1;
1 D1 U+ _0 ^, w) O7 r }- l" O* x' r7 w
e=*(S.top-1);/ _4 f! s% X+ u& \) F- c
return 0;+ ?3 ~) N( H1 d# T9 |7 Y% _$ L1 S6 s
}- N% E( s, X5 \; k; w
W. Z; t- w; r( I, Jint Push(Stack &S,SNode e)! y$ v% J% }2 u9 C. l/ T
{
5 S3 @$ A/ f4 L& ?2 r, [ if(S.top-S.base>=S.size)
/ |# {( [3 H. i( O+ ^6 x( u* ]- i {% U7 D4 h+ L% x( Z( N+ x6 B
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));6 E3 s( a/ R- n1 |. ?4 D7 }, Z
if(S.base==NULL)( U4 ]6 c2 U' y. i
{
, s0 ?& q" J2 @9 Z0 N' ? printf("动态分配内存失败!");0 d' e; j7 o; e& B
return -1;3 M% z4 F$ t3 X- n. b
}+ P: o1 W* p) L5 Z/ [ H
S.top=S.base+S.size;) D7 `' n6 S" u; Y# L
S.size+=APPEND_SIZE;
& f1 ]+ f4 z" i( A1 [+ n: H }
8 P* ^, X. [$ B+ c$ T* F *S.top=e;
F" X( V$ ?% W1 d3 s S.top++;) y. Y5 L3 \* F/ T
return 0;& Y, b( d& r0 e0 `" i
}
# o8 O+ m1 E2 u
. M6 _/ ?3 g6 i- ~, i0 fint Pop(Stack &S,SNode &e)
9 m8 w2 o5 P% J3 `+ @{* b, {; J# u( p$ S% |5 J
if(S.top==S.base)
/ f k- {* }) D {( U* Q2 K$ U, _' V7 P4 p; m6 T
printf("栈为空!");1 \3 o* c! q$ j# F( g% b* w! u
return -1;8 e' l' v0 ~. [6 S: H/ p% X
}$ I' o+ y6 i6 U; r/ F h( d* @& U
e=*(S.top-1);
9 G3 K" r, j+ a! A. ^* y1 K S.top--;
( U2 a6 g- C7 U) o7 t return 0;
1 V1 g( D8 B+ b) {1 V) s, |}
& m8 g7 V: |0 t3 G0 D% P( F% w: U
8 k0 H; t: w0 f, j0 h% o5 A/ wchar get_precede(char s,char c)) k5 Q+ N7 z) p
{
* _' c! a7 p8 I' I, t7 i switch(s): Z4 P+ a( {5 s% `4 c
{& z {# X+ V5 L, w/ D
case '+': 9 u: V0 x0 S S) H, L
case '-':
Q$ m0 T3 i; r4 J if(c=='+'||c=='-'); C& g5 Y) c# e, E) y' z; `; D
return '>';5 S% K1 n3 B2 M4 r+ |
else if(c=='*'||c=='/')
+ I/ [0 E6 T' d% {6 C return '<';
1 v/ v- i# p& w4 t/ a/ t else if(c=='(')
g/ R8 e5 i2 Z- M: n, v, L+ t return '<';
( n$ y# o& U* k/ G' w' G0 u" |! {, W2 q else if(c==')')
8 n- i+ @$ m& Z! D' J return '>';
5 o* Y; c- L- m* k3 G$ C else 5 _+ X" P' H! R
return '>';6 A7 P! r+ t' T+ ~* O8 w
case '*':6 e% \+ V7 k2 b; e I
case '/':
8 f2 T; ^4 o+ q4 O if(c=='+'||c=='-')
3 f/ F, ?6 B4 B return '>';
3 W7 A: R( [" d# j else if(c=='*'||c=='/')
* E, W0 E0 Y( ] return '>';8 q B7 E9 _" R9 ?$ |3 S, L1 ^
else if(c=='(')
k9 w+ ~$ [. C6 d return '<';" v. f3 e% ]8 e& Q$ @
else if(c==')')0 I. R9 y( P- I, r
return '>';
. E+ e; r. r) ^5 J5 q3 u- L5 n else) K7 r' D, x% B4 E/ a+ H$ L2 ^
return '>';
6 [; b+ j/ v* W) i5 g1 `1 X case '(':
! r5 V/ j# I, r7 B if(c=='+'||c=='-')
# \# T, E+ t- Y5 ~ return '<'; Y8 t/ j- K" T' P' r) i+ T |& ?1 s
else if(c=='*'||c=='/')
) M( q9 i4 \8 A1 |# c* t, x return '<';
- e' S0 h: `4 q+ y `0 c else if(c=='(')1 s6 D! u4 n0 ]7 x, r: ~6 ~
return '<';5 d' u9 ?9 @' R) S/ w9 s! z: x
else if(c==')')0 M# i+ ^1 |& M9 v E
return '=';/ q: {1 E& U- g5 R5 Q1 B4 e! j$ S
else# j5 Q" d8 b& ^* t7 A# b& d
return 'E'; G/ Q# i4 ]# l+ f) X W' E# f
case ')':
/ d. C: F3 ~2 I2 \4 t if(c=='+'||c=='-')
$ T9 ?, t T1 B+ l! w* V3 h) r return '>';
; Y/ l9 g0 ` S; d$ m f' Z/ Q4 } else if(c=='*'||c=='/')
6 \5 B ?! u6 w. G9 M6 } return '>';" l# d* D5 [) k1 i; p
else if(c=='(')
: ]6 I% |, t" S/ d, ? return 'E';
5 x! u! O5 P; b$ o% G else if(c==')')2 \$ q1 d3 |" i4 }0 o
return '>';
- L4 g4 [5 n$ J" \; c2 E0 U else2 Q' Y7 }* ^+ D. G
return '>';* Y' n( ~' |# W0 O
case '#':
" _: J4 r1 K% J5 a7 U if(c=='+'||c=='-')6 K6 ]' z5 P& [8 J3 d
return '<';
0 e4 M9 g/ f- U5 W( T/ V* \8 f else if(c=='*'||c=='/')! w: F! t8 L: j1 K& y6 D% O$ R
return '<';
. V7 t% F; u7 n% h) Q( B+ ^, O1 t else if(c=='(')
7 t4 x" m$ u/ m( R, \- c3 v return '<';
4 q" @7 l+ ]" Q* {6 H0 J" K else if(c==')')
8 p8 T+ C( w% R6 u0 R' I' p return 'E';
! r5 T8 p r$ i G6 h3 w& _% M else
* o1 v& g7 e4 l- _8 O return '=';! A; t+ L R( ]7 {9 ?
default:# {3 w- R$ \7 X' e5 ?! h0 E
break;
9 c1 g7 v% m( } }
9 O1 F0 y& m" g; J! t return 0; 5 @, X0 u v" F- o& ?
}* q& v) J* O4 W. P9 ^
5 Q g8 ?( }2 N* S" ?9 O
int isOpr(char c)5 O7 n+ E4 W: |8 t- R& J: q
{0 q3 }" v# v; G4 g8 {& W, M: @
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
+ D7 o1 i4 q, y( [ return 0;3 p% J5 ^' r$ w2 w' }1 Q3 |3 d
else
8 X X2 J; j/ d/ a$ N8 ~7 x return 1;9 S6 n. {. k( I8 r
}
, y8 L+ x- Z3 @! G5 }* `( d* G4 V& h) e- R1 ^0 m3 y
float operate(float x, char opr, float y)& P( I5 ^4 V1 h. P- x
{
; Z% d; ?0 l) Z7 h- p/ a float result;7 w8 }5 A1 `& ]2 M& N+ r/ L9 |
switch (opr)
7 z! s! P: \$ ^! z {
3 V, ~) V( u2 e' E3 I case '+':
2 _1 L1 I- H/ M9 \0 ~ result = x + y;9 c( \% O' [ P5 D9 a. O
break;
8 e9 n' o2 @" C case '-':
% |) F- S: e* L) N/ [7 k, j result = x - y;
* e A* {) e2 u- F4 E break;
2 f# q! B6 k: f* L5 c* A case '*': 9 [( O8 K8 d- P2 |- c5 E, @0 v
result = x * y;
% x8 q5 u* P: w( o break;
4 f- w2 v. |+ e2 B; y8 _4 m case '/': ; Q! Y. B* L; u, C$ U% u5 E
if (y == 0)
5 E, A/ V0 E, x9 Q {' d2 Z' F. r/ Z3 U/ G1 i+ N
printf("Divided by zero!\n");
7 T+ r( B; M% o ?6 X return 0;2 D8 d% x, x6 X( j2 G& M
}) Q$ n$ o2 H6 g
else
: T1 O7 T+ _; b+ w1 T) c. f {
6 J! \% n1 S( R8 n result = x / y;: ]; o! m( n2 i, x$ J* u2 b
break;
v# S$ n' {4 r4 y5 A# J( W }
7 ]4 F+ y& x& K default: 3 F; i: R4 J9 P# F( `* i7 x, @
printf("Bad Input.\n"); % q5 X4 Y) L5 K( R9 B
return 0;
% Y" B9 E+ F1 B3 Q: f& r8 p }7 X1 l2 Q6 ^5 m
return result;
" x6 P9 N0 x" g! v}
# k! [: Y( ] x0 ]0 `
% F* J6 w+ u4 H& |0 O% u5 r" Hfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
K ]# \8 l$ S3 Y: ?: ?{
_! E6 Q% }7 U$ t2 g4 l& ] Stack optr,opnd;
$ z3 ?: m' o; q, Y- B- d struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;6 V7 A" z9 ?: _9 Y
char c;
8 t# u* S2 b# C0 K( c4 l2 K) G char buf[16];
1 C# J0 X( Q0 A& g$ @' c& ] int i=0;2 m9 g* _1 l' h; a8 c$ o* [0 f8 d+ r+ h
: A9 A! ^- A2 B: a InitStack(optr); /*用于寄存运算符*/6 q4 Z4 W7 z' H0 _* y
InitStack(opnd); /*用于寄存操作数和计算结果*/2 A" P- _3 l" Q# n# L- ]( e/ W3 {
memset(buf,0,sizeof(buf));
$ c, w8 F) z0 z2 h9 `+ r
p2 }9 J6 l( d$ G C( R/ A printf("Enter your expression:");
8 C$ I4 B; ?0 g; u
( y! g. u8 L" G opr_in.ch='#';
. Y, P2 o; e7 t: J) I Push(optr,opr_in); /*'#'入栈*/% s8 H5 P9 E2 }) n$ E- k
GetTop(optr,opr_top);$ p. n8 ?/ v6 a8 `5 M" H; p" j! ^5 ?- j
c=getchar();
6 u6 @% L$ M% e+ q1 R3 c while(c!='='||opr_top.ch!='#')
# \$ M9 G6 w6 m; u* q {
3 d- B1 M0 P; N' r( a if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
& R" L( r0 B7 y {5 Y' [4 \: S3 K
buf=c;, [7 b7 O/ P0 t8 H/ f; v" x
i++;
8 L6 q5 j* }. _ c=getchar();4 Q6 U W6 @3 g- y! I7 V4 A
}4 j% b* O9 @" i
else /*是运算符*/- _& U9 p3 E: N3 {
{" q% n% O3 x# t U$ t* r
buf='\0';9 _: w* M& j+ f9 w6 E& H0 g) H
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
8 e4 g% w' o8 P; o* I {3 k. q) k; o$ l& G% Z$ H% W
opn_in.data=(float)atof(buf);
9 G2 Z, v1 j- {7 H. h! o, d Push(opnd,opn_in);
& [1 Q- E4 K- q1 z" d2 u2 ?# _3 t printf("opnd入栈:[%f]\n",opn_in.data);
6 F; u9 ?6 ^, X0 _ i=0;9 h, P; ~3 }; p8 x
memset(buf,0,sizeof(buf));( ~7 I+ Y M5 u, K2 f" @
}
1 n% \7 o9 I7 j- u6 T opr_in.ch=c;" W, A# S& f0 x( G
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/; ^* g2 L0 g" r+ @3 |% i0 K- z
{
+ \5 s! ?6 Q4 _6 p) | o case '<': /*优先级小于栈顶结点,则运算符入栈*/
t. ?0 Q0 Y- {3 ^6 H3 e+ F Push(optr,opr_in);5 u. o$ x- K6 ]4 u& i, n9 k9 [
printf("optr入栈:[%c]\n",opr_in.ch);
9 T8 {" X1 [$ J+ l9 a- t c=getchar();( G: ]1 T$ X# J4 n. X' {
break;
% f/ t$ W% s M& B+ U9 m case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/ W# l! w/ r, }1 v: B6 E o
Pop(optr,e);: m2 R! u D/ @& z1 x
printf("optr出栈:去掉括号\n");, T7 q7 T4 H9 ?" a V( F" ^
c=getchar();
: m9 M2 `% k* p( | break;7 Y, g7 Z3 B- ~7 J
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/0 s/ _& p& e7 K2 p& b- }, Q
Pop(optr,opr_t);
4 b5 b( _* L5 @! |7 r printf("optr出栈:[%c]\n",opr_t.ch);' J* U0 [ w9 T8 _! f
if(Pop(opnd,b)<0)) H1 U/ s3 Q( Z2 o# y
{" M1 {5 F, t+ m8 i1 U4 C- M3 x
printf("Bad Input!\n");' u) `5 T$ Q' r, V
fflush(stdin);
r) m* W. A+ e) u return -1;4 z) M( T' _7 D2 X8 N% e
}2 }: R$ f+ F7 a- _* s# ?
printf("opnd出栈:[%f]\n",b.data);/ Y6 E+ ?: g7 X& z3 {
if(Pop(opnd,a)<0)
3 d+ J; J h2 l) I$ P {* O" z4 f5 i8 _4 t, h [
printf("Bad Input!\n");% I# g# `* x7 t6 i- {1 W' N
fflush(stdin);- E$ y2 B# v0 M2 E! t! l
return -1;
+ a' K; K* J. r% Y }
/ M5 v# A7 i" L7 N printf("opnd出栈:[%f]\n",a.data);" x: I9 R2 t I b" U3 N
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
6 R7 j1 R% P' `% {7 F. K% } Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/, e3 a. N! x* a6 k
printf("结果入栈:[%f]\n",opn_tmp.data);0 r$ C0 D" m7 v, K+ `$ v1 H5 b* D8 S
break;& {5 q2 {" Q4 X4 r* A A
}
. W; o" v. T% {6 z4 t! b8 N }
; U! d% V: z# A3 s$ e GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
, S2 r# i6 B7 o- f' e }& G* S0 A; s$ x! ~2 @% o% u6 ^
GetTop(opnd,opn_tmp);$ }! `7 @/ \4 F4 _' S1 {8 j
DestroyStack(optr);0 I: P' \; a7 s0 q- {7 j. T
DestroyStack(opnd);9 w5 e9 S* G8 @ s4 u! @& P& d! P
return opn_tmp.data;
1 @! ^& P/ S* l0 R}: h9 W& Z3 Z$ u5 p% N' n
8 r6 p9 w8 e0 b7 a8 Y3 c& Wchar *killzero(char *res,float result)8 m2 t0 p6 l$ M8 h, \
{
* h9 z: B1 w- o& \& W& Q+ X int i;
' _9 N5 c* k$ r; G; [3 L6 X
' i% f& N. [. H+ v/ e; K) m3 V sprintf(res,"%f",result);
0 K" b% H: C# `. ? i=(int)strlen(res)-1;; {8 x; b. V+ v$ ^" X4 S
while(i&&res=='0')
/ t- r, ]' f& p4 D5 ^1 ` {7 H/ N) ~/ O1 }9 ~: m) f
res='\0';5 L/ H) b+ u1 o- d9 k `) ~, W
i--;7 m2 Y0 J- o p" m, P) `+ |( s9 H
}
- v5 b6 B: r( z/ C$ W* @: q& L4 p if(res=='.')4 B: c0 @; V4 s* t
res='\0';; U0 f+ S" T$ p1 e7 ?& {* M+ p
return res;4 F3 a. k3 a; D. P# |, v
}
3 l+ J3 }- u3 x# A% b" y$ `+ h. @
int main()
$ C2 l, A. z, F$ D- \0 T8 G{0 L& |; F: p7 t' l& y; h; J. {
char ch;$ ?9 j% ^9 q5 Z" H! k
char res[64];& S) I; r3 Z' R) a
float result;1 C+ a0 c" k: D0 A6 d6 i) z
while(1)
7 @; k0 d5 E9 z* V4 b; ^ {
$ L! x: H" t2 W result=compute();
4 I5 J4 F- F& x! E( J printf("\nThe result is:%s\n",killzero(res,result));
/ T. t& p8 Q+ a1 Z: H7 }: h printf("Do you want to continue(y/n)?:") ;1 z" l# z6 r" U; }! _
ch=getch();
8 T7 [! H8 n; Z* p) @- S7 { putchar(ch);' t" k$ {9 |9 k6 |
if(ch=='n'||ch=='N')
; w4 V, }, d- j- Y/ v break;
U/ h; H' a% l0 G# U1 e else3 G. N: r5 S( T% V- Z9 I6 v* c
system("cls");
1 A) j. ~5 ]0 Q }
4 D( E& e. u4 ~7 { return 0;9 p' Z1 v* ?& K; G5 [) U
}# @1 [7 ^2 ]! l) Z2 ~0 U8 K! d
- o% i9 L ~) r3 k
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|