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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
5 o8 I) [8 `. j w程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=3 @+ {9 f9 Q5 V6 P! y, c3 h
/**************表达式计算器************/
7 t- E! m) k% Z$ m( F; o9 B#include <stdio.h>
m1 d8 _" J; J# f3 f, L* X! h#include <stdlib.h>, D6 _: P5 i4 y( w; k6 {& d: N" ^' x
#include <string.h> x6 N9 |! T( a& h
#include <conio.h>$ f: h, w2 A0 f1 Y
#include <malloc.h>- F/ \, t$ x+ \7 g; b3 k. n
A! m% X- l$ W7 u! ?& t# w* n4 k#define STACK_SIZE 100! J0 I' i& [0 _- x) \+ G* k
#define APPEND_SIZE 10
- O* W! e6 Y, }/ ~3 b% `# `
+ {8 e# |1 p# l7 Zstruct SNode{8 a5 w; k8 Z7 [7 y6 C
float data; /*存放操作数或者计算结果*/3 }. O) B$ i5 f8 V3 e. z
char ch; /*存放运算符*/! `, E7 R: X) [; u+ ~. I* N5 c6 m
};7 t$ }. z I/ ]# R1 b5 n. I
, l& P4 N* N8 w; I
struct Stack{
( \$ e- L6 A8 v/ K$ f+ \, o" I SNode *top;0 A$ e6 ^ ` w8 @; P( s; v
SNode *base;
9 f6 q5 J" a" b7 n int size;
& e) Y9 D7 b" t. Y};5 t% O8 L) n' Y
0 V! A) o8 l0 p+ U9 W" x" @4 k# A
/*栈操作函数*/- f# k' A# h3 ], [$ W! S# N3 e1 B2 V, j
int InitStack(Stack &S); /*创建栈*/' I9 u( r8 @( L2 l' T3 k
int DestroyStack(Stack &S); /*销毁栈*/
1 \3 B- c6 N$ v& s6 g$ Hint ClearStack(Stack &S); /*清空栈*/5 D, V z `) ?% E# V2 k$ D1 f" W
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/" M3 j1 G5 f/ s1 t+ {
int Push(Stack &S,SNode e); /*将结点e压入栈*/
8 p9 V% ]: u" f7 ?int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
! u) m0 { m; U: I
9 o4 U$ [, e& V, P/*表达式计算器相关函数*/0 F0 L2 q* O0 S8 h5 ^
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
9 M3 W- K! o" ?- Y! Z* `# Yint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
8 o& ?: e9 d0 Efloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
8 o) k& y' w: E3 g% J0 b! M( k m+ h4 efloat compute(); /*表达式结算器主函数*/
; O% _ }! W) _/ D$ O1 U3 o6 Jchar *killzero(float result); /*去掉结果后面的0*/ 2 O/ ]8 Q" ^) L( S3 e
( J+ b' \% \4 n' \; \8 O0 [
int InitStack(Stack &S)
|5 A( U* `& U7 w6 _: s( V{: K( v2 f0 |- m; ^
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));+ o- D+ b2 R/ O: M6 e
if(S.base==NULL)- w: S% O% b) |2 `, J% u4 ~1 O
{; P4 ~' G4 ?! {7 A. v/ _
printf("动态分配内存失败!"); W& E9 l; R4 Z9 y; H9 H7 c9 f
return -1;
& @5 j' I7 M( }" D8 x9 W }
6 |% Y, Y4 w' v I S.top=S.base;
0 a6 @2 m4 b7 o8 `6 \# e5 F: M. \ S.size=STACK_SIZE;
4 j' A4 Y# |$ m return 0;& @$ S: b- R5 ^ {& _
}
0 s3 l0 p! V. R; G5 t$ A5 _
0 K" y5 N- Y3 x4 P7 C7 kint DestroyStack(Stack &S)/ s, R$ H5 I* T1 c( \2 Z
{1 ?& a6 `9 A: `/ a. D& R
free(S.base);
+ U1 i- I3 Z0 T3 R, e7 D- y3 d return 0;
b* ]7 W: H/ M8 x- N, N0 S" r7 Q}8 ]0 Z. q) n% b. b2 I
) o) `8 [& d5 p0 Q( r2 h8 T* U7 jint ClearStack(Stack &S) w5 j, A$ Z% ~' T. l* F
{
/ |# D' T$ e$ F S.top=S.base;
/ C9 ]% m$ `! g& j return 0;
2 [: q6 C" ]5 Q2 b* O}
4 w' l' v3 q8 R3 z) S: B7 J+ y" Q5 x' W+ Y: `% S4 m
int GetTop(Stack S,SNode &e)
$ h& U+ L! g! a! `* `9 l6 L{
f6 n" N0 o. M7 W) p if(S.top==S.base)
. g, R% C$ }! C/ X$ U {
; r8 H2 d! O0 x printf("栈以为空!");
* ~! r& O0 K. r; P! t& m return -1;
8 _# f+ Q* B1 [! A# H! I4 ~% u6 t) k- n }
( D+ g" T% ?3 A+ Z e=*(S.top-1);& u% Q! ^$ ]& z; T$ j! `
return 0;
# \8 B" h% I" A$ |* _( |% m9 F}9 z, |9 \1 O9 c: O7 k
6 `% T3 v% t; F' q, o& U& `0 G: J
int Push(Stack &S,SNode e)
# [! O8 M. R9 z' T' ^5 C6 L: k{
- d+ d+ h3 S4 [! \( w- S( w if(S.top-S.base>=S.size)
* A* z8 J% o/ v7 w# l( |# r' @/ v! C {5 V# C5 y0 P/ X7 c, b
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
) ~) H# R# Q6 Z6 U- h if(S.base==NULL): Y, F3 y4 S; q0 |% [6 k/ y m3 u
{
c( v5 C1 N1 o7 m# t* X, B- s; r printf("动态分配内存失败!");( D/ I9 m# k3 t* A
return -1;+ @2 _ f2 D' [
}
/ L7 f2 K8 X7 H2 [, w; { S.top=S.base+S.size;0 ?' K2 z- q* R( l; s$ d
S.size+=APPEND_SIZE;
) E. v+ Z) v) }/ X }. p) R, {% H% _7 T
*S.top=e;
4 n* Y' L8 t) O, V1 A O! @" p S.top++;0 r% V! t% C, r# H
return 0;6 @$ e8 `" T- Z! H6 T# ^/ J: q
}
& W; Y- [% |5 Y' u$ l$ O
" U+ Y8 A1 H9 E- @int Pop(Stack &S,SNode &e)% c- f+ B% M, t
{' \8 B3 E. S: p+ y7 v
if(S.top==S.base)! ^4 R, e: T0 G2 ~
{
# T' H: j. @3 T9 c1 y* Q7 O. j printf("栈为空!");
" A# @/ V' m( o _7 c, ~' X. ] return -1;
0 |0 p& T8 ?: D" n: N7 S$ _0 B( [0 p3 r }3 F0 r% N. W/ K8 u3 X+ k- g4 R
e=*(S.top-1);
- G( F2 f v+ V2 J( z, {; _ S.top--;
q" l' B' l' W return 0;
! J% ?. h( Z/ P/ N0 U, y) M}7 y9 J; O2 |+ M% ~2 ]
, g6 |) b( o% R, L3 \) Z0 ?. p# G. gchar get_precede(char s,char c)
% k9 t9 c9 {5 u( |% h5 u{
, p. T, _; G# a switch(s)
* c% M( @/ k/ U* s' D' G+ ?, { {2 |+ d3 `, }/ a9 d7 V2 J) C$ ]
case '+':
& [. L8 f I% T2 V case '-':
0 X6 g6 D& Q. }8 C) M$ ? if(c=='+'||c=='-')% I! J' @+ o# N0 c% r: C
return '>';
5 R" d/ `# A: j( T8 `: g( V4 @ else if(c=='*'||c=='/')$ U9 w8 R0 r* X; B/ x
return '<';% C! s$ U1 K: z2 o' {
else if(c=='('); k) ?$ ^4 I7 G
return '<';
0 |0 @; r4 c) g# L else if(c==')')8 @4 [% h( E' v+ T5 q* G4 X* b
return '>';& q( w7 m# |7 C- Y7 ?
else
3 Y3 [# m+ a/ E$ E7 `3 { @ return '>';. Z5 i4 `) V8 c3 W
case '*':
9 j3 J$ q& C' i9 T% q7 l case '/':
. x* a& x3 I- B- b- Y; @0 W if(c=='+'||c=='-')7 [9 L" S) {; `8 o. b) V
return '>';& S5 F0 ?/ j0 q/ a2 G" @" w
else if(c=='*'||c=='/')6 g8 V0 \1 z8 Z# n
return '>';
8 P9 }9 w9 g; r# S6 R else if(c=='(')8 c- b$ r9 W0 V, }+ p8 @2 b" E
return '<';* \. I6 x0 h5 x( a/ V
else if(c==')')
1 m- O0 _& [( t& K* n return '>';6 V9 G' \- s+ V, E% X9 q
else
. H' M+ z5 C" r; h return '>';" \3 I; v5 C$ |8 C1 y" i: B
case '(':- T" [ A* [& x. ^- s# D6 A
if(c=='+'||c=='-')
0 J* g7 c" @ e- x" \8 w return '<';" g' }2 y8 ?( ], {7 v; E
else if(c=='*'||c=='/')
1 C1 E: C/ u7 w! C* q k return '<';
: S2 l# k4 c3 D$ s/ U! D else if(c=='(')
! j# f+ s9 \ E return '<';3 q1 R0 P- ]- T- w
else if(c==')')" R: H: {4 |: M) N6 f% H. _) `
return '=';% F& v, p# p- `/ R, z+ P3 n
else" E' Y Q: r# Q- Y
return 'E';
- B0 l+ v6 j8 n, G# q9 ^ case ')': R8 B, n$ N4 J" J) \7 y
if(c=='+'||c=='-'): E& N# B: y, i8 o0 |1 n
return '>';
i$ T* n( M# x; Z else if(c=='*'||c=='/')
/ y' `! t8 Z: N M) ?; Z( F return '>';
9 Y- k2 j7 F" Q4 X4 @" R/ _ [ else if(c=='(')' d/ U+ {5 J7 ]0 p
return 'E';
6 n) B% w3 T. p: V else if(c==')')
/ C) r; {9 N( N1 R0 h2 t6 W4 T7 |5 u return '>';- J: F; c+ |) ?; ~! ]5 I7 }
else
3 l9 |, j, c& A9 g i" _ return '>'; k2 ^2 R5 i# [3 q" s. k
case '#':
2 T6 v1 e' g. w: V4 A if(c=='+'||c=='-')
, l8 a0 w, A9 S0 K return '<';
% B6 D/ y' S1 ?, c* V$ f! y else if(c=='*'||c=='/')
. N& p- R' I# T return '<';
8 i9 F( D k9 e* ] U/ l3 R% ~ else if(c=='(')8 j P& i- Z! u- d t/ n
return '<';1 j) O* g" N$ G6 a, y; j
else if(c==')')
0 M" _7 f0 Y3 }* Q return 'E';
$ j) n; b: |! x+ @4 J3 V else
. m( c, F1 @/ i/ d' q. v return '=';
+ @8 J' m; e2 S0 K7 W4 u default:
G+ B) e; d" Z0 p. M6 q break;, V+ Y# {& J4 U3 |' Y
}
: g0 d$ C5 `& O( ?& S return 0; 3 a1 c y1 A$ _4 Q/ z( C
}0 F, o4 |- F2 r8 Y/ P; {
, Q# h# \2 ~ O: U* R' t2 H& p, W5 j. C# hint isOpr(char c)
- ]) U8 V& y' Z/ `- \{" ^$ C$ S$ w8 t* S
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')2 m5 \& k5 `& ^" W6 l5 b, S; a* y
return 0;
5 O* E% q. V2 L else ( V$ v7 A/ ?4 F
return 1;
" h- X8 p, U& {6 N/ x8 ?1 b# V! ]9 I}
+ z. Z/ Z; W7 m' l6 T4 T4 ~' ^) [
float operate(float x, char opr, float y)
- h' b2 A& S T0 {1 B# r7 v{" ^" ~* K R, a# l. g
float result;3 Z; i& c8 ], Q: q
switch (opr)
. N4 w0 ]" a6 ^8 q {2 A5 {6 U1 I; ]6 E8 S2 t+ N& T% g
case '+': 2 T# S7 d9 g+ _* g- E
result = x + y;
. v/ A' c# `7 z5 U* [9 j8 ^ break;
/ |, K0 o; A- ? case '-': 4 x% D' @( D0 k6 ^# S3 l0 T
result = x - y;' C" E& {0 I7 t& ^2 D- u
break;
: _% x3 M/ _& H( b+ v q, R% _; f9 w case '*': / j; K& N% d% g8 q* w+ I
result = x * y;
( |7 n7 s: k1 Z, ^" C0 @ break;" F( @! @4 \( @ p' ?! [' ~6 d
case '/': 4 k1 v5 K% j& w4 k/ @
if (y == 0)
6 s* l/ y3 w. Y& k8 \3 N) M0 K4 W {
# x) }" @2 D) T2 Z printf("Divided by zero!\n");. w3 q7 c6 v( ?& @9 a2 F! O
return 0;
$ d0 G8 v1 `/ {+ I }
6 w5 O# F% I( D2 _% d% o else# b5 v; k/ S" B0 L% [5 W
{% m. e5 y3 c! }6 t9 r9 i
result = x / y;
$ j2 E) n- `- G7 b# ^# D9 o break;3 O# O3 e. [( K- Z
}% s; w. M" S2 o; R
default: 5 A) T1 d3 q9 C* N& a
printf("Bad Input.\n");
z: M% [* w& m Y return 0;
, L$ h8 X$ @6 i } t1 Y! h) r+ H8 O) H+ l5 g1 t4 H
return result;6 V& s- ^3 X7 \, f( n8 q
}
/ ?' j* p; r+ S' Z; V' Y7 Z, h3 H0 E. O& r
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/! n( }# ^3 P, d- y. }. F1 j
{5 C' O+ |( Q- y F/ n) Q! z
Stack optr,opnd;
. J' d; M* j) r struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;$ c8 U* @+ E, b. A3 G; X
char c;, t0 m* t8 H) Z6 D
char buf[16];
2 b8 x x% [9 d$ r- D( O: V- k int i=0;
% E; K! i5 x, R, f, h1 w% f " h+ z `$ c9 \4 g1 D
InitStack(optr); /*用于寄存运算符*/# {/ b8 J* w( q* [( P3 R
InitStack(opnd); /*用于寄存操作数和计算结果*/- \, J$ |0 c* y/ F
memset(buf,0,sizeof(buf));/ [4 x- @/ t/ A2 [! t
5 W3 i' J! C# h" V, F6 \% }5 l printf("Enter your expression:");8 G. V2 g7 d( E F% Q
' z s; V z, F# u" {" M9 \- t* ^6 u# S
opr_in.ch='#';
% X" F! \4 k2 a/ Z Push(optr,opr_in); /*'#'入栈*/
! Y& t. M9 k: b GetTop(optr,opr_top);4 C, |% Y9 m5 }8 Z1 b% C
c=getchar();) c+ Z; b2 x) v( x) M6 k( i5 H
while(c!='='||opr_top.ch!='#')
' p; }: Z7 j$ M- C" D {
* z6 H+ @- `* m7 c$ } w if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/- ~" _$ Z8 W2 _( |5 g
{' w N+ `: M" s3 ?/ d% _
buf=c;
: {$ c) E4 h+ [+ C$ | i++;3 Z8 G& Q, B+ `1 [4 d
c=getchar();& M# F0 F( a6 a- i. f" j
}
$ k- x ?( h0 _+ ]' C else /*是运算符*/( u0 h, x9 W o. h8 K7 u) V
{
- v+ }$ y6 |) w' C* {5 W# p5 X buf='\0';
* Z' M& j* f% U. P5 o3 D if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/3 l: }9 Z/ L# L( Q
{
- S3 u8 C. z) Y I4 m) B opn_in.data=(float)atof(buf);
; k! J$ _( U0 G1 E3 u: ~ Push(opnd,opn_in);) m& G& C# P) v
printf("opnd入栈:[%f]\n",opn_in.data);) W$ P. z3 p( @
i=0;! |0 z) f8 n, b/ T+ P$ O7 P1 q9 e
memset(buf,0,sizeof(buf));# J0 b0 x- G; w" t7 g
}
! d: [' G5 c$ A% X9 \ opr_in.ch=c;2 @6 L0 J$ g( P$ G
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
8 x5 G1 t; K% Q$ l {3 y/ q$ ?0 A3 i0 E6 b$ _
case '<': /*优先级小于栈顶结点,则运算符入栈*/
5 {, Z% A2 D. N/ z9 x- F3 h$ E0 u Push(optr,opr_in);
7 g% h0 [8 b5 F3 r! g. I; R5 N printf("optr入栈:[%c]\n",opr_in.ch);
. R! F/ x: L8 K& D! r: Y; k c=getchar();3 x( s# S4 v: g! M4 U0 ?
break;
, [2 }8 E" O% `. D8 M; C3 F case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
: d% X0 \) ]4 c! g Pop(optr,e);& @7 `7 Z" z6 y" i# f
printf("optr出栈:去掉括号\n");# G4 B0 A* f" B$ d+ n6 p( v
c=getchar();
7 N B+ B) l/ w break; s# N& f Z+ m5 O) x B
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/- m# L$ t% {. g, F
Pop(optr,opr_t);
7 a" \5 p" x3 d1 y9 o7 A( } printf("optr出栈:[%c]\n",opr_t.ch);
5 w7 B. P" _6 v/ L- K9 u( _ if(Pop(opnd,b)<0)
- T& T0 J. R1 z4 M; A, \ {1 h5 o9 j( W' Y& R Q
printf("Bad Input!\n");
, I% z* d" J" a5 `+ Z, v: r1 c fflush(stdin);
4 H6 _- ^9 P! T8 o' }1 X return -1;
- W! ?, X @* H% w! P! c- ` } g" y1 z+ k# \/ S
printf("opnd出栈:[%f]\n",b.data);" P1 v$ c8 i, p
if(Pop(opnd,a)<0)0 e# O. Y, u b7 E/ \3 A1 ?
{
0 R6 z. D1 I; U/ [# U4 c printf("Bad Input!\n");( y% j0 ]- q0 K& c( y. M
fflush(stdin);! f( V' H$ f' ?
return -1;
: R9 }) l; q9 q+ I; G0 Q( ^# q: T! t }+ w3 G7 L( o' m6 B3 Y
printf("opnd出栈:[%f]\n",a.data);
/ E, x4 y" r4 @& { opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
2 n6 S6 C8 V- E( I# N0 h z$ @ Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/ U+ m$ i4 M r$ Y
printf("结果入栈:[%f]\n",opn_tmp.data);! @2 ~* v: r+ v$ i2 b8 h( X
break;- q I: [1 w f" _2 A' l9 m0 b( L
}0 n: `: W w/ N- j- b0 z, |
}' B+ g# B: B- c# H
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
1 O% M$ Q. v1 W7 _" i" T9 d( q& d5 ` }8 A. O! k1 N& ^# u4 _* y
GetTop(opnd,opn_tmp);* {" ]6 r* x% R# `8 v: |
DestroyStack(optr);
+ e3 u$ e% G; J9 {1 x0 r! g" ^ DestroyStack(opnd);" `- B9 C4 [; U/ y2 b" b; u* L
return opn_tmp.data;
. K& K) x' G# I4 L/ a}5 Z: Z# a$ b2 s; {; M2 ^% o
* A4 I% Z2 B- B( N" |
char *killzero(char *res,float result)
$ J& n; p7 `9 X, S: }$ `{" y# r" ` G# c, N
int i;
) n/ t6 i0 S0 K, N6 F2 R. o4 s: p2 n' U' Z2 t
sprintf(res,"%f",result);/ h8 ]2 m& w6 C+ F$ L
i=(int)strlen(res)-1;
" S2 X0 w, d# g$ D$ u1 | while(i&&res=='0')
) g/ @7 X9 e0 G5 n, e {, } r; w% ?8 z
res='\0'; ^$ n4 I) J7 c3 N. V( Y% {
i--;$ r5 p8 B; n2 [( B' F* [
}8 \$ T6 J# {. v* {
if(res=='.')& W& E! R# m/ a& S9 k
res='\0';7 O/ ]8 ]3 u4 T. E" p
return res;
( o1 E* m8 B7 M- L% H}
& m% {' W; a- x6 ?" B
2 ]% e3 _+ K* s# z+ l' ^int main()
- u* X. ~0 P. ]3 C6 r$ _7 k9 Q1 e{9 z) R8 }. z$ h ]0 b3 p: y7 T
char ch;
' s7 \7 h! M7 v* e$ \7 V! w! P" W char res[64];
0 _- w: j! R b2 J float result;
: u/ O! r; O+ M1 E$ ^( [ while(1)! W0 I% Z$ K0 h J
{
' D1 L, a. r: I& Q: A1 z result=compute();
/ g" n0 Z+ |5 m- Q& g printf("\nThe result is:%s\n",killzero(res,result));$ J+ Q. \" E6 f* b' P& A6 `
printf("Do you want to continue(y/n)?:") ;; h+ N% }, R8 J$ p
ch=getch();0 @" v- P- j" f
putchar(ch);
" p' U) Q+ B2 H6 m# R6 @ if(ch=='n'||ch=='N')
0 O, k* l0 q6 W. ]9 x* E break;
1 ^8 z; y2 B9 w, D else
& X. Y m* C: ~ system("cls");5 {. a( }4 h& I5 ~7 h! }
}: Z& }' H! V0 B2 G. U( b
return 0;" u( r0 h$ c; F7 A: d- G8 y: W
}
, \2 l+ y- G* W0 z8 a$ x9 m: e5 n2 I5 K" v) q% A
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|