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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
. g! U7 A% |! s, x# B# o/ s- w6 `+ m程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
. Z/ z7 `" q) I/**************表达式计算器************/
' h- U4 _2 p$ O0 J, f4 `2 J#include <stdio.h>
; W; F1 s+ l+ j#include <stdlib.h>& ]& e9 G a! ?9 \4 B( s2 O) }2 R, j
#include <string.h>2 H: Z7 y& \' K. u
#include <conio.h>
( P7 I k( m* q% ^9 K, J#include <malloc.h>
, ]) m4 O k; {: V `& c' F% i2 [$ B7 `4 t/ f# Q1 _/ x" l) f
#define STACK_SIZE 100! ]+ ^( U+ B( [6 J2 u
#define APPEND_SIZE 10
8 X9 v8 q" q( U9 I S$ Y
1 q) a7 v( B% p* @* `, a& p5 Estruct SNode{( c. C# ^" }3 J& N3 S; ?
float data; /*存放操作数或者计算结果*/
2 r8 k& b9 I. H# U5 c) | char ch; /*存放运算符*/ a( W' p+ a# |5 d0 j3 A' e
};1 D3 S4 q0 P9 |2 W: S3 V
; p5 H( a; d( A& ~6 ]; l
struct Stack{+ Q4 ]3 E& K# Z0 o: W: S, R
SNode *top;
8 N4 I+ M; S& V4 T7 I5 D( p% Z" d SNode *base;
6 q1 G/ U' A+ a9 I: f& O int size;- U7 u4 }# v8 @2 `# O- \
};
2 N, S# {% O$ H) m+ n2 ]
3 r: h8 M1 }: b, ~/ \: o+ f0 ?/*栈操作函数*/* C8 T1 T5 b. a; ^
int InitStack(Stack &S); /*创建栈*/
& p- T! f! m1 [* H# h6 Mint DestroyStack(Stack &S); /*销毁栈*/
9 m- K! a# x. X) P6 Cint ClearStack(Stack &S); /*清空栈*/
. N! t( I# r7 S+ M& A* aint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/: U7 o& X1 d f+ v4 g6 B3 L
int Push(Stack &S,SNode e); /*将结点e压入栈*/; H6 ^' w6 w- y% P
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
2 k: L# H" s' c% y' h3 ^- W* A5 [( g) g1 K; K" m9 u. P0 l
/*表达式计算器相关函数*/+ v& J$ C. ?' M3 h% P
char get_precede(char s,char c); /*判断运算符s和c的优先级*/) a7 ]* U- ~+ M! G3 m" r
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/1 V( X8 o N% n: H7 ^
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/$ }( o {. s6 {( L- b O! s7 r. d
float compute(); /*表达式结算器主函数*/
; k5 s9 c, J4 C& s- O' [char *killzero(float result); /*去掉结果后面的0*/ ' ~4 M7 p* H% B: p' t* [7 m6 i* V/ W
3 Z3 @1 T& z4 {8 e$ G5 Y$ Uint InitStack(Stack &S): w6 }8 H! p3 ]# M5 J0 K: m
{
" P8 A- P8 p7 B |& F8 g0 j0 a# s S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));+ a) w6 T/ d2 b8 h# [ i" e
if(S.base==NULL)) p: i2 }! ]. O' y0 K
{
4 E) O9 @" `0 S, X6 C printf("动态分配内存失败!");) q* e6 u$ `+ }1 p. |, H; a
return -1;
( b# y+ O9 n, r& p/ @% C, ~ }6 o% L7 i' o0 M8 g) Q% H% O- r6 @
S.top=S.base;/ a0 Z9 B* C y9 F) l& C
S.size=STACK_SIZE;; y, J% a+ }9 y/ Z7 n
return 0;$ P( ?/ O9 p# m: r$ g, ?4 s5 d8 B
}
3 r7 J! O9 A' |; f$ h5 s
! ]+ q% m" h8 E' P: \" }2 H8 Uint DestroyStack(Stack &S)' _' n* n5 g3 ?0 Q
{3 x( U+ t* a) S4 c+ k h" `
free(S.base);
) W, B9 i8 ~/ q return 0;
2 r5 v( f4 B! m0 J" c; }, h# Q# f6 X}
- `( d1 ]* f) x2 K& O) t/ t; w3 Z7 x* g/ u' p, ]
int ClearStack(Stack &S)
9 z. p) G# `. o. \2 w# H{
7 ?+ ?% Y, U$ h' Q9 u2 ^6 f S.top=S.base;
: d8 j, x( ?1 C" C. d return 0;4 R; I6 [9 o$ V
}
9 s, z6 c& Y3 x8 `( X9 E) }
8 \: c6 f3 G B6 B d) A. bint GetTop(Stack S,SNode &e)& z5 q: _; C% _
{
+ s, W- j. k6 s: R if(S.top==S.base)
. O9 l& j% f' A4 S A {, m8 P0 C0 a& L5 D' w1 @
printf("栈以为空!");
/ R' Q) o* t5 C4 h return -1;
) @1 W6 G# W( p+ I. v3 M, F3 t$ I }; ?6 J$ v. w3 E/ s6 |2 M
e=*(S.top-1);1 w5 Y! E) l2 g
return 0;' F( D5 T- U/ @1 X, K3 K3 R
}, x J: B4 b! Y5 o7 {- A% E
. h$ V$ z' x) Y4 @2 b5 qint Push(Stack &S,SNode e)- V/ @8 V3 M7 N! Z, ?' _' X
{7 f! Y% P9 _9 J' Y
if(S.top-S.base>=S.size)+ n7 i7 V& q* K; w o. i; k4 a+ e" p9 M
{7 p7 s8 M; v/ l* c
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));6 Q; R* ^; C7 Q+ A
if(S.base==NULL). l {& s8 _. A1 m. \
{
+ N) t* x8 }; i printf("动态分配内存失败!");
+ @% B; [7 J) H" B return -1;
+ \! }5 u; P8 H% X, G+ B1 r# d8 L }$ w9 x7 C3 Z$ S" D- ?6 a8 U
S.top=S.base+S.size;! K: v. B5 R# `5 m( Y; S. t7 x) U
S.size+=APPEND_SIZE;3 u* F2 h5 \. p, K& l# R7 N( [
}
! G, |) y$ j$ @& F& h *S.top=e;
# H0 E) v3 v- A" i- L+ _# Y S.top++;
0 z) ?% N p5 _7 C8 [& e+ o! b return 0;
6 H/ `/ ` j& B" A7 T}" P: a1 Y, J2 u; E
4 Q- W! V! n6 n6 \int Pop(Stack &S,SNode &e)
' H1 s1 X( _2 K0 B, q% Q7 I3 [{5 c' h7 V+ C3 F0 J9 S
if(S.top==S.base)3 C+ e$ M3 d+ N, x0 [: H: p- h. O: d
{
0 r; h* R7 ~3 E& ?" l6 f printf("栈为空!");
) P6 i8 ^& g- _/ S% f1 D, g return -1;4 [# c4 j! f( J% O' Z/ X F4 L
}2 u, j' }+ M/ Q+ a' ^# ]
e=*(S.top-1);5 t I0 Y4 d+ c, F: J! Y/ P6 c# H
S.top--;2 C9 ~1 M7 S3 `. M+ V4 S) }
return 0;
1 c k* w+ O) G4 F/ ?6 n* y}: I0 z* r. }+ j) t. J. X
: F% m# Q! k x) g1 [6 n8 F
char get_precede(char s,char c)3 ?/ J& v& t$ ?, W6 P# \
{ I1 X. ^1 F8 ?* K+ j
switch(s)1 d3 d7 d* O; d- n9 k
{( B i) l2 H" Y: G) i0 E
case '+': ' f, S- o. K X1 K* n- ^+ q* x/ H
case '-':
, W3 U: \9 J/ `1 _( [$ r if(c=='+'||c=='-')
$ {! n0 a9 E0 t return '>';
7 t3 E. L- C- \8 P, K6 y! J* a else if(c=='*'||c=='/')3 W+ Y1 @' B9 h% N* X
return '<';
! z1 Q( V! f( m else if(c=='(')
$ \; i, i: r- b( O$ F5 B9 C return '<';
% e$ C0 [ f$ f) ~. y& ^ else if(c==')')" L" a( _7 ?" {, a% J4 z6 ]* g
return '>';6 T$ q& ^, z2 a2 A1 {" H* P
else * [2 l |3 u& I" C
return '>';6 |8 y3 u6 p. s0 z" P: K. S' o
case '*':$ a4 d( @8 i" b5 S* b7 a: x
case '/':3 t0 ^" [" C# ~3 H2 n
if(c=='+'||c=='-')
% T7 v2 z/ r8 {& s1 F& ^ return '>';6 p9 l& c. x2 a/ P
else if(c=='*'||c=='/')6 Z" ?. R' @2 j
return '>';, @8 m9 L1 g" w- ?! I" G* e
else if(c=='(')
# j8 k! a3 D! f) V/ ]1 w1 p3 _ return '<';3 P4 x7 i, K: x* }7 V7 S# y
else if(c==')')& F$ w+ D5 Y, U9 @4 Y3 n0 ?& W
return '>';$ E4 `5 D+ J( W" |
else
: ?) D8 e* r5 T2 j return '>';
L `4 h- y, \& V; w, N case '(':) h( Q9 v( g6 g1 [
if(c=='+'||c=='-'), w1 b4 g/ G8 @( G" B8 b1 b, }
return '<';
& k p: h! M* L else if(c=='*'||c=='/')
6 I' o- y# k2 X return '<';+ r. ]9 x& _, t- R4 {5 b0 H) i
else if(c=='(')! @" t1 ~2 m+ \5 m
return '<';
) `, g. h- M8 M0 J- b) l/ `+ @ else if(c==')')
) B4 j5 D! H( a \ return '=';
j4 K4 v" a/ s( s else4 T$ |: [1 K0 v2 w0 L
return 'E';
0 k/ b$ `; k1 f; h3 ?9 ]$ d- q case ')':
5 i I8 x4 \. |7 t+ I1 \2 d1 |. g if(c=='+'||c=='-')
/ D' ?4 i4 z1 A3 R0 q9 ?; z return '>';
1 \2 I4 p7 U0 J5 r0 \5 s3 E else if(c=='*'||c=='/')/ ?0 d4 v) ?3 A/ K" @6 v
return '>';. k. Q' T" K9 K
else if(c=='(')
4 Y' M% a* |/ A0 F- B* [( l return 'E';5 [3 E6 ?7 r5 o! L( C
else if(c==')')4 J8 `8 d% {: O, {0 F; J8 N
return '>';6 e/ v2 v; Z* W- J3 z
else# `1 j: P4 ]+ h9 d, S
return '>';
+ j- K) Q# [5 }, A; R case '#': U) ]0 T* V6 X3 x1 q5 j: e
if(c=='+'||c=='-')# s( {+ A- P6 U: y) ~8 X/ N+ q. c! S
return '<';" d8 C% R' v* W. D1 I
else if(c=='*'||c=='/')0 o9 P% Z/ T4 d9 X& T9 a
return '<';5 a' L$ m2 _9 {$ V
else if(c=='(')6 b: D4 z; \6 D+ R. p5 j
return '<';
7 v% V" w0 ~6 ?/ Z L5 o$ a1 u. a else if(c==')')* t1 n, ]/ D( Y9 t# t
return 'E';
2 y- C$ m. f( L* e else
/ P7 q( f% g! @ return '=';) i6 e: H: l: w# V, W: C
default:7 y1 V" D2 e$ _
break;
! x0 i& a6 `6 s v$ [9 w4 N }
/ T; M; \( \) O' F return 0; `8 M: D- ?; c7 A/ F' L7 o
}
! M0 ^6 R1 {2 L. g! `8 ^4 l" s
$ L& O) @) ]: e# w* q& _1 v; V3 jint isOpr(char c)
. N3 t: _# [' |/ k6 R1 J. g3 a{" U7 q7 y( w; v( m
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')3 n" Q5 A- v/ h+ k
return 0;
F2 ^0 \* r& c4 ]8 |* T' d0 q4 q else 7 M, x; s" Y G$ w d; r6 F
return 1;5 F6 C2 U% I% t
}5 L+ |; P6 J8 G
# w4 N! h7 N1 E1 M9 V7 i" wfloat operate(float x, char opr, float y); @$ n5 p& I, F7 Q$ Z
{
- L' K5 T, i) n/ D8 ]6 y/ ? float result;& J8 i' n5 t" u* ~. E. L- A
switch (opr)& L' B" l3 q# {7 _
{# b" D$ D. r/ v) i* Y; |. _
case '+':
- R7 a! h) g* q& A# Y( a N result = x + y;4 K0 I/ j+ b7 E" ^' |3 L' ~4 |
break;
; s9 l- G/ N- R5 F5 } case '-':
! A/ j/ [% s# {' S" ] result = x - y;. r1 C x$ Y6 b/ U
break; S; @5 E) U- T) S: H2 r$ Q
case '*':
3 C: d G9 ^. B- u result = x * y;
3 K' z" M' X! Z. G6 p break; T* [& @5 O; D0 ~6 A
case '/': & c/ B' W2 N! T0 }2 F' r
if (y == 0)
L! H9 A3 M$ p- F {
0 c" z" @9 r3 K$ V printf("Divided by zero!\n");9 A) ^9 h; a; F4 B, K3 }. I3 }8 }
return 0;# c8 I! X; ?9 ?4 C+ v0 f
}# g) d' [5 S3 X
else- R( t' [2 L' _ E! P
{5 e+ d5 y5 m, O& g( v' T- v
result = x / y;8 p- y! R5 F8 k0 M% `8 x
break;
, @* g* m+ L' C; ` }
5 r' k( _9 s' ]5 |6 x& s default: & ?# [) k( M% ?( k \+ ^; T
printf("Bad Input.\n"); 4 j/ X( C9 Y6 @4 M2 c0 H" P
return 0;9 t3 P) Y. G' K6 L; I; N! i- N% ^4 c
}1 E$ d; y# q- T: Q
return result;1 T, v+ f' H. C+ ~' _. I
}
( x! C' U! h" I$ v4 V, x. l8 Q4 J( d/ w6 G/ J; S
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/9 k( r' v: X/ {4 U, p
{* P9 c* N! l! Z9 Z* _% p. J) [
Stack optr,opnd;
' X2 ^- r7 Q. s- j6 ^- W7 c struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
! z/ j/ g4 @0 X# H char c;
6 m4 D+ m& ^$ _ char buf[16];1 w5 j E8 D* A9 q. f* }
int i=0;
; m- @9 z) V" G0 A% Z: ]* [
u* t" E$ b" k7 f& ` InitStack(optr); /*用于寄存运算符*/; k. U D! j1 o% p( T: z$ l9 n9 w
InitStack(opnd); /*用于寄存操作数和计算结果*/9 R i. e z3 M! L9 N
memset(buf,0,sizeof(buf));4 m7 F( m& Y6 j) P
2 v$ u% U9 f `; j2 l+ `
printf("Enter your expression:");
* b& p: ] @5 A+ b2 x& V 7 {: C4 s2 J* z1 F* Y) p% S% S
opr_in.ch='#';
; x" g+ S3 y" @6 a Push(optr,opr_in); /*'#'入栈*/! f% y' e% Z! X) p0 i7 f- ]
GetTop(optr,opr_top);
7 o8 ]! |0 M: j* t9 i3 D' W6 \" Y c=getchar();
" T9 N* K3 ]3 N: @ while(c!='='||opr_top.ch!='#')
) F9 `. k2 ~) I4 \" g {- i7 |% H! d7 m% l+ t
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
& h1 U. x+ \; J' H: ]% t- K+ Z! t {
4 h" Z7 J; E, @" g# t0 t buf=c;7 d( ?# `( P) G
i++;
7 ~. N2 ]& Z0 |4 J c=getchar();. t) U* B7 x0 y4 p
}
& a" D' h a( T* A else /*是运算符*/# u. H/ k6 c; m+ P7 G6 H
{2 ^% u* X; ]' Z( E7 j6 f2 K
buf='\0';
# |+ D$ m- o, y% _& @/ X7 O if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/% @- k& Y. f) w( }( Q
{- F- o/ o8 \2 J* y1 u2 c P K
opn_in.data=(float)atof(buf);
7 k N1 G, t& N# M" c! {% ~ Push(opnd,opn_in);/ k: n- T* I+ f' h) c" |4 ^
printf("opnd入栈:[%f]\n",opn_in.data);
1 u+ J: y7 q: [: t+ i0 g! {/ k; d i=0;
" Y) N. o, ^ n) g4 ?; q% G8 g memset(buf,0,sizeof(buf)); }/ X" [ {# ]0 ]1 V+ j, ^
}; U& W2 O* u# e" E
opr_in.ch=c;' ?$ s' p9 f, }% X# i! s7 I
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/# t# \- @2 y) P& u
{5 O. a; [# I% f3 D
case '<': /*优先级小于栈顶结点,则运算符入栈*/5 U5 d I/ e( Z3 K) T+ u
Push(optr,opr_in);
! ^& o* r- M% d. S ? printf("optr入栈:[%c]\n",opr_in.ch);( z) k8 D, D1 G7 y3 B5 Y
c=getchar();
) H, z, w+ t* n# Y) V! m; U break;
0 Y# {8 \- U" j. \ case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/9 d1 A% H5 P; m3 j+ @* s# m
Pop(optr,e);
0 d: E# k+ y$ e+ U7 [7 v printf("optr出栈:去掉括号\n");
3 X5 ]9 Q6 m# S, `+ _ c=getchar();4 t! u, y7 k' {0 R
break;
) v9 C6 ^* f% R case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/8 f% @) P6 e& N
Pop(optr,opr_t);
, a8 w" {0 R2 } printf("optr出栈:[%c]\n",opr_t.ch);! F( E. f# K, z8 @. s, s
if(Pop(opnd,b)<0)
2 d, B$ A6 X) x( g' V {
3 T* C' O/ a/ _1 G# `" M- ]0 Z printf("Bad Input!\n");1 U% y1 ?: l3 [- x* R6 n
fflush(stdin);
# x' H+ x% k' ~ return -1; u2 H, W" j) z7 _' b' X" t
}
+ T" C1 X+ q3 ` printf("opnd出栈:[%f]\n",b.data);
9 e; l8 d& B" [2 L( n% h" s if(Pop(opnd,a)<0)3 u- M+ c6 n) c: ?* X
{6 l6 P# C- e/ a O4 B9 B( z
printf("Bad Input!\n");! h3 I: q' M9 V- e6 u7 w: {+ z
fflush(stdin);
2 D* t6 M# A% Q" x return -1;
% d* a: R( ]2 F4 O* Y }4 \3 g- y& X2 O" B6 h8 F
printf("opnd出栈:[%f]\n",a.data);
/ w* q4 x, N2 v' F! Z& V; b opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
6 j# }/ K" a. X5 F# ~# a+ e9 I Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
$ {5 d: T; y+ V' D3 B printf("结果入栈:[%f]\n",opn_tmp.data);9 W; B* ?% s# F3 ]9 y" \8 p4 K
break;2 `) p: \' t% G4 E5 j
}
' w' @( q6 T& x9 o* V& x2 i }
7 ~2 Z' U4 F4 u* S' f- J; w GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ : k1 V& L5 Y5 [+ S& B
}
; W+ H2 a7 o+ E: j( g GetTop(opnd,opn_tmp);
/ P) b. i, q+ u: Z) E$ l4 E, V DestroyStack(optr);
. x, Y- r3 E' x+ t: X! q" m DestroyStack(opnd);& V c' F& ~( I
return opn_tmp.data;* s& A3 b& Z5 y' E0 X6 J
}/ g( Y+ y; L: |+ x+ M2 u3 u6 u; e; t0 }
! o) F# |! g8 ~: y2 r7 D/ N
char *killzero(char *res,float result)# H: f2 z: @* E
{- [7 f* C: m% ]
int i;
* \, Y6 }& s8 r: ]3 N
+ \- i8 r3 A9 [. e sprintf(res,"%f",result);
( R5 _" d3 U9 P2 W9 N! W; Z! c/ b i=(int)strlen(res)-1;
% q, X5 `2 C' x; J" m while(i&&res=='0'). u/ {# d4 B5 e4 \; k
{9 Z# Q, }5 J' l4 h7 l
res='\0';3 M. f J9 X& h& q: T3 `. n
i--;2 X* G0 R; Q l' x- Y, I, w
}
* Y# |* c. A" m if(res=='.')
) Z$ j. l* t) R1 a9 f7 ~$ n res='\0';
) G/ O9 X3 {( r return res;
2 S7 P# [. A! ]' x}
k. s; U0 s6 \" Y! t4 X7 }) L% m6 ~# n6 x( L
int main()
0 j. P! p; A( P& U{, Y+ g2 S. ]) L, o [
char ch;
6 o+ W" J$ ?5 h9 Q& s: W char res[64]; ^+ f6 [% m% q* }9 X. Z
float result;
5 D) H# h2 e7 f# e/ _; v. Z: _ while(1)
% K; I% T+ p) H3 P- p {
4 i4 f& V% U2 y; B3 C% j% _ result=compute();% U4 @( N8 `( C
printf("\nThe result is:%s\n",killzero(res,result));0 [+ y7 O' o. Z0 ?
printf("Do you want to continue(y/n)?:") ;; R, ^; [4 i0 T. X8 n' p2 b6 d; Q
ch=getch();
/ X }1 ^8 Y: i) N# ~( |: o2 v- a putchar(ch);: z3 a" \1 h' ^$ b
if(ch=='n'||ch=='N')$ o, ?8 M& S/ C5 L7 U
break;
: _. U& V" U$ j/ _1 a else$ k3 S: m( [' o
system("cls");
, i f ]( |' O8 _1 y8 l }5 B/ B" z" |8 y5 |, D
return 0;$ p) Q& @6 }/ ~5 q: R
}
. K& I8 ?4 t% {0 r" ^/ T8 J6 t" I0 Y( p; v8 L }* @+ U( c
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|