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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
* u4 ?# x6 `& H6 \# f程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=( X1 I" T. o# l- S; |0 D
/**************表达式计算器************/% n/ I( z7 J6 ^+ r* Z @
#include <stdio.h>- i0 C* H- g) K' F
#include <stdlib.h>$ m" K0 I" ]; v1 g Y- Z# v( d) A
#include <string.h>5 D" O$ z" b; ~8 m5 a
#include <conio.h>( k4 ~6 I4 q" r
#include <malloc.h>; f7 J0 H5 q8 C
. i& L- A7 O5 i) W% \
#define STACK_SIZE 100
3 [/ w1 V5 d( M9 }% h" Q0 i# H#define APPEND_SIZE 10* A6 Y" j' r" d8 N0 Y" Q( u
4 l9 O6 ^) h& }struct SNode{$ s a% Q- ]" p4 u
float data; /*存放操作数或者计算结果*/
% E# J! j5 l j- h+ k( ?. N$ P2 T0 R char ch; /*存放运算符*// m- }2 h% \, p
};
# W. c$ B' Y5 K* e9 l# _ U- J* u; ~& Q/ r
struct Stack{
8 `/ G9 y1 y+ A0 ~ SNode *top;- J3 T* ?$ G7 G1 O9 M8 b z% \' T
SNode *base;) M! N) e0 P0 ` A& f
int size;$ v: }0 ]$ B+ k) h2 h% F
};" M8 @1 b+ n- \ h0 W' o4 Z+ m
; u3 g! k, V. K; i# |1 P. T: x/*栈操作函数*/
* M6 \) O7 W ]) d; Xint InitStack(Stack &S); /*创建栈*/
& ~3 U. Z6 X, k9 Rint DestroyStack(Stack &S); /*销毁栈*/! J4 ?+ d0 J! l8 f$ K4 {6 |
int ClearStack(Stack &S); /*清空栈*/
- z3 ^$ X3 p I- e) [int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
6 n- [( I8 t0 n+ r# R3 b& pint Push(Stack &S,SNode e); /*将结点e压入栈*/& o6 g/ x' E, l$ }2 G3 ]6 z
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/" h3 z; R8 [8 h# c4 E
; a& G: T6 w# p" \' x
/*表达式计算器相关函数*/
' j4 O0 K6 j* d2 o$ J, Y- Ochar get_precede(char s,char c); /*判断运算符s和c的优先级*/% t7 U6 U, P ^9 K) k" ~
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/! O' E% x+ |! O- b" {) u: q$ E5 n
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
1 v. z( f# Y$ d0 `6 X$ |; B: Tfloat compute(); /*表达式结算器主函数*/
# d) g# P6 Q, u0 U- b1 jchar *killzero(float result); /*去掉结果后面的0*/
: n0 F; B# j/ ?6 ]) c w3 M0 M1 C2 q2 x0 c" K
int InitStack(Stack &S)$ t/ {- G3 s, d& c) H
{
# g6 Q- F k6 ^, I" Q' z, w1 G" o- T S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
) c) C7 c, G# _* ^( b if(S.base==NULL)
% B9 I; s* x J7 k `' f9 O$ b& R {
' F3 M9 g7 [8 [- a0 P printf("动态分配内存失败!");, l S7 W1 [0 t: q4 O" ^
return -1;
T+ X @/ V1 f @ }
' b2 j6 c D# q6 ~ S.top=S.base;" _ n' U- T) y5 E* I& z
S.size=STACK_SIZE;
" x* E" A( O: }7 i return 0;
7 `, p+ {/ d" J% a8 N}
8 g+ e- ^- f2 g, D" ?" G, x1 \
! v5 ]% a0 O q O8 H# jint DestroyStack(Stack &S)
) {/ K4 Y' p7 C# l{
3 d/ K# `$ r( d% y* u free(S.base);
# Q5 d$ g+ U& ?# j return 0;
& p% E: Z! c- F6 M1 ^$ t2 H}
% a+ U/ w9 A" c3 c; m# V# O( B! x/ A2 _, k, ]" \% R. l
int ClearStack(Stack &S)
2 r4 d" ~5 T/ \{7 [! m( X: w1 g3 [$ ?: ]0 Q5 n
S.top=S.base;; n6 S: Q( Q6 ], \' \
return 0;
* k3 ?; d: E8 S9 G% c, D6 T}
1 i2 g4 c: E2 v K1 [- ^: N/ W7 \
int GetTop(Stack S,SNode &e)$ p, H5 F/ {. h# b; J6 ~- w; {
{
8 @ S$ R1 B, Q) \' Q' U7 l if(S.top==S.base)9 Q7 `# D$ [" ]; f7 u! U
{2 F) F0 `. H7 e g+ M( t( U
printf("栈以为空!");
. h" ?: e- D! r return -1;
: @3 O6 \- i1 v; t/ ^9 a, y$ C" E/ R }1 {+ u8 L, O" U6 e$ ?8 S% b
e=*(S.top-1);2 x% _) w6 M6 G
return 0;8 k- l% U5 @& E. O0 h
}/ d' A! V+ `) x O0 R
: [3 M3 K; o& [* `int Push(Stack &S,SNode e)
; y6 T* E& Q/ r q. y6 u{# r% F6 B8 _" u2 U! K2 ?
if(S.top-S.base>=S.size)
- J% X# o3 _) J. Y: F+ R {
! o0 e+ F( E% { S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));8 D1 r& t: G. D
if(S.base==NULL)
/ h/ I" e0 p8 M/ |0 | {# t G/ ^* `5 A' A' k& v( M- D
printf("动态分配内存失败!");; g( W+ h$ c; f$ Y' W
return -1;
9 U% y9 k- n. h6 G/ M5 B }& D+ ?% |* @; s
S.top=S.base+S.size;
" O+ G( W$ h2 f S.size+=APPEND_SIZE;/ D( I# u& j) b
}. h( i4 S6 c0 [) ^+ m& L4 {
*S.top=e;% F( k# J' r% R% @9 g
S.top++;# o; b( a3 R1 t, P8 D# }3 |
return 0;6 R( X0 U6 z" Z* j, s
}% D) L9 u0 J7 ~* s
% v6 K( g; B0 `( Z, X: tint Pop(Stack &S,SNode &e)) y$ P8 S- _. f1 ?! U0 V. |
{; d) X. d, d& V% B
if(S.top==S.base)" T% J$ |& T$ C: k+ _
{* Z7 M. x) S8 K' S+ D% Y* m
printf("栈为空!");
, V5 W7 C& z$ n- k* W! Z% N return -1;
7 z( Z- F# A% B( E9 ~2 {# [: @ }
& \3 V% }& T r) l6 Y+ \& x. c e=*(S.top-1);( e. T7 O; @+ s! m1 ?7 r
S.top--;# A6 e8 w3 `, \
return 0;
( ?& ?! N2 B$ Y _ Q2 U; g}0 G4 I5 `3 I4 @ Y3 _6 L9 M
' H6 o" h( |6 n4 y
char get_precede(char s,char c)
5 `1 {9 X& W. O9 ]+ {2 _" d{6 L% P! \: U: t u! L, q/ |! }
switch(s)
+ q- j) ~1 [/ p' D0 {/ Y5 d C {, e8 Y3 P. e3 U+ t8 s8 W# q; H* s
case '+':
1 o4 V$ @$ A' u7 }3 c case '-':* h8 d) N0 ^: x6 t3 x% h
if(c=='+'||c=='-')$ W5 r( S( h( x; k' f
return '>';9 |0 M! s7 S# @' P
else if(c=='*'||c=='/')% F( P1 T! x+ E, v% v
return '<'; P' M: h! q1 i+ w, }* \
else if(c=='(')
) A+ N. i* ^- W1 i5 |! u Y+ C( q: L+ ^$ E return '<';
. Y2 S6 l- \( R& j' c5 U0 B else if(c==')')
! `" f6 K( X) L& s return '>';
3 o. } Z% }. i$ y1 s else
H1 Z! y* `! E$ G: j return '>';+ i0 Y; U: b: t$ U/ [3 H8 C% D; R
case '*':
( x j( F5 B% B' ` case '/':# e8 V8 h1 W; l% r0 ~
if(c=='+'||c=='-')5 j4 s( |# N* m. O+ o. N/ b
return '>';
( [- }/ s4 @* p2 v z else if(c=='*'||c=='/')
: D) g9 Q5 v, M- P8 z return '>';
; F' D9 K- S5 c1 T2 G else if(c=='(')
" R7 h7 s( U3 G5 _+ X return '<';
# {" T6 g# |$ I6 Q+ C6 b( ] else if(c==')')
6 y, n/ V5 n, f. I$ W! k& o return '>';
0 _% W. @% b b1 L/ j1 d else1 C) t( j. m' S# {8 O4 v) n5 d
return '>';1 V3 ^9 p v% Z" @! A0 b
case '(':
4 s2 |) k+ n8 z: e8 h9 ^( z if(c=='+'||c=='-')% M$ O& m' @! R# v5 A1 \$ X# R
return '<';
# Q/ o; u. U6 C* g else if(c=='*'||c=='/')
8 X5 S) P' j, N return '<';: y* a2 [4 r; K' x `8 s3 v; C
else if(c=='(')
3 W$ k$ ?9 [# {0 E( ^# U. N6 X return '<';2 }% S2 e$ O3 x) ~
else if(c==')')/ C0 [) O# H a8 T3 o
return '=';! i! c) f& {, x+ r M& m0 q
else- H% b4 U& y6 ?4 |( M$ j8 l
return 'E';
1 k: o/ S- H- |. z0 g case ')':' [9 e/ ?) x' P# x6 u
if(c=='+'||c=='-')2 [! |- g2 W( o" [
return '>';, ? y* F6 `+ ~0 Y3 }
else if(c=='*'||c=='/')
* Y6 X1 B; H8 |5 \! @ return '>';
/ |, {6 U7 N. `6 N. c5 E% @ else if(c=='(')
" U6 w1 y( ?) U7 g return 'E';! o3 t L" C3 H
else if(c==')')! R& x% B9 s* P+ {7 E% ~+ Y
return '>';
7 l, I4 c/ d3 j( o2 l2 B else- p7 A' M# K2 t. d9 y' ^# z; K
return '>';) T/ @ @) ?& R
case '#':
5 q0 F! {4 r' @0 t. ~6 q0 A if(c=='+'||c=='-')9 P5 ]" F$ E9 F& f$ b8 E3 D2 v+ \
return '<';
; d" \' E; J0 K$ r1 E! l( [' m! U else if(c=='*'||c=='/')
. o8 M1 g1 J Z. Z* Q+ { return '<';8 |8 T7 J( M: C6 _$ b% r& {+ x. o
else if(c=='(')
! n$ u+ ]% x1 W3 Y" B return '<';
9 R( h2 R; q+ b6 v' s, {+ b else if(c==')')
3 q# @' x3 }# n6 y# t2 p9 V& R return 'E';
6 L2 z" C0 k+ E9 M! z/ R8 p2 p else
; F% B \ y5 F5 i% g: _: A( ] return '=';5 D1 ^/ a' L! M$ K
default:
4 Q L: W4 a5 G7 H break;3 G4 z: s0 P7 `7 x7 A: A
}
. Y, V$ s& @! k- v/ u return 0; 9 _3 }) X2 T) |8 i( A* h
}
2 C1 {: h" [, z/ t$ r) `, r, t1 N7 \, d5 S- r7 ?( k
int isOpr(char c)1 c! b- R% k% \
{# D' A8 I: h3 J' _" b
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')1 h2 j) t( j" y5 A4 @1 q
return 0;
9 x0 y5 h$ z4 V e( x8 ~9 d else
$ q+ }6 l- e/ u) Z1 U$ N: Y return 1;4 K. j( Y* E6 v* t* v2 K
}
8 m0 L \5 I( x/ r1 t/ C
# P7 U5 f* r% G$ |8 {float operate(float x, char opr, float y)8 @) Z. S" w5 G" V) R8 U$ E, j. L
{
$ N& ?$ I/ h# G1 Z' g) r/ B float result;/ u2 K+ e$ \; }: Y: C
switch (opr)
' U6 v2 l/ }( l0 M {
8 ^ N) @9 {2 X9 e case '+': ' `4 j7 u, _" h* O( {1 {7 w' F
result = x + y;+ _2 T7 y P6 E- I9 b
break;3 r& K, R' `- C& F
case '-':
) d6 {' }/ l* k: v! o/ B# K) a result = x - y;
$ I4 Y; |% g: w+ d break;; o: F6 O! w3 U; b) G
case '*':
' V t3 C: M( Q) `( J; z/ p" e result = x * y;
. w: u# n- x4 ~) v break;
* H% T+ ]5 B1 r case '/': ' c% Y! l( q+ |2 t! z$ _9 q% C. I
if (y == 0)
) S5 g' h! ]5 v8 m- c {
2 G7 T1 R1 W# x7 Q printf("Divided by zero!\n");7 r0 F3 g6 B% ^) Q- a
return 0;
, ]" H, W- u" H+ R. S, P' C& P) W }
, q" f* f0 m6 U9 O8 c( ]4 B0 E$ q' ~0 J else
, Y. S4 u% h" U4 k4 G9 n* ~& V4 w {6 m( e: S! \9 m9 r- ]8 _) L
result = x / y;8 a0 s% G% P5 v+ J2 w6 R6 _
break;1 S( P. Y1 x9 U3 ~+ u( N# R
}
2 g1 J: |' U) |( c. ?2 U( y default: . w @1 W: v* w' ]! c; v3 _4 d
printf("Bad Input.\n");
) O$ q$ }7 p2 t6 B8 `* R( ~1 W1 k return 0;$ F. f1 {# B; S6 a4 E8 G; g5 n
}( t2 A9 K I6 D7 a
return result;, T& J# L& N# T
} ) C& w3 F& [9 ^. ]$ e
) O, j9 F, Q1 N# K) A
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/' \* ]7 s2 H) ^6 u, S* P6 v
{
: K0 i8 @3 v3 ^, ?' }- X2 h Stack optr,opnd;& r8 C7 J o) h; N/ q9 {8 z; s$ u: M7 a
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;7 b+ P& C7 I! T
char c;
$ T5 i+ k$ U( _, ^$ R" J' W char buf[16];2 s- M6 e* |$ Y1 u3 t" Q/ ?% m
int i=0;
8 Y9 b, h3 Q$ ^' a7 x * g, D1 R+ _4 M+ s/ O& L) Y. K
InitStack(optr); /*用于寄存运算符*/% z% `: Y4 d: g* N+ w# g
InitStack(opnd); /*用于寄存操作数和计算结果*/1 X6 R2 d# w! g' W( ]8 m
memset(buf,0,sizeof(buf));2 r2 E0 E( E9 j% b- C/ a
' ^* n' V! j4 S, E+ P printf("Enter your expression:");5 v7 J9 M+ Y% w% @, {& P1 h6 `! |
3 F9 [; K8 B$ x" t opr_in.ch='#';: Z2 P# V% t, o/ w7 C) B- K
Push(optr,opr_in); /*'#'入栈*/9 r/ J: f, X0 A$ v
GetTop(optr,opr_top);
& _& r6 w& K. A) @4 x5 E) @7 N& b c=getchar();
2 A: c: C, E! a4 v0 G9 R, K while(c!='='||opr_top.ch!='#')
$ Y6 o5 y- ~! f) S( s7 l, D {3 @3 E2 h# k0 [
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
6 B' x7 ~# b3 u9 a# A9 _ {
$ x* l0 M+ g. Q5 K* p. F* H buf=c;3 D3 W4 t0 r% [1 Q0 j5 d6 |$ T
i++;
6 I8 f5 l7 N! S1 y+ S; e$ Q ]5 D6 A c=getchar();5 j3 F+ E( L6 Y0 y& Y, T) g
}. }) O2 @& i( j ~
else /*是运算符*/
9 |, Y( l! [0 u. v% ^6 v; H {, F& V/ s3 [; @5 \7 q9 x+ L
buf='\0';; O+ X: [( D) @
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
8 D7 e7 r1 L9 ]3 C4 i! f {& c# u% b! i5 ~2 f5 J& V6 u5 s: `
opn_in.data=(float)atof(buf);( n, z4 r, f" |4 U7 n" u
Push(opnd,opn_in);
0 }/ D/ j7 T4 H, u r( V/ t printf("opnd入栈:[%f]\n",opn_in.data);7 V6 x$ e9 z9 W' ?7 a: k
i=0;, a$ J6 u* R6 E
memset(buf,0,sizeof(buf));/ a2 S" k- i! T1 G
}
: l4 A% I3 \, I opr_in.ch=c;
& G3 k: k+ g( G switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*// `9 C7 Y/ W# A3 f% R5 a1 k' {/ {
{
6 O( A' k- f: N7 p" u' Y case '<': /*优先级小于栈顶结点,则运算符入栈*/
% ?* b# K" ^& S+ j4 Z Push(optr,opr_in);* j( Q' @, J3 z( P. D7 n- G* I
printf("optr入栈:[%c]\n",opr_in.ch);/ |+ }5 X ?8 R ]- q8 Z7 V
c=getchar();
' Y( u8 W& B( O: G7 Q( Q# J break;
# f. _" \7 Z$ q+ G# D* } case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
& S% U2 U9 L; N+ G! \ Pop(optr,e);
& j' U U9 s/ e& f printf("optr出栈:去掉括号\n");0 n [1 g. h7 ~* N
c=getchar();
9 y/ m8 K3 x0 Z6 C3 [. A& l break;! M O' q) [3 _2 V! ~* K
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
% [& j: G0 r6 b- `2 g' Y) J) C# i; O. E1 w Pop(optr,opr_t); g. n( ]# k1 }" O( x
printf("optr出栈:[%c]\n",opr_t.ch);
( B9 N& j$ l3 Q9 x if(Pop(opnd,b)<0)" {, n+ C" _$ w# }# H
{
7 c' o1 L. m5 ?. ]; X0 c8 O printf("Bad Input!\n");% T: n n5 f% ^
fflush(stdin);9 v/ K" Y" l+ M( V) i( n
return -1;" T3 X) i1 w1 u$ z6 S H/ f2 n: {
}
( Y/ O6 `8 p$ v$ h8 ?9 H5 r printf("opnd出栈:[%f]\n",b.data);
- E$ s$ i8 A) W" L' } if(Pop(opnd,a)<0)
9 `; |' f) W# n% Z, s7 b& b {
, h1 {4 Z) }6 A, ?; P" n- K7 T printf("Bad Input!\n");6 Y* j7 K- `; x' @7 l
fflush(stdin);
' z' B7 W8 S) E( O return -1;( V# U6 b( x J, S, ]1 F. c3 b
}
" e+ e8 O3 b% g& H, |/ W4 p printf("opnd出栈:[%f]\n",a.data);/ F r* P x- f0 }2 w
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/0 ^+ N: i$ Q2 v
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*// b$ w+ R0 B2 t/ G& }
printf("结果入栈:[%f]\n",opn_tmp.data);8 I p' Y+ |1 T: o+ u' G7 _
break;3 B, r6 C f t& `0 S( z
}
# G- K7 f# [, V0 b5 \ Y/ \ }; N; H/ k0 i2 T$ `% D- L
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ + O7 ]6 h+ J- u
}% [' R, g/ r8 u4 F- }. C
GetTop(opnd,opn_tmp);& B a& g# G5 D
DestroyStack(optr); k4 d' H. Z6 P4 p% S# p
DestroyStack(opnd);# x' R' h7 C. l) Y
return opn_tmp.data;3 Z; m% @0 h& g
}
$ l+ [; H3 n- r N0 j3 f) O* g. K( c1 y' C
char *killzero(char *res,float result)! g2 W6 ]$ ~) h1 r; X
{ m. _ K8 b. H+ V, w
int i;1 D0 Z7 j/ J6 d- m
/ s$ \; m [+ w$ A sprintf(res,"%f",result);' i& b, [( U# l- [: c; D
i=(int)strlen(res)-1;; k' m* x- U/ j1 V6 |2 r
while(i&&res=='0')
( S" _! [# Y4 a& Q: K2 O% P" R# s8 O {
. B2 [% K) V2 e. W res='\0';. c% b% n; p1 P+ F% v- e
i--;; @# O" }$ V- o, a( s9 z8 n, U
}
" a1 I: @% i' |, M( V- y if(res=='.')0 D8 O+ J9 P6 j0 O5 L3 T \1 J5 [/ ]
res='\0';+ a* ]' K% A7 o+ T
return res;1 F; C- |! |& f- }) ?
}1 ?9 v( t8 H: }2 T
1 F' ]5 f( v9 O4 {: T8 x- O; L
int main()5 |2 d5 g+ g( |; J* ^
{- v& V2 k+ \( [! b3 [+ v
char ch;
m7 M1 Y/ `. t5 Q; j, e! u char res[64]; o3 r% t1 Q5 C( I
float result;. u. P/ `4 K6 g% Y% [1 L! C
while(1)
1 u& G" S* @( a/ O+ O' y {
$ F/ l& |) u, j- k3 k( O% q/ E result=compute();
7 W/ _) {5 O9 [ printf("\nThe result is:%s\n",killzero(res,result)); b: I0 v1 g# n7 x6 ^
printf("Do you want to continue(y/n)?:") ;9 h2 ~7 n8 O9 L3 I
ch=getch();* U4 j, {. D' ]/ P- c2 c2 r6 r
putchar(ch);& s' q( L5 W2 t4 B, }: T
if(ch=='n'||ch=='N')
. m: e# k+ V+ C5 w" W( v break;
. J5 K/ Y4 U. }6 r2 l! e else8 n6 v; q9 ? O/ L+ H2 V! D
system("cls");
" L5 [# p1 i/ t$ a3 T) Y }- W% E9 R! d. X+ z
return 0;5 ? H; B$ o# i. t. W2 Y$ x
}
+ A: c! {& ?1 A3 Q4 e Q- G
, ?% \* O4 p- N: q& V8 g[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|