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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.% ], z6 q; t% p( E/ W: W
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
& l2 p8 @, I. s/ V! ^! h: L' ?0 e! _/**************表达式计算器************/
7 p3 [# a S* u" w. N5 r: z# G% T#include <stdio.h>3 e2 O% P0 t: \6 Y- p2 S/ M6 r
#include <stdlib.h>
: I" B3 `0 q9 c: k( G s2 G#include <string.h>2 {4 v. c7 {$ N1 X
#include <conio.h>* Y) `/ c- m" l; }4 I0 G! E2 N
#include <malloc.h>; m5 Z% A; r0 R+ ~
# ]& M1 I8 S. R% p6 L% X6 ]( @% u#define STACK_SIZE 100$ b: o5 n' k4 R6 d4 R2 ?7 z
#define APPEND_SIZE 10
% c3 e7 e, [0 Y7 V7 D
6 w& T+ w5 T) ostruct SNode{7 u, b- K$ j9 C+ x% G. ~- A" h
float data; /*存放操作数或者计算结果*/
( Q. A! F- j( P) M( G char ch; /*存放运算符*/
; ~ ~, F, H% _& @};
1 k8 [: H1 d9 E }1 `5 _4 P
- n4 P% P/ d ~: g0 A$ Nstruct Stack{
" M1 \5 A* i) d, i5 h$ C5 u; | SNode *top;
# x+ n; Z, D0 i3 U* \0 P4 S& A% ` SNode *base;
& d# `9 J( Z% b2 F% \& W int size;
6 V/ M+ y0 R5 L" z1 p};
1 f' o1 J- X/ M6 q; O( i
; d; m6 d8 ]7 W: b4 e/*栈操作函数*/
# F$ b- p' s$ s2 |/ K! i* lint InitStack(Stack &S); /*创建栈*/. Q/ z! C6 {' n' S
int DestroyStack(Stack &S); /*销毁栈*/+ O3 i+ ]8 a, S1 f4 D
int ClearStack(Stack &S); /*清空栈*/6 j7 `$ q# p& X. u9 I
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/( Z1 u {, H# W- i0 j
int Push(Stack &S,SNode e); /*将结点e压入栈*/' S& c) t& v& k3 m
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
) j. J$ m9 N! ~6 e2 ?; R- R7 |) }4 x' N9 g$ z9 K a( _
/*表达式计算器相关函数*/
+ Y! }+ ?% d' @# z* Qchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
4 d1 C' S; P2 B2 t' M [% T* _, lint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/7 p1 K$ }8 ^$ g
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/" S! N" K* P2 G$ ]
float compute(); /*表达式结算器主函数*/
7 V# a/ V- z0 z' C3 |. @$ v5 fchar *killzero(float result); /*去掉结果后面的0*/
( @. V& ]2 J$ a
; o0 Y9 F1 L' p: z% c+ |int InitStack(Stack &S)$ x% V; a5 I& t9 i2 ~" m
{
$ o1 ^) x$ f% c( |9 I S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
" m0 m1 M" a% w+ C+ q! R9 h9 a if(S.base==NULL)
* G4 G3 s% z( _* D5 t {, L4 K+ o$ i) [+ y; r8 C
printf("动态分配内存失败!");4 G+ q4 k; u7 s# Z# t3 ^7 D9 U) u7 }
return -1;
) H9 P. {* C1 F( Z3 c, S6 P3 P, y }# A2 s' h. O7 ~6 g" c0 b
S.top=S.base;+ M, o8 g5 z# n4 e4 ~1 L% ]& ? Z- @
S.size=STACK_SIZE;& p. y9 {7 ~" a: y Y B! w
return 0;
8 k; `- O) x2 S$ w' ]) n" ?5 G! q}
$ c% K8 a' {' M& u& W' {# z. P
A4 H2 y' ?8 `5 l+ pint DestroyStack(Stack &S)2 B0 }% A7 U2 [) G8 d s |, Q) w
{
+ x; W, y: r9 Z& g1 L/ ] free(S.base);
( Q8 {0 j" y4 x9 w: m return 0;+ [/ G4 p" Q. O( y) R! U9 `
}
, t5 [% m, E) ?/ n, x: n$ N+ ?
( g: n, d$ I u9 x- Tint ClearStack(Stack &S)
$ m3 R# O- f& j" z+ `! E{
6 [; U( h$ Z5 T0 l# P: m* U7 e* S$ P S.top=S.base;
# l. H! k7 U( ]5 y return 0;, K& P( \( d5 B# q6 A& o* Y
}
8 Q m$ V3 v- z, `# d2 @
! b" T9 [2 r, C- ]4 [) rint GetTop(Stack S,SNode &e)
+ U) U& `% k0 h, ?{3 f2 ~; U( N5 A' D2 p. p0 a
if(S.top==S.base)" u, i4 k9 u( u. V2 T" X4 u+ Z
{8 J4 \2 }+ O$ K+ W1 B4 I% h' y |
printf("栈以为空!");
; A- Z( k; q8 `1 ` return -1;* n; | v7 l7 G& R7 o
}% t$ ?9 d- C, a) b! t
e=*(S.top-1);! m7 ^3 u9 Q% b* i ?* e6 r0 C( E+ i
return 0;
. M9 t" F, |, I+ i4 q}* I7 K; R* c' v9 G! m. H2 ^3 ?
1 e6 s6 Y7 V" W4 C% I7 Zint Push(Stack &S,SNode e); S. y% `, K' S9 l5 j
{' v5 m7 A* F [! b+ D5 @$ [& T: c" |# v
if(S.top-S.base>=S.size)+ O7 L- d9 Y- @. S$ h. e
{
. x! x r( C# W S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
7 i; b, c) y- c' I# u2 y+ Y if(S.base==NULL)
2 D1 l A! ] C6 V( n3 n {9 A. B. {5 S( ?. S
printf("动态分配内存失败!");
v% D# |5 I6 L& b: c& J1 h. z N' e return -1;
; h7 T8 x! `$ ?" n, _+ q0 h3 x }7 z; k- F$ X; j0 J
S.top=S.base+S.size;
- h- S# ]7 d, Y0 A7 a! M, g S.size+=APPEND_SIZE;6 A5 a% m% `* [" ~ r" p7 Y( m
}
% @4 h2 w, I3 H) ?% f" k *S.top=e; H9 I6 v9 q9 G1 U9 }4 q8 ]& b, v
S.top++;* e2 \4 R6 s% U6 x
return 0;: g9 |% m/ N$ i/ r
}
4 ?6 b* @2 g( D6 F2 T+ i; _3 S7 N* h2 k: }3 b" d+ m
int Pop(Stack &S,SNode &e)8 a. \6 h, T# m1 A }' q
{
6 O4 e# f) I% p/ j& f: q if(S.top==S.base)
/ W' I% y' ?8 o& Y5 a {
" \ d( p: n. }+ q/ k. n printf("栈为空!");
. |+ w- `) Q" o$ f return -1;
; b1 y s* q u }
7 i3 a! ~- Q, i2 h9 R e=*(S.top-1);
/ M( S* }' C: p0 t' N% ~( |; }2 G S.top--;
/ s2 u: ?5 r9 w! k. h return 0;
1 }' Q9 F. v% m S}
) _ j, x5 C( j' P7 R! W7 [) M
% I/ D, C4 B( c9 v+ h4 X9 jchar get_precede(char s,char c)% n( P0 X3 \1 d1 i7 t5 g
{
8 m% }8 V$ L9 P* f% J7 V switch(s)
1 b* I+ k( ~8 I* [- F2 q7 C3 R {; G. e8 v) H6 [# h d5 U
case '+': 9 i% d$ p, y: e3 ]; V: f
case '-':0 `) w( }+ t2 y9 q8 `( a, e
if(c=='+'||c=='-')* t$ h9 J/ y4 V# }
return '>';
: ^$ ^6 z1 J8 I1 j8 D) {3 B else if(c=='*'||c=='/')4 \. R+ g: n* z: n1 \# o _
return '<';6 o9 ?3 n1 L! h8 e1 o4 p, k
else if(c=='(')
" X( [- ~7 e! c4 S+ [8 ^6 D) v return '<';5 s5 r8 `& v9 B1 B! u0 ^
else if(c==')')$ [8 e. m7 @9 A. h& `9 V# l5 e
return '>';" Y- v2 g1 X$ I- X5 i
else
! t$ B( p, n; { return '>';9 L# U, c! a5 b: H" S3 C
case '*':
M' U& w9 D$ U; Q0 l case '/':; K: ^( d* v2 {8 n, {5 |% ~* u0 c
if(c=='+'||c=='-')6 K0 g" m3 j2 N' _/ N2 ]6 z
return '>';1 v: K! X4 h$ g9 v/ k9 B
else if(c=='*'||c=='/')" B- _0 r+ E* z; r
return '>';
" U+ K2 f* V9 N* G else if(c=='(')7 T% y C5 M* o1 h" x h" d8 |
return '<';! X8 G7 |, R. R+ a+ X
else if(c==')')
0 j. M6 Z& N1 y+ l return '>';$ A2 g1 T9 Q$ O- `! k4 _- ^) w$ n
else
% b6 D0 Q/ g l d! m return '>';/ f6 x* M$ T" K- O& e
case '(':) R0 D5 v o* H, @# P" b. q- A% b2 Q
if(c=='+'||c=='-')1 t: J3 F4 M7 K" B' W4 K
return '<';8 O W, S8 J8 l, B7 A$ f! ~
else if(c=='*'||c=='/')2 f) a( O# [: q6 b* U* c
return '<';3 i" _% u; h3 I
else if(c=='(')+ U. s7 b. S- W! T2 {( o3 v* \
return '<';
5 W/ W3 J2 m2 i else if(c==')')/ D% c+ i) B% d6 @& o) h
return '=';3 v; U1 `( E- W! z
else' n8 t6 b8 a& ~5 g4 h
return 'E';
* U. G/ F& B7 {5 r case ')':, O7 n. i% s" X% d3 G7 v5 ?. A7 r
if(c=='+'||c=='-')
' _$ b6 D3 m8 b0 c return '>';& J; ?' S2 m0 i! T
else if(c=='*'||c=='/')# v: ]+ O" }9 r: {: E4 P
return '>';# E. `: t- q( o7 T& Q1 m2 l
else if(c=='(')
) D. H' e v b4 l" S& k" Q' V' F return 'E';
' Y8 b h( Z7 E5 n. W" w2 R6 L0 h else if(c==')')( k( k% i; ~& x/ a3 [7 g+ j% |
return '>';
& Y; {+ t" p" R# U% x& Y else, x6 Q3 t% O( ^+ q% J) ]! Y9 J& D
return '>';% \. M5 `, I% k7 Y* a$ [! E
case '#':
7 r# t: _8 M. |1 X if(c=='+'||c=='-'). I5 W) A6 T4 t# \) m! u4 |1 _2 `8 l
return '<';; q/ V2 Y3 U- W
else if(c=='*'||c=='/')
) G ^" T# W( h' G" W return '<';
3 ~* F3 d/ u: H e" P9 o else if(c=='(')
) t5 M2 ^; m3 L return '<';
" |( T2 I3 C3 n7 G else if(c==')')
3 O, Z0 F: G& L) P" t2 ~# A return 'E'; Q* ^3 q( T8 p' e4 l) E2 l! `* \
else7 X5 i* v( C4 W* H- g3 h2 e
return '=';% M; k2 c2 T' h5 ?# N- c
default:
; E* s6 T- W& o. c* ]/ R; i8 a break;" {/ ]1 ~/ C, \0 u9 ~% O; S
}
. R' b5 @8 g1 Y) ?# J5 ] return 0; ' E# g4 g$ l* B0 K% s. |
}- q( L2 j3 f/ @( B4 j) j& u
3 f/ |0 ]/ g+ ^4 T: H
int isOpr(char c)& j8 {: I- J6 t ~( Y K8 A
{
- |; z' e7 w' g2 Q if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
4 Q* l5 N7 m: t+ J" L return 0;$ J- N. I ~) k- O1 s
else
" ~$ y6 C2 I5 e* K' `( F P return 1;
% |( ^* R: }; e1 | ^0 K! _4 \}) [0 G# ^- q! g D
- x6 j* S: v6 T+ Bfloat operate(float x, char opr, float y)
5 c5 N& g! n/ i* N{
8 F" C6 {( c# L/ x3 x2 K7 y float result;+ a+ F: X1 U+ F t; G
switch (opr)) ~+ i4 U/ c6 l R7 M, [6 c7 X
{
3 M4 v$ Y2 [6 D8 {5 W case '+':
" o4 N* y0 N; F, a3 P+ P result = x + y;! Q; P% \& q1 w% J8 g4 q
break;2 j9 c( i! o/ ?" n1 }
case '-': + |( d: b- T K- l+ |) }( |
result = x - y;% C: q9 k1 F& e8 l
break;
& K& [) ]5 I/ w' y7 x0 a' c2 i case '*':
. O7 I4 h, H- ^! r ?% c8 D; @ result = x * y;
9 F7 v4 ]$ M' n1 M break;
# ?# W# q) L& J) ~ z case '/': / G# S& B& k2 k$ [7 ?
if (y == 0)" A9 E7 x7 E# X; x% T V$ T
{
9 N8 `! ~( J; Q' B printf("Divided by zero!\n");* E. [* p# H3 l8 \: b7 p
return 0;
+ s, F0 H# [' B }
# A! I" g3 L, _ else
/ Y9 Z( x( K1 K {" |$ {0 {5 E! A
result = x / y;; R, H q4 ^9 Y9 G8 w4 C
break;
- e' [8 p# W2 i6 x5 j }
t9 p7 z/ @5 F+ o default: ( }0 j0 n! P& P; C3 u( G$ X* s" e3 u
printf("Bad Input.\n"); ' ?. p ^& u4 z+ S& R# k
return 0;% I0 a% j" B/ z' v, p0 Z0 m }; a0 s
}
- [- y' C$ w( T' b& K return result;# _: |- F$ J( }6 }5 q$ _1 W' d, h
}
* U7 L' p4 Y2 D9 L+ m8 V& F0 G# A n5 }
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
7 z/ `& G/ ~, J% g! V/ I{3 Y. T* n0 B; |0 R5 j, V
Stack optr,opnd;
5 r2 g; b- x" C @% |4 m# v struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;. t5 x- S' T3 f% r8 f# v
char c;7 |2 l6 L( N/ l) B0 t1 ^
char buf[16];+ D+ i4 R$ M" u& A( g; d! g
int i=0;
, c9 C' Z( ?8 ` 6 l, k8 D* p6 }% p) r* P! j6 E) D
InitStack(optr); /*用于寄存运算符*/
# Q6 n( |+ v3 N0 V) s i InitStack(opnd); /*用于寄存操作数和计算结果*/
j4 n" ^" M( _# K6 s: D memset(buf,0,sizeof(buf));! B ?0 O- ~9 z2 _$ u; D
6 B. x- ^3 B% Y, K) q0 s: S. l3 T
printf("Enter your expression:");
7 X, z; ]" K- d$ Q2 W
, W3 d! ~( r' v; B opr_in.ch='#';; D! K5 @7 Z0 l7 D0 i1 H
Push(optr,opr_in); /*'#'入栈*/
: a& V. T) P/ Z' O$ A @ GetTop(optr,opr_top);9 `4 `* q* e; {' o- K
c=getchar();
3 T) \0 v7 h+ b0 N& I) Z$ _0 a while(c!='='||opr_top.ch!='#')
. m4 w( j: @+ @+ T" L" z {# ]& S' P" W1 `5 {3 r5 ]+ h; J
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
q4 V q( ~! p5 O* O {
9 |) G8 C; e/ K& x% a0 ?8 w) t buf=c;, [, K6 }: t9 a' v2 R; x# @+ b
i++;# y" @, o$ o; ^, c- `! t
c=getchar();0 s2 o5 q# Q, O' @2 s
}
) H! c5 e" `; P# a8 o else /*是运算符*/
0 ^7 J6 ^! M+ `6 I) p {
6 A' u6 P/ g0 ?( k buf='\0';
* H: h5 h4 _, g) y if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
& ?9 b' X5 E: @8 V, E* e {
# N9 {/ f/ Y5 N t' o' |2 { opn_in.data=(float)atof(buf);! {8 \. |# A" I4 N! c6 C) [# [
Push(opnd,opn_in);
& c W D- A+ Z* ] ~ printf("opnd入栈:[%f]\n",opn_in.data);! ?& Z$ [2 [6 R J+ D
i=0;$ U/ b; K' c6 F7 d/ l o% {0 {
memset(buf,0,sizeof(buf));
( |' S# O; d6 |% U6 h8 D, Z) U, \8 L }4 a+ I9 N# _$ g- ^
opr_in.ch=c;8 M8 W5 y7 O2 U2 O
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
, a) H# y9 o) s& s0 ]' j, M {
$ Y9 n5 U& R) t2 i; e& ]* o/ M case '<': /*优先级小于栈顶结点,则运算符入栈*/- [- ?: z' g4 W0 n* Y) Y- E$ }$ @
Push(optr,opr_in);
" g/ b& E. _$ i" p# t printf("optr入栈:[%c]\n",opr_in.ch);
. y* j. l6 N( | M c=getchar();" T* m3 D( V" |: k' H
break;+ F4 t$ n3 @1 l1 ?' X) o: h' \
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/8 D& g0 ]" I5 f3 B
Pop(optr,e);
; o- g8 Z$ Z7 Y; F printf("optr出栈:去掉括号\n");
. L4 Y+ M. w% k1 w2 e) C c=getchar();# b" f: ^. b& ^
break;
7 q! r* P j2 v3 ~# n+ i& \5 C1 o. _6 _ case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/) l$ M) I! t8 k# H
Pop(optr,opr_t);
4 p9 @- ^4 _1 o i) r: z printf("optr出栈:[%c]\n",opr_t.ch);
- X' }8 P5 D6 E3 F8 ` if(Pop(opnd,b)<0)
# b# z8 g! U4 t0 d% }; d {
F$ u% ~* _, G' e# H* X# X; I! s: d printf("Bad Input!\n");# ?# b, K* n) N4 |& u: T
fflush(stdin);1 Z" \) ^7 X+ L0 q. | P; X6 z8 w. C
return -1;
, w' \# |" v1 ?1 C8 X- E& y; B }
! b) ]- Q. {7 @" L% W: B printf("opnd出栈:[%f]\n",b.data);
" |9 B. O* R: h3 X2 i if(Pop(opnd,a)<0)5 c% \7 ]" S3 w0 u
{
; A3 S; f" y/ q& ^) W& j2 H printf("Bad Input!\n");
& S8 ^5 _! B7 R) i( g5 J fflush(stdin);- T- y O1 I9 z) t* _
return -1;
, R( q& S- ?+ u5 \" ^) D5 P4 g }2 b! v( N" C# u9 s, i% S b9 B
printf("opnd出栈:[%f]\n",a.data);# ?, O8 K g& ?- C
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/" U8 g* X) o6 {( A! A" |5 {
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/9 |# ^( f# u* ]. \& [- q
printf("结果入栈:[%f]\n",opn_tmp.data);* _* D3 b. H0 Q6 L" I- F
break;) z6 z2 ?' l3 g: D* p# y
}% k8 z1 o# U9 y# e
}
' q5 C9 G" u5 t3 s, z" f GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ / P! R |9 I# t) M* y
}* k0 P/ k7 ?. c: n8 B, q- L
GetTop(opnd,opn_tmp);8 ?3 @, f( e! t* x8 K" a8 y
DestroyStack(optr);
8 r, o* j; A0 \2 N' A% y DestroyStack(opnd);
% r2 D" N- B3 N9 V9 w return opn_tmp.data;
2 ~" [8 F; \7 v1 K* W8 D2 i4 ^}
" U8 i' b' Q* K: m2 L
: J' ^* U( s! B6 echar *killzero(char *res,float result)
; K9 F: g& o5 N) E{+ K$ P L( C$ A6 c
int i;: d, q% m& R/ M7 a. \# g
1 F$ `$ k# i# a
sprintf(res,"%f",result);% P6 B( Y0 ]) Q) g
i=(int)strlen(res)-1;
" s9 `7 i( u7 G2 k+ ]* v while(i&&res=='0')
" ^% l; z; T- L K% v5 D, S {; L }( i# Q9 k- Z! L( r$ z$ @
res='\0';
, o0 \! v) V+ f2 [ i--;) ?7 F8 C: o& I! ]2 @4 E9 b6 q
}$ \ G4 `' g+ `* A8 g$ D9 ]
if(res=='.')
2 Y* B v# q5 ^ res='\0';) f8 w* E; r6 [: p- q% J
return res;
$ G9 i9 w3 z) S- u* k+ j$ o}
* E- } @; h# s% D: }% b0 O: y+ r: X/ D4 w8 J
int main()
2 B% [4 \. e1 ^1 Q8 a5 ]! l' a{
2 e0 m9 X5 [2 u5 J* W- E( q5 T char ch;' F! [0 ]& F8 I4 d: r
char res[64];
) s- M4 Y5 u8 p* g float result;$ S5 g$ D6 o, v0 T2 ?
while(1)4 H3 M1 r) X2 r# W( k
{
) u; g m3 s( r6 q2 v$ |6 r9 W result=compute();2 I* g2 s3 M' r8 T
printf("\nThe result is:%s\n",killzero(res,result));
# ?6 S, \- M3 a1 @' |# B J4 D printf("Do you want to continue(y/n)?:") ;' Z8 _- L) o. G3 {1 Z" G2 z
ch=getch();
* Y" o6 O3 |5 n* s3 r putchar(ch);
/ W5 ?$ g# i5 b* U! @ if(ch=='n'||ch=='N')
, U% W- k, n: [/ r8 h break;$ u Y# r' \7 r! I$ A$ p
else- {. G" h$ U! O3 |* F
system("cls");5 z' F' [9 q$ E& ^6 W y
}& o& B) P8 y5 Z) y
return 0;
/ @3 x' ^$ C* q1 k9 n/ L$ K3 ]' `}% N0 }7 ?/ ~' u* P( q& H
1 [4 G4 ~' H$ Q
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|