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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.9 ^4 B4 @( k# O$ ?3 J3 i6 j! W
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
) Q; M+ H# }7 l; E+ d2 X G) o% P/**************表达式计算器************/
/ b0 @) H' R9 ]- D#include <stdio.h>
; l' Y3 d. V. [# b#include <stdlib.h>2 f, n4 ~1 Q- u5 i! P- r
#include <string.h>
8 u/ {2 r7 }9 J) N$ ]#include <conio.h>
& R2 o: H. I8 u/ M; }#include <malloc.h>$ e" v1 K1 i6 Q9 f- x. Y7 h( n
. a p+ K. E }, ?- D0 V) p& U' `
#define STACK_SIZE 100$ s2 F( b* r8 C6 H& S/ h
#define APPEND_SIZE 108 J5 H2 A% D; \% n+ p
U6 Z9 q( s# T$ R, T# b3 |5 h5 Q
struct SNode{5 @* ^, z, t. g7 G# l$ ?9 k
float data; /*存放操作数或者计算结果*/
8 Z( @( w H# `$ T0 `- ?6 N! ~ char ch; /*存放运算符*/
7 A; X# C8 w' |$ N* n' {};
& k! G r w6 y" g' {8 p4 d- k; n0 Q* `2 W
struct Stack{9 A( T' E; D- |# q7 O
SNode *top;* I' B) K) H7 g6 m9 b
SNode *base;
; z, k$ P* l. Z+ `6 P int size;
8 z! J+ h& l# ~7 W};; {! Q! O \: [" N5 w6 Q
" n9 u: P: B+ F- _/*栈操作函数*/$ l( b0 J) y5 p+ S
int InitStack(Stack &S); /*创建栈*/& A$ }5 U$ Z% H1 U8 K, r6 |; J
int DestroyStack(Stack &S); /*销毁栈*/
3 ?" F' w; f6 n* W$ i& m' i: Kint ClearStack(Stack &S); /*清空栈*/3 d3 D) P1 ^! _& z9 Q/ \7 o# M
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/4 C9 l# E+ f7 ?, \" `$ @' x- z
int Push(Stack &S,SNode e); /*将结点e压入栈*/
% n+ V# C% ]1 Q/ _int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*// R P- l ?. }: C- m
$ F- g! r# L) p; M, P; ^) c1 M, B" D) x/*表达式计算器相关函数*/. K8 h9 N: y7 t! }5 h
char get_precede(char s,char c); /*判断运算符s和c的优先级*/& F# P8 y3 D0 A( q5 @- d
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
6 ~4 f3 Z% U- I& ~& `7 w, _float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
" [6 t+ B; q5 \6 ]7 xfloat compute(); /*表达式结算器主函数*/6 a- y+ ^/ T' |, }- y
char *killzero(float result); /*去掉结果后面的0*/
2 @+ k V* I2 A8 e
; q: X# n' t/ m- t! i0 Kint InitStack(Stack &S)" x0 A' z @( C, x
{
! n H7 A) X) p" k% R E+ @+ E S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));4 }) f) l& a$ a+ ^2 U4 d4 D! Y
if(S.base==NULL)5 r7 Q+ c" }+ X$ G. ?% }
{
, R4 J; B) L- r, x printf("动态分配内存失败!");/ w3 p( d! B, z# j0 A3 Q
return -1;$ C0 ~: l$ L7 ^; y
}
. @% Q' T7 L" Q S.top=S.base;+ m6 W: {! z& E8 o" G
S.size=STACK_SIZE;
; ^5 E: `6 y% ?- x& m return 0;
+ x& A& z( J' z, t}
9 o6 J, J" \# K9 ?- h" Y) ?8 V! Z3 g! C+ [
int DestroyStack(Stack &S)8 B7 [6 s3 K6 Z. M' s" A
{
4 N8 s# X# q3 _' i, r) Z; ^ free(S.base);4 Z6 t& \' W& y8 \1 z. }% k
return 0;
; m z. a3 ]2 J ?) S5 Y/ s* e}9 N* D. F* X+ A4 [7 C
& I+ g6 B; ^: h* \8 _
int ClearStack(Stack &S)
8 A7 H2 X4 |% S. U# X/ x( Q& q# I' z{2 C( N9 {) h4 G0 ~ D4 J
S.top=S.base;
& \! @ z5 b2 m1 G- F+ p return 0;
4 Y2 O$ z/ g7 A% Y5 P* j}7 P [; u7 p9 a8 A3 X: h$ x
- A$ w9 u- @' I/ a) A. ^4 @; Q0 y/ G
int GetTop(Stack S,SNode &e)
5 f' K' d: A7 Z' ~! v{4 I; {; W4 b' G1 A* _- k) a
if(S.top==S.base)
7 n1 _0 g, E2 ^" f+ U g {7 b) P4 X2 t9 V, O
printf("栈以为空!");( }* Y! F w- g
return -1;0 y/ r4 S" R! x
}
6 g& U, G' y& J& ^5 A/ q8 v | e=*(S.top-1);
, Y0 U7 P: P/ [8 u8 V- i return 0;- w% P# d9 f' R; L6 N0 D
}
7 X+ Z( ~8 ~+ X: F# \: {* i* s
0 P8 A, e" m1 [. P! M3 mint Push(Stack &S,SNode e)
; q3 N6 ]5 k5 v# T( _9 B{+ y, ^8 H. d! G6 P- v6 {0 Z
if(S.top-S.base>=S.size)
( Q/ g# N" f7 B/ M1 i9 K6 S4 w {! d3 t; C/ N8 r, X
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
* K; ^9 l) Q" B+ h6 z0 | D if(S.base==NULL)9 g' w' J$ p- y- G
{" E" }( A! U5 y# Y
printf("动态分配内存失败!");
2 D3 M5 d7 Y9 {+ F" \9 q+ b7 S4 Z2 T! C return -1;
4 m) l& N$ v* A0 W }
" A6 x4 N9 U4 a S.top=S.base+S.size;
' U' G- y- @8 a! E- V S.size+=APPEND_SIZE;
7 ^3 i- m& e% S/ ]6 i }
5 n( F# G# M% K1 M* S *S.top=e;
. U6 J$ c6 r! {6 Q/ L2 a- w+ V9 V- y S.top++;0 C8 W% U- v) P
return 0;$ M# |/ l% ?" e) b* W4 `$ o
}
' U: K" ~0 n1 F" G% M9 z! z6 o
- \) Q0 O9 z+ I" t# yint Pop(Stack &S,SNode &e)
6 `; V( ?% `* M% J{
8 ?) N0 K/ i8 V7 J( D if(S.top==S.base). D) d8 L/ ^- `
{
- z" b3 C: O3 @8 U) J8 e printf("栈为空!");
3 M3 s+ ?. D- G, k5 W- v return -1;
7 Y6 B4 b h N" a4 a8 q% f7 ` }
/ Z- i. B8 j9 E- A# H" | e=*(S.top-1);* \: ~; C( B# ^7 z- E& o. \2 B
S.top--;6 r4 {/ c1 q: U& k7 m. d a8 }
return 0;) D8 u9 S. ^# K- z$ P3 I
}. S( c( O' m3 {# }0 z- G2 W
! a% Z3 H- U( s) y* o
char get_precede(char s,char c)
4 c; i- a" f8 n1 N{6 `8 X: t% V7 F: G
switch(s)3 l/ s+ x0 E/ @ y% ]% V& E
{) R" N' l) X$ D( K$ h7 s R
case '+':
- ?/ J3 p/ Y k8 T" `5 G case '-':
3 _1 G7 E& Y/ a( h. M# j if(c=='+'||c=='-')
2 Q9 h) Y' j" c( E% e return '>';8 D1 u3 v' Q4 H3 A k& ]: D* B" s
else if(c=='*'||c=='/'). I9 g8 { e; f9 u
return '<';
0 N6 @1 O$ v4 s$ k4 p else if(c=='(')
7 n2 r/ o$ H# G, |% i1 U+ g: B return '<';
/ B% H7 g, N( w2 H. q( x else if(c==')')5 f: a4 i! ?8 F4 L* Z+ v
return '>';
' {8 R+ H( Z. q; E else 3 ~; s' m' k8 \3 A% v+ S1 P$ p
return '>';
9 I6 I" W: k' F2 ^: [7 y case '*':
8 R# Z1 R3 f* V+ K case '/':% w) p) ^" h; @. s0 G
if(c=='+'||c=='-')* T, A9 D- R0 ]# `' C: X
return '>';# r% s* K5 A" a5 |/ w
else if(c=='*'||c=='/')
; k* N. y" q' |& f, Q return '>';" b6 H7 c! E6 ^2 y4 ], B) e
else if(c=='(')7 p! b% F0 o" U% O
return '<';
* b9 T) }: _/ M4 [# T7 |* l) c else if(c==')')
4 c! Y+ o, ?( {( D, N return '>';' E4 m% {; }6 Y
else
1 a! ~3 r' y2 G2 Y9 a+ E6 \$ }2 P return '>';
2 z3 j# i+ x2 |6 e case '(':
" e; N5 S5 v/ D+ X! B& O if(c=='+'||c=='-')$ |# V0 ^6 N6 d/ I
return '<';/ ]. W- L+ N7 U
else if(c=='*'||c=='/')" y2 k* z3 S0 H, {$ ]0 W* h) `& E2 _
return '<';
1 |8 G3 J, m2 {$ J' E7 w else if(c=='(')
9 v6 p& k9 z. z8 f$ A, }; C return '<';
) \0 n* g9 h5 D3 c7 K$ v( W* Z else if(c==')')
8 a7 ]* J9 f2 D return '=';
7 o9 p, u2 \7 l" S* O# X else$ ~, p# R3 f% w' T
return 'E';
+ l1 G) }: Q0 x0 L case ')':
) P* ^5 T; r3 j' S0 A3 a if(c=='+'||c=='-')& r; I8 `7 k5 w" r: q9 W) l4 C$ S
return '>';
2 Z$ `7 ?2 t$ @0 G8 I0 m else if(c=='*'||c=='/')/ `) u. I' O! d5 Y/ C* w
return '>';
! e& m5 J/ S6 d2 c. V p- _ else if(c=='(')
( s0 L! c( B$ C/ t return 'E';
/ Y+ f# A$ i4 j) A H else if(c==')')6 R* b. u# t3 K- W8 v; p" i- G/ t8 a
return '>';
1 w X! C7 l% B else
! e( Q& u4 A0 g8 S3 J/ y return '>';) v7 o% Y2 a2 A# f! c' j0 j
case '#':
5 v8 a6 B4 i+ c2 A" m2 e$ \ if(c=='+'||c=='-')
P0 I6 |, h Y3 z return '<';
' V6 q- f2 I# u! Q' b. p else if(c=='*'||c=='/')0 z& d) ^2 h# z
return '<';
. t: B" ~ s+ g else if(c=='(')
- V3 @2 V% c7 j, ?( C; ?, { return '<';
2 V8 w% v0 ~4 ^+ M$ C+ c) Z$ N/ Q else if(c==')')
# `( |. D% _6 v @$ ?1 E return 'E';
7 s$ ^5 e# b( s, P, ?2 p else5 h/ D% I% w0 ?* a1 r* h9 O
return '=';5 V C8 L) {6 n. E8 z
default:
5 p: U7 h& Q* s break;
9 h) m j/ F7 u) V; a }
A W/ C F/ X return 0;
' D6 k$ V; \) w! O$ I}) Q" k* P! K7 Y9 ?" H$ D
, k7 i( j' Q# p; L9 Q1 _' _8 Vint isOpr(char c)0 y, F/ j5 B# s0 e! q! H) y7 Q+ z, i
{2 B6 a: Q7 H' m3 W
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
# Z% X& Q$ H% a6 a' n return 0;
7 S+ r3 a4 h' x. M6 j! c8 j1 o$ ]2 V else
5 k) C) k C+ Z return 1;) q( e7 ?/ s/ T
}& ~; q1 d# B% K
w. }* y/ j z& J6 o
float operate(float x, char opr, float y)
% D7 L& E: W* B: }{
; `+ j, ^+ \+ c7 a8 k& k; f, z float result;
; I! y* Q9 H( Q- K. m switch (opr)
/ c/ ?# c# b4 k/ K1 \ {
, R6 o$ }, W5 c* ~& C# Q case '+':
9 C9 y) g# M5 T5 N3 V$ [; { result = x + y;
% F4 B# B, R% S break;
( V7 r5 j* _+ `8 F6 Y, I5 Z case '-': + A+ i8 j% N3 S: U* X
result = x - y;/ g/ e6 n* Q0 e6 M$ D; l$ V
break;6 K0 p2 d5 u4 _* l" c+ l
case '*': $ g+ O9 |# V2 T5 A3 L2 P
result = x * y;$ t4 o; J: f7 y* J$ M$ P
break;( O# z" u. @, ~+ m
case '/': - Q) F; G6 r/ ]8 o) o* Z/ l5 i( g
if (y == 0)1 p! @% p- F* |" ~, b0 y$ T9 J b
{$ ?; p" K9 _# o5 m/ O' t$ ]
printf("Divided by zero!\n");
0 T0 v3 I3 F2 u1 t" r return 0;# B p' S& [9 ~" a+ p
}
: N- l( z# V2 Y) x# C else. H1 J& {- m1 b3 a6 j5 A8 e$ s
{
& v' ?, \- c$ W- U& O! t result = x / y; M5 _- T5 K) c. e$ N2 K- I
break;
@- F7 k& g- O( X* ?5 [% Q }
1 O4 _9 Q/ o9 G' }$ f: m- U4 x default:
( b' [/ B# B( u; R1 ]3 M( i printf("Bad Input.\n"); " p( u5 f2 J& a- }
return 0;# o1 }' I. z7 q( P! D& Z; p
}
6 h" _( f, ^8 o0 d0 ]) j return result;
1 j3 r2 m% P8 }, i}
; n: [5 b, d: ~- }5 u
! A5 S8 s; I5 |' k3 J" x0 h, Bfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/3 y2 v: W3 B. i
{$ b1 f' z9 U4 j. F- a
Stack optr,opnd;
6 e: l" Z& E: x3 J4 e- G6 v4 T struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;2 j: X4 Q( j g0 W
char c;5 c* l+ f7 J& o& }
char buf[16];
* ~- Q1 m( ` E7 K7 J7 D/ K int i=0;! U/ n3 W6 x0 e$ r6 R, n, K0 N
- o/ \+ R+ }, h) x; V+ Z) Q InitStack(optr); /*用于寄存运算符*/ V) z6 n: l% F' K
InitStack(opnd); /*用于寄存操作数和计算结果*/
; C$ Z* K1 a5 x memset(buf,0,sizeof(buf));
: Y& a! z1 F* b* @, D' n; w
$ k& U0 Y" o- t6 A3 ` printf("Enter your expression:");. H" v- |( L0 ^ x$ D) {- d: _
% I( L- q9 z, S5 n ]3 m
opr_in.ch='#';- t( @) R4 {9 M8 _3 p
Push(optr,opr_in); /*'#'入栈*/
( [. E5 t v8 f GetTop(optr,opr_top);/ R1 j0 \" p+ v( N/ M5 g4 X
c=getchar();
0 w$ j) d& O- H+ c* y while(c!='='||opr_top.ch!='#')# }) \ Z/ h8 {" Q. Y( R
{3 ^3 j, m g* u. F2 j4 Y9 F
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
) C6 ^: E+ y! z {: F3 t# p8 Q2 ^* Y3 _: b8 P
buf=c;* b- L/ P# r" q }
i++;& O5 x6 l' N ^0 |( K2 m
c=getchar();0 y) \: M2 M1 S
}
' S1 O5 i' j k/ V else /*是运算符*/7 U# J" m& u$ q1 h* O8 W
{
2 n* d7 F: o0 I9 f t/ I( L, s buf='\0';3 Z- v5 V \) U$ B! a
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/4 d; x. e( ^9 d% h4 J3 A, O* O
{
5 K8 B$ ?+ U* B- C. x opn_in.data=(float)atof(buf);
5 W9 q. k$ M3 m# Q6 ^% B; w6 R! J Push(opnd,opn_in);
# Q9 R! k2 U$ p: X7 X/ T printf("opnd入栈:[%f]\n",opn_in.data);
/ j8 @- m9 t1 G4 r! [# s7 U i=0;/ }8 L5 E1 d6 C' \1 a3 D
memset(buf,0,sizeof(buf));
$ n6 J$ t8 U/ A4 C& M$ O }. [+ g* Z5 g' e2 J
opr_in.ch=c;1 y* e2 f- Y; z5 c8 {
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
& v F6 ]8 t5 a7 V M# c3 ], W {
% c( p! Z( S2 [7 ?# C4 U( e7 D; d& } case '<': /*优先级小于栈顶结点,则运算符入栈*/+ Y( A( q5 j- p& W: X$ T
Push(optr,opr_in);. U. a+ H! R8 t( C* Q$ y( W
printf("optr入栈:[%c]\n",opr_in.ch);
& |' P+ E- G! t7 B c=getchar();
" K c _; a- R- r+ s& D" N+ W, q% q break;
2 s( X$ w4 ^8 r- s1 d" a4 H# Y case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/' u* x$ M+ _$ q
Pop(optr,e);
& [3 r, i( P/ ~ printf("optr出栈:去掉括号\n");
& u- S& H. Z6 L' i. A8 W c=getchar();
, u3 t+ {0 Z0 M break;
" }% f" e' c. k( U case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
) h- A( L$ A' }$ M. r- q Pop(optr,opr_t);, R7 y+ t1 N$ f, {; {; r9 s( B
printf("optr出栈:[%c]\n",opr_t.ch);
6 b8 |! J3 z6 n2 z7 M3 b% y if(Pop(opnd,b)<0)
! |2 ~" N2 S! W1 B, n6 m {3 `) l: Y0 k: I1 | c# C
printf("Bad Input!\n");* I" ~5 w9 G) b& H
fflush(stdin);6 N# H$ Y& F, D6 F, y
return -1;: l" w+ r' H" H, ^7 R
}/ a" M8 a6 P* ~$ C w# h
printf("opnd出栈:[%f]\n",b.data);
! h( P+ [; W3 n# `8 L, ~4 w if(Pop(opnd,a)<0)3 A5 B6 `0 e% i& t0 v4 n6 Y
{6 a/ U1 o& n' k
printf("Bad Input!\n");
4 K H* f. Z; W/ t* Q3 S$ m7 L fflush(stdin);& q6 A! N. e% r- }$ T: f C; ^
return -1;) l G9 B7 I; q" i% R6 Y5 n: ]
}
0 P( ^; A8 s7 C% E- q printf("opnd出栈:[%f]\n",a.data);$ p2 @# N( N9 K
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
7 M) _$ @; b7 d Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/5 ]- A- M4 i+ x. z. G
printf("结果入栈:[%f]\n",opn_tmp.data);; k6 [+ v, o- v/ P" H" F
break;
( _# m$ H6 T) [8 r1 c }* ^; j7 x4 g5 H) F2 c
}
# y# e# |5 P$ ?; V( d- Y8 U. Z GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
% r0 V, f6 k2 P }
0 S5 ^. i7 X* _' R8 j% \7 E GetTop(opnd,opn_tmp);
3 E& g7 C5 Q- K* B* d+ U+ q DestroyStack(optr);
9 @# b/ a: x- v$ e3 l7 j0 J DestroyStack(opnd);
: ?+ n! |) H8 o& H! C; q" E return opn_tmp.data;
" f! U; w( M& _2 X* N}8 R/ R/ z `+ U" Q0 M+ ]
0 n# V: e# L9 T! e5 {char *killzero(char *res,float result)
9 z& C8 c4 i! e, u{: K3 k' b6 Q: E2 W9 M
int i;5 q e" x- a4 b/ O4 Y
" v; k3 |! | e3 W2 U sprintf(res,"%f",result);" x5 [9 @# ]4 y6 e% A* @% `$ d% L% K
i=(int)strlen(res)-1;
& k M: Y' D1 ]6 C' w/ ~4 M5 w& d while(i&&res=='0')
5 M) c8 `0 i& o$ a {# l3 U/ S: [: s {+ S6 {# ]
res='\0';
" O' k1 b4 p2 v/ F5 w1 N8 ^ i--;' d9 s$ Z% C- K& E+ F
}
+ g* O$ D8 ?) J" a5 W6 r if(res=='.')
) D8 k9 m4 O5 C; a: h8 { res='\0';' y. a- n/ W7 F8 L; n0 M
return res;# g) V/ n; \/ f
}$ x! ^" u, C/ _! m) Q" _
7 G1 T5 c+ z; w5 o
int main()
7 ~, ?% a* Q7 O' q# ]$ `2 y$ {! S) B{, i# a) X% L4 z7 ?
char ch;
7 q$ J: s s8 K. Q char res[64];
1 I* |& r* U" y! u9 \/ L* T, g7 j float result;, l1 g! p/ ]5 k% p
while(1)
7 H- `/ F; o- U {$ k" Z0 z- _/ B. F( ], i( [
result=compute();1 c3 ~/ ~+ Q9 A
printf("\nThe result is:%s\n",killzero(res,result));
! `: _2 A. ~ y3 T$ F- g printf("Do you want to continue(y/n)?:") ;; r# d0 Q$ w% B! u$ E4 S# e
ch=getch();
% B: F6 J. h0 T/ t putchar(ch);3 W* M+ d. c1 |9 C
if(ch=='n'||ch=='N')) E0 L+ g% p! S- h, ~
break;8 c5 S% g& E6 w. n- d+ E
else
% _7 |% [0 z! F) |/ H system("cls");) z9 z6 r' }/ J8 Q( O$ O
}
! I3 T. V8 p# Y8 \ return 0;
( H( X$ f. g* q# [: J% ]% U3 n}
: {! [9 i* g4 a. Y" z' q4 A" k0 W# o, d$ k/ n) P* f8 l% R
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|