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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.0 c& N1 k. S2 y1 }5 _' g
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
& V' s/ B& x$ h, ]5 Y/**************表达式计算器************/8 f; l3 l( e# c4 @
#include <stdio.h>
1 ^3 T2 I" f$ Q, U#include <stdlib.h>
2 w# r# S; a3 K#include <string.h>: h6 ?& m3 a' a; U7 l
#include <conio.h>" `8 Y, V$ a- y6 j7 O
#include <malloc.h>
! f( z$ K4 i. X9 C" \. l6 d$ z+ a" g: W0 }8 |* k! C
#define STACK_SIZE 100
& K( T% M8 L, L5 T#define APPEND_SIZE 10% O8 n" n o$ J. M8 I% q! G
: `+ J3 {& Y! i/ d5 k' @struct SNode{
4 \+ }# ^! ]1 z1 N6 [/ O4 t! m float data; /*存放操作数或者计算结果*/" Q% \. |3 K5 j6 Y/ G' J
char ch; /*存放运算符*/. i# z, Z/ u0 C) w
};9 P8 d% [- l0 b
! w" M& P7 V' G; o9 cstruct Stack{
7 x! x5 {! ^+ k% a, i SNode *top;
9 Z9 F; r+ l7 z/ T9 m% g SNode *base;# Y) ]4 o9 [6 M3 W) R1 q& }( x
int size;
/ Q. r/ t7 [" b) r) u4 F2 i};
( f6 D( |" p% V+ X! w- P' s
% T9 t6 t3 `! H# V" a9 Y: V/*栈操作函数*/
' _" R1 {) D# ]% cint InitStack(Stack &S); /*创建栈*/+ D+ S# Y- \+ r/ C/ z+ _
int DestroyStack(Stack &S); /*销毁栈*/' Q8 ~9 \) |4 _' x
int ClearStack(Stack &S); /*清空栈*/" U: A" x; P9 D1 S) y
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/1 \ _7 r1 A. s) t- V2 i
int Push(Stack &S,SNode e); /*将结点e压入栈*/4 t3 s; v$ b, U1 k
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/, t+ O/ D4 Q5 i: z$ \9 z
' L! M7 m4 ~2 Y F/*表达式计算器相关函数*/" W$ Q) Q/ Y2 t+ V$ k+ m& V
char get_precede(char s,char c); /*判断运算符s和c的优先级*/! c( u4 a" @6 p& S: B: x* |4 T
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/- B) Z( x" j! a
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
c8 B4 Q+ t& \0 ~# ^& Cfloat compute(); /*表达式结算器主函数*/# T- N5 r4 t. ?$ T8 B, W
char *killzero(float result); /*去掉结果后面的0*/
' x. I6 S2 R+ w! ^: z8 l$ L2 L* b' z) Q; @: o8 k- l9 R
int InitStack(Stack &S)" n' T' q: |. ~9 b
{
& ~$ v; g/ I, [% ]; I; S S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));- d2 M5 k: P) b" H
if(S.base==NULL)
~3 w$ l3 I/ x. U6 [$ |+ ` {
4 b0 J9 @0 N' A9 d printf("动态分配内存失败!");; w6 X! N- b3 v( x
return -1;6 ]% n/ P+ E- \# y% u6 {* R; T
}
; s9 N& Q( t; o3 N" w0 k S.top=S.base;
6 x- Y5 p3 p) n: \+ z' o S.size=STACK_SIZE;' A/ r+ ]; S7 u1 {1 W$ v
return 0;
5 L# B9 t% e) X/ q, I- P" l}
8 h' h9 @. Q! @& a0 I% ]& ?5 O- X+ Z0 k) F
int DestroyStack(Stack &S)
) n$ b A% t/ U{
1 s$ Z0 c2 v: P/ F free(S.base);; b% w. V0 Q: ^. F |
return 0;
- A4 ]0 O7 Q s% p% _- Y}
9 L) y% d8 y7 \- j) n: I' b' ~2 E
0 C" }1 h9 L6 G! w/ b) ? m! x7 Rint ClearStack(Stack &S)2 `2 F1 {. T' S9 @ P
{
8 J2 x* w7 W- T9 O( c. S S.top=S.base;: w. ]4 ^! P5 o# ? w% W
return 0;
- Y% x' m) b7 r3 c* w}
7 a0 Q0 g w9 f0 }
& r# V$ C5 v7 O3 {, }- b( Vint GetTop(Stack S,SNode &e)
v" r6 C0 @; z; i0 R% x, ?{
* a7 S; D; @# c" E4 S1 r, U if(S.top==S.base)% t' K- m5 F/ c9 t
{- c" _- M5 z" Q1 |3 X; Z7 R& U0 d
printf("栈以为空!");
x. r; i* S6 U* z. n return -1;* C+ X o5 @! y; R
}1 n" x$ ?7 _& t* n8 d' p
e=*(S.top-1);
: R- k) c/ C4 |8 U9 M/ c6 R ~ h return 0;
; j ]/ C# l1 q; x}. b) Z/ Z4 X0 s8 U9 a
' P4 M& w; b3 ]* C7 J v0 h3 K
int Push(Stack &S,SNode e)" G! C6 q6 a7 G# C$ |
{
# U# a7 V( W4 [, I+ r& G$ n if(S.top-S.base>=S.size)
4 f( v- O" u) P( ?" z: f/ @: H! r: C {
" @) E3 X( S- _) w S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));! O- k* K" I( K" ]( O9 G
if(S.base==NULL)* U( P6 [& z+ B2 L
{, ]# Q, n( z* O/ A7 O
printf("动态分配内存失败!");+ J* a5 i& m8 j2 G
return -1;
3 F1 k: ]+ p8 r# \/ ` }
- b7 M5 m' c+ U- o" s S.top=S.base+S.size;3 N, E* K# {) c4 o
S.size+=APPEND_SIZE;
% r5 o) x$ D6 {* T8 z }( B! v2 x& y6 t: j- t: K+ t* n
*S.top=e;9 n) e+ D& _! @( J% u+ x7 a
S.top++;$ ^% x3 K6 p: d( A. f/ w3 Y
return 0;4 a) }& y2 `& J+ u% b( e6 Z
}
7 }5 I6 d$ Q4 e& u6 A7 R; K3 i' ]$ [/ p4 Y3 J) [: m
int Pop(Stack &S,SNode &e)
7 I* P# r- B7 ^, k{: d7 y) O/ \# R1 ]+ A
if(S.top==S.base)! t. {" C: p5 f d7 u
{
7 K+ b6 X! o+ U# K0 f5 k( l printf("栈为空!");
) z4 Q9 ]& z( L" j: L return -1;" f! _! x) R, q3 q- v" M' U1 S z. f+ }
}% Y$ T) G7 S& V" p
e=*(S.top-1);
/ ^( v* a( k, ] S.top--;
3 ^$ D2 K0 R- j! `, O return 0;+ k1 f0 N7 f& X
}9 L. }3 u1 j0 }4 E, ~( y9 @
0 B' l, E( @4 c, tchar get_precede(char s,char c)
. A" p: z) C" F4 B{
# T" ~+ z* R" w/ G0 v) w switch(s)- m1 n/ \! Z0 r" ^
{
" l: C' E/ r3 I6 U2 S case '+':
; R$ G1 r9 t' F# \# ? Y( Z case '-':
$ X% |. u7 b8 J) m/ U if(c=='+'||c=='-')6 b4 J1 ` {) u+ [& Z3 e0 v
return '>';5 a( ^# {! {: R- W$ Y1 C7 `
else if(c=='*'||c=='/')
2 r: b$ d5 J$ }$ D1 n! t return '<';
6 ?9 C b' l+ L) o' v/ r( h else if(c=='(')8 ]* ]1 c! w% I, Y5 v
return '<';" M+ O/ y5 k- P6 q: U( e( _
else if(c==')')
+ ?) H# |0 i2 F return '>';) x" S! _" ?2 a' T; k6 }! A( R% v+ w
else 2 l0 k" p* a# d
return '>';
0 m- a' `/ r- R; }2 q0 ` case '*':. t' q; m W6 _' Q7 [ x
case '/':: V) I4 }) }4 T$ p/ j$ w
if(c=='+'||c=='-')
( M0 X* g. J: G0 V; a9 E return '>';) ]8 A, @+ X# b' k
else if(c=='*'||c=='/')- h- |, L S9 q* D! f# d' @ u
return '>';; _$ [' h& ` c3 \6 ~& ^8 E- h
else if(c=='(')
- M: |- G* z1 Y0 B, G; B' c, F return '<';
& I- N4 o5 _" }/ l else if(c==')')
$ d+ w! v2 H4 L9 Z5 v. f1 j return '>';! b+ I) E( q4 e3 ^
else
8 i0 h! |7 X% K: F$ o1 X return '>';
5 T' }3 W! e/ {3 y0 X5 O case '(':. T# L' ^1 B* p& p8 J
if(c=='+'||c=='-')
1 o# E7 q$ K- @5 C return '<';3 n9 p1 P, `3 w: q% t/ D: f
else if(c=='*'||c=='/') Y/ @1 ^9 }& C
return '<';
$ B; t: n! \3 Q9 Y' R: A" K3 Q else if(c=='(')
8 Z9 `; h- y! S/ \: W return '<';
( A2 Z1 z" o; G7 n) @# v else if(c==')')2 L3 @6 T" n p, s! y3 W
return '=';
; o$ X5 Q M+ Q! H( J! q$ c$ K( u else
* U( m2 {5 Z7 n return 'E';
8 Y( _4 |. ^/ X0 ]" Y; o L% I" X, W case ')':
$ f6 n3 e: c+ S, x+ H if(c=='+'||c=='-')+ m0 L& O5 A, b( m4 u' D' t
return '>';
5 Y* R# ^: n0 b else if(c=='*'||c=='/')
) @9 `1 z/ I5 h) J4 C2 u# z return '>';
3 u2 h1 j; a2 Z0 c else if(c=='(')
2 I. q+ H% e, R8 F! G' n return 'E';
/ e0 z2 x6 k% G$ P7 f0 w* u; G9 b) ^9 u else if(c==')'): h- z+ J1 K S% s
return '>';
- r, G2 q2 r5 V1 m T3 i' S D else# r0 z& K7 j* O( f
return '>';! Z- |7 s2 C/ x' y( l$ y
case '#': ~2 @% ^ F$ N* R5 `' k* d
if(c=='+'||c=='-')* b2 h. o: j% n& ^2 a8 P
return '<';
% Q$ s/ R) h/ L% K! O+ Y else if(c=='*'||c=='/')
% }5 m8 B1 t0 E! n u) b. A4 \; @ return '<';; D% T9 `4 S% ?. I7 P, l! I6 z" ^6 M
else if(c=='(')
# P6 k$ f& ]' [1 o; } return '<';
9 A, u, G! ~) o# Q$ y else if(c==')')! e. x5 t0 q$ Z8 _3 k
return 'E';
* y: Q1 B( v$ [! @, a3 B4 b& r% h else) t$ V/ `* o2 M0 `6 Q
return '=';* v! [9 N! C9 ]4 m+ P, r; X; U: `- n
default:. E+ t# W/ T/ ]- K N$ ~
break;3 {1 [& u' V& ?- M. ], d S
}
3 u( l! f8 q6 P* j return 0; # H+ u3 w7 d" ` ^+ p* J: [
}+ H! Z# w8 M$ P; O+ \
% ~9 t8 o. s4 B0 L; r" j" Mint isOpr(char c)
/ L& Z1 U% @* c0 w{
9 m1 Q' ]- @4 T; }: b if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')& W2 S3 Z; \3 j5 {* M+ F
return 0;
) Q% ?6 L1 l5 ? else
) L5 b( J k0 G4 E return 1;
2 N8 O( K& X' Z: L}8 S' ]8 d, ^3 A
- s% [' @% H! }3 wfloat operate(float x, char opr, float y)
, o( y" B: g- I6 f) j ^{0 Z: n, i9 W; s- L6 [: b, c& x
float result;
+ H3 h1 F# f: r3 }& \4 b3 h switch (opr)
' L" E `8 T/ |. t! W: e. g: { {
" \4 _9 k% x' q q0 B case '+': * Z8 t: H/ L. H) [0 W& w$ d
result = x + y;( d2 g0 @, p/ I8 L5 T
break;% u0 Q# y' ^. e5 u
case '-': 0 K& A1 E/ Z# x! V: Z9 Y, u
result = x - y;
# Y' n. J8 ]( k0 t& a" @ break;
) g& Z/ ~1 K9 s. u2 a- m* m% O0 x case '*':
K9 H0 ^" Z) ~/ J# I& B result = x * y;
w d, S" k7 j1 k& j9 T: d& H break;7 z3 i' ?. r- N- ~
case '/':
3 r, ^& f0 w' g if (y == 0)
$ W6 \8 V% I$ x" `0 y# _; s" V B {
2 Z1 w& z( }% w9 q R& J( h; K printf("Divided by zero!\n");
/ r7 o- Y: j) d# c7 H# { return 0;, H( H- m: a5 o0 T/ x% p
}
. X/ S2 H a, I else1 [6 y% i! A3 Q. u# m. o
{
# Q4 k6 y# l7 E result = x / y;( Q+ }) q. }( l/ [7 B& J4 E* A
break;& p2 o G# H+ R; W
}3 O c/ b" J |8 k2 b0 Q. k$ }4 y
default:
$ N) s: n! C: C! N$ r+ @6 t printf("Bad Input.\n");
" ] b0 r$ b) `0 D5 t' I return 0; z8 @0 U: R. E
}
1 ?, j3 f+ P2 C, G1 `, ]* l3 K return result;
; J) J( K/ r8 z; {9 m3 N} 3 j$ |* p( v" y" l" M4 ?
& n& j2 ~' }- L+ `9 M6 gfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/- g! }; K5 b. e( z0 c
{
% J; H) l6 _' P8 d% u Stack optr,opnd;
& k" T. Z+ W4 b4 E" i. _( _0 s0 t3 w3 _ struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;1 ]0 K% Q9 r8 D1 f$ y+ {$ b+ B; b
char c;* e E1 s; i* ]; A t
char buf[16];2 w0 h5 | D9 Z% c
int i=0;6 O( M; e. a( O8 T z* w6 g" O
$ d& s2 e0 @9 { InitStack(optr); /*用于寄存运算符*/0 ]' C8 u2 E4 z
InitStack(opnd); /*用于寄存操作数和计算结果*/3 g/ s& [* J+ q- p: N* m
memset(buf,0,sizeof(buf));
$ R3 f" r( R( C3 ?5 X, D
+ _6 }8 L9 X- F* R$ x3 }! F0 N) g" O printf("Enter your expression:");
. n6 B% J# J, f6 g' ~4 e
* Q m, w6 }; Y opr_in.ch='#';/ P; k/ i5 o' Q4 U' A* G6 e: B
Push(optr,opr_in); /*'#'入栈*// z ~6 h Q7 c$ }5 M6 {# [
GetTop(optr,opr_top);& O7 L) Z8 L+ c! E2 B6 d9 C/ V
c=getchar();
2 L% I5 L$ u/ j5 K# i) U1 f2 F while(c!='='||opr_top.ch!='#'). u2 o& _( \& `3 F+ W- C
{. S5 P% A' k; a _/ D( y0 `
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/0 x+ e, J5 Y4 j X% B$ n
{
/ l' v- w% Z Q6 g buf=c;% ]$ v y, }- j$ G
i++;( z. J. X3 d( M
c=getchar();
' o0 e1 ^, r% w8 j& s8 [' D4 q }+ l' h( X$ [2 E4 I* u- W
else /*是运算符*/* H6 F2 n h! S3 i# ^6 U# N( d
{
: d% o! p/ J+ {" k buf='\0';
% ^; e1 m, b9 a7 P+ a3 P if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/2 F8 d4 T F: g/ E# b
{3 U" ~! F( P* D% w
opn_in.data=(float)atof(buf);# ~1 z& `! J% ?$ U" s' Q/ N
Push(opnd,opn_in);* u1 r- i' I( M3 G. }$ e
printf("opnd入栈:[%f]\n",opn_in.data);
6 a F" }3 p) L. S$ M0 S: o& ^6 f i=0;
; w; [) ]3 J" `* D1 Y( s8 m memset(buf,0,sizeof(buf));4 K$ w' N$ z+ E! Q# k
}* p. }: |. l$ W% T* k3 y
opr_in.ch=c;2 q5 L% _9 H9 j( ~0 {' I+ b" [/ n
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/& K- t6 p! j( {+ c7 m5 \! j
{0 N1 H g& t4 [* y. P) N0 K$ T
case '<': /*优先级小于栈顶结点,则运算符入栈*/4 Z% l7 w, t6 j/ h
Push(optr,opr_in);
* G& \- \, q# O* _' v6 n printf("optr入栈:[%c]\n",opr_in.ch);3 o: K" j/ o% Z7 z, \3 ?
c=getchar();
7 B b) X/ l. u9 J( v break;$ U5 G8 R4 T+ S8 D8 \: m
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
+ ~8 T9 }/ C( w4 O$ T6 y, b! r8 X Pop(optr,e);
# R8 V4 E, ]" B, v; l printf("optr出栈:去掉括号\n");2 ]9 r" o% @, t4 i0 B
c=getchar();
+ l @! _+ _+ Y break;9 k/ \7 d* K5 L0 `7 r% U" x
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/6 t( l4 m: o5 X# E f+ L- Z' s/ P
Pop(optr,opr_t);
3 Y# f3 S; [. {# i# b1 S8 N printf("optr出栈:[%c]\n",opr_t.ch);
4 {: L. t. D, y$ O: o$ Z1 G if(Pop(opnd,b)<0)
& E; ? \3 E @ {3 s7 a; m& }2 n! j% b6 n
printf("Bad Input!\n");+ E4 F3 V5 |( d, K
fflush(stdin);" q$ c$ R& v- J8 v) ?" v
return -1;* p1 \* _2 c- D, U/ ]5 q
}
, l6 u# u8 x/ I( [9 D0 q printf("opnd出栈:[%f]\n",b.data);" p4 Q! A& H( c; I
if(Pop(opnd,a)<0)
4 L- d# j I6 t) K H {
w% w* @% _" W; r0 Z printf("Bad Input!\n");
V) J; O5 O9 z8 M: K fflush(stdin);
" m" T: y" [; n4 f( {' @9 w return -1;. b7 |8 u/ p+ V q* O2 i6 }. g! j+ |
}
; w/ a3 A) [% z' n6 s* H) l/ y printf("opnd出栈:[%f]\n",a.data);4 i0 d! k/ b3 L( o7 u$ F. ^" x
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/. h2 O) H4 ^7 p: |( w
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
; T3 m$ q6 X/ R# W printf("结果入栈:[%f]\n",opn_tmp.data);, u& S6 e3 W5 g
break;
1 p M8 B( @" A6 C! |0 ?& r# h }! t9 J7 |7 Q# |
}
& p4 C3 z+ r' @7 U: `- j/ r GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
, r2 }6 F2 R. |" T }
: ^; q5 D) |2 }$ C GetTop(opnd,opn_tmp);
$ y( g; s* E7 I9 C6 k* ^ DestroyStack(optr);
: y7 l1 k! X! S DestroyStack(opnd);6 K' y; i" O2 p! L( @
return opn_tmp.data;* D( |' S' B+ y0 x% j7 w: I
}( B; q, X/ ~5 T: p. i9 A8 S: s
2 U' `, Q/ n9 [: I( y" D
char *killzero(char *res,float result)9 N4 Q- j/ M. j- }/ W$ o0 z
{, l* ]# ?9 t K( e8 i
int i;' f0 t% e- T$ f* ?' t4 w
. l; K3 j2 V( W8 r- s1 f( @ sprintf(res,"%f",result);
1 f% o7 w" {8 u- n+ ^# x i=(int)strlen(res)-1;1 i q8 g" n- W6 \
while(i&&res=='0')# z- D! F) c2 X/ g d9 S, R
{
* D4 j8 F- E& ?2 H res='\0';
) b$ k) t) F; J, S) B9 ^ i--;- r0 |3 K. z4 D% J3 y# k
}
+ X) k% U! d. Z1 P; N' G if(res=='.')2 ]6 t- ~2 g6 w N1 {) i9 U& K
res='\0';+ g, l$ h. L K4 T8 F; A5 n" Y& x+ V
return res;, }; W* Z. J' l9 K
}
j4 O: n5 d" s5 C. W. i7 ]# [8 K; O9 H7 ^
int main()
( k' r2 y9 i/ p6 G' \{. X) h3 Z( K3 P3 g
char ch;& l! M' }7 y% C# v; c
char res[64];
) I s* r9 {9 f g float result;& |8 U3 t& h5 k& b H) c: d
while(1)
3 _- h: X5 W9 r3 y- X {4 L: [0 L* W7 O3 G/ O
result=compute();
3 `; J6 @" d0 g: A( X- i printf("\nThe result is:%s\n",killzero(res,result));) A3 o6 M8 R2 B& t4 O
printf("Do you want to continue(y/n)?:") ;
/ g5 {* V: N; F$ U9 |- l ch=getch();
5 w1 v# S+ E W8 |" h7 w4 Y4 ~ putchar(ch);( @ m+ T0 k. G; j
if(ch=='n'||ch=='N')
[$ y2 \8 Y- c! e) i break;9 ]. O" @7 ~3 P8 ^; z
else
* C8 |5 \( z6 o' k: {8 q5 O) J system("cls");1 Z* v- ?- p: N# f
}4 T# c1 i5 a7 a" K
return 0;3 y+ F7 B8 f' ^) {' [2 K* b8 J
}4 ~7 G+ U5 l8 w% ^, r% W+ B* {; G
# |" k5 l ?: ~[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|