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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
+ j# M! w$ L3 p9 E7 P% A程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=9 ?' {3 z+ o) N
/**************表达式计算器************/
4 E0 z7 z" x A#include <stdio.h>
% }* r: k" \6 v$ L; G8 }6 M#include <stdlib.h>
( W" q y4 h. ?5 D#include <string.h>' }0 ^) z+ V% L, N* P
#include <conio.h>
& f% b! v6 \0 q! O8 B0 [. q#include <malloc.h>
6 r u7 u; [5 Y* a* g
8 A [- A3 m. u6 N/ b* `#define STACK_SIZE 100
9 t& h2 g/ q8 K0 @7 P#define APPEND_SIZE 10
0 y( x+ L# U1 Q# B5 N" H6 C* u' g5 m5 l9 c. E: F" z( P2 t
struct SNode{# r1 C/ p) y+ f4 n0 z
float data; /*存放操作数或者计算结果*/# R$ |" }$ l. E' ^3 j5 `, T
char ch; /*存放运算符*/7 B$ }$ j5 {: _* F* i1 l- G4 M
};1 O8 I( l5 h& a! U
8 _7 A3 q9 D3 z* Q: ~: U) @5 Sstruct Stack{3 e3 }. Y9 M# S4 W$ R F# m
SNode *top;' L1 j6 |7 z- v5 V7 y
SNode *base;0 x/ `" _" p( d
int size;
2 Z# {& V# S4 A# e};
, d" Q6 m1 |5 z
( r4 l, n% E; [( i/*栈操作函数*/9 Z5 p2 _( o. {
int InitStack(Stack &S); /*创建栈*/% V( F8 G" L* F/ _ @* B5 H' T/ `
int DestroyStack(Stack &S); /*销毁栈*/
" Q6 V# \2 @ ~8 e3 U7 w% k7 t, gint ClearStack(Stack &S); /*清空栈*/; h3 C d) F6 j& a, M
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/! w8 i% D& U5 {$ E& {/ B( v; a
int Push(Stack &S,SNode e); /*将结点e压入栈*/# C% ~" J+ ?; X5 k( H
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/- e8 q* \# a- _3 [, p
8 J7 z \ y) |& Q
/*表达式计算器相关函数*/
5 b {5 U+ q, Y- N3 G" uchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
" ^/ h+ p' @! g/ Cint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/+ X5 g& l0 _1 V6 F& H! B& k2 X
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*// ?5 I( i. Q5 h0 B- {$ X6 X# g
float compute(); /*表达式结算器主函数*/& i5 m* F: ^1 B5 p: {$ c- T
char *killzero(float result); /*去掉结果后面的0*/
2 R+ \! l4 i& i" D U3 s
- V( b% W% h/ u9 J Qint InitStack(Stack &S)
$ z! G9 x( B Z; Y8 ?{6 }' m( z/ ~3 ]) g! X+ M. `
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
/ ?: w7 @$ p3 @# Z$ ? if(S.base==NULL)
0 {5 l2 g$ B: V+ o- u {; `% ^( r& b* A$ p+ H' ^7 E- g0 a
printf("动态分配内存失败!");+ |6 [$ X* o+ R" Y8 g" j8 {
return -1;( L" N3 n! I( K. X/ e& \
}
* L: T) l& S- n2 U! A+ | S.top=S.base;8 m2 @& D. t+ {
S.size=STACK_SIZE;
2 z3 h. Z% c4 t; C& v return 0;' b' f3 D# x) W
}( {$ p' e7 R* t% X/ n% P
8 |2 g' g5 h e. e
int DestroyStack(Stack &S)
. B# R2 P. A0 k/ q+ i; Z$ p% o{
" v- n5 r+ x* i: w. Y free(S.base);0 b( X! z" x9 X- I r/ @
return 0;+ o4 W0 b, s: O8 T @. {
}
/ [' \' O* s- x/ {; |0 ~9 P- R0 y S0 M; W. t) G9 V
int ClearStack(Stack &S)
( `3 q b: u' g! h{! v! W- `/ [1 _# a* u
S.top=S.base;
9 a. b5 b8 Y* q$ m% @ Q- L: r, v, @ return 0;
$ z9 s+ m# ]. w}
! Z0 t& Q ^: t& J) v
& k1 a& d4 Y: @* J+ A1 m6 S1 m1 hint GetTop(Stack S,SNode &e)
" i _: |/ H0 O* h{. S: V) R9 Q' s4 l7 n, }
if(S.top==S.base)0 P9 ^3 j; G3 h* f6 Z, b
{) E$ _- Z3 K; \- c3 M( g/ B
printf("栈以为空!");
/ L4 g6 j4 P% k0 U return -1;
4 F4 e3 x O0 n) U6 t6 Q }9 g; p, O6 n/ W. V% c, P
e=*(S.top-1);
# p; U8 S: l3 I% Q( R return 0;0 n3 `7 c3 r' y8 G6 ^8 {2 @
}' p! b" A% i+ \2 v
/ V7 |/ P1 o; p2 L: wint Push(Stack &S,SNode e)
" Q' ^* E, I' u- Y& V{: i$ S2 o+ ]; i9 ?. G9 T6 g* ?4 x' K% F
if(S.top-S.base>=S.size); V! a) K0 o& @
{5 ]& V) L8 D* ^( @
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));8 M0 T+ K8 _& w& x
if(S.base==NULL)3 T1 m3 {3 p, o5 k
{. c7 }3 p5 E# n. \/ Y
printf("动态分配内存失败!");
: Y! J! ~) F6 ?" J s% { P$ e2 q return -1;+ L* G& Q' C& M. H8 t
}
6 b3 {5 B3 F2 b, A4 b) U S.top=S.base+S.size;
8 {( S9 s6 i# R9 B- P+ | S.size+=APPEND_SIZE;$ z! t* i; K/ h/ D( J
}
5 G1 b; a& G+ e0 P" E; D+ F& h *S.top=e;
$ Q- w, `2 a; k/ v# z S.top++;
( J6 ^3 g Y1 m/ C; s return 0;2 o; ^6 L* o$ b- c6 E) q
}
2 I% r6 M1 K% h) q: |8 Q n! ], U* w. l4 q
int Pop(Stack &S,SNode &e)" t( V8 T3 D: b) r% o. u
{
, b" z, o3 R* A) `0 e if(S.top==S.base)$ ~* J' a7 p7 x
{* v; ^, o) u! R
printf("栈为空!");
8 C* W9 Q( _: {& Z$ Z, T return -1;
P9 o; J, }8 S! T6 _# l0 ` }$ B& P7 t* M! T T) f D* J
e=*(S.top-1);# B5 T5 [9 i% w6 Y7 \% l
S.top--;
. R, `* ~5 j x" L c" ~- A return 0;4 [2 t6 G/ Z* l, |, g. N
}5 h, w# k, s. I1 f+ w
$ Y. L4 I, T: J( ]1 q6 h% Ychar get_precede(char s,char c)
& b1 I; R/ x0 r) n+ @{6 u9 J" j' f* B8 N1 Z
switch(s)
+ R6 D2 o1 B: w/ E/ v {
1 y5 N% n. F X! ~ case '+':
$ I5 e. j! D2 I& Q7 ~% e case '-':
* e# ]% {$ E( h O. F# J if(c=='+'||c=='-')
_- ?+ u5 e2 G* K2 ] return '>';
6 J" Y" ?2 T2 D U" r else if(c=='*'||c=='/')
5 n; d7 R, |( k' ?. w; T return '<';
( f" a9 r. f4 s* [( v else if(c=='(')" m/ C" S8 B/ s7 S4 O2 |2 ~/ ^0 s* {
return '<';
/ m9 r8 T G7 Q& H- [/ @3 g4 ] else if(c==')')
2 {% N; U6 I; _# I9 D3 |0 D return '>';
8 q/ y" L+ u9 d) N; [$ c else
6 y! H5 N! U$ E$ u4 Z return '>';2 Y7 Y4 g9 T, ?
case '*':
$ y: x x# I f% ^7 K( P+ B9 f3 p case '/':1 l' r4 ^* d/ P+ @" V0 e
if(c=='+'||c=='-')/ {- [4 v2 U& A& _* [4 \
return '>';
/ W0 y/ @$ {! a3 R' c0 H6 @ else if(c=='*'||c=='/')
) p7 I- s1 \: _9 C3 V return '>';8 m3 B4 \0 u. `& `& v: ?
else if(c=='(')
5 C* h/ t/ @$ F$ v return '<';
) r; l" o0 x& `$ F6 i4 q g else if(c==')')2 L9 Z s& R, C
return '>';
. E' U4 n1 M& h1 ]3 ?* l R& m else
# O% o* K9 O! t1 P" W return '>';
* v" e& y) J$ s q) G- m case '(':& l' _. F# \" Y% m1 \- z
if(c=='+'||c=='-')& ^9 Y2 A1 w+ R
return '<';4 V5 T" T6 h4 d# N. l* A
else if(c=='*'||c=='/')
2 F7 Y. _5 ]) J1 d# l: S, r return '<';
; V) A$ I- s3 Z) j: Y else if(c=='(')
) B3 l0 J: M7 `6 G( e return '<';
% ~. o/ R7 l' H0 P: j/ | x else if(c==')')( T; ]7 R$ {! |8 t# n
return '=';! C0 f/ ~: P$ V" Q0 L
else8 N3 N7 s& p+ v* d
return 'E';
5 k% s# a( N7 _: c" j( p2 d1 u g case ')':
, O& p& G9 u; u# @( e7 M if(c=='+'||c=='-')2 w, [2 H z: _* h9 d3 S6 b* Y
return '>';
. f( |$ {0 |' r( Q+ F1 e% }: R else if(c=='*'||c=='/')
' W$ Y, v: I: {5 M return '>';, ?* w5 i) r; o: M1 x) t, V m7 B
else if(c=='(')8 o8 X8 [( a, e; h% _7 T
return 'E';- i% R& }" m3 t N
else if(c==')')
! `) v* s' y0 ] return '>';
% R; B& Z+ x6 `$ r2 C else
+ _+ T- @) {: w( r) V return '>';
* J( ?. l9 S. K: t case '#':+ S5 P! \6 g6 g3 t' o
if(c=='+'||c=='-')
/ o( ~: [- M! H+ y# u' }7 \1 ^+ v return '<';
6 K4 h5 t" L, b% r else if(c=='*'||c=='/')
* ~* o6 s N* N! m6 e( e3 D: Y return '<';
/ K9 a8 a" ~5 u else if(c=='(')( B' @5 u' Y! F1 O6 ]. z) {
return '<';3 @$ H+ a+ J' s2 V( g; }
else if(c==')')
B, d0 V& E4 f1 l. S return 'E';
9 X/ ~4 F8 ~: r M else: P* b; k3 _9 |/ w1 [
return '=';/ h: ^; d9 n" z
default:+ n% L6 b, _+ a$ t8 |
break;
0 I+ l+ Q( o6 J, P1 R8 N }' C# s0 }6 n' R Z6 g- {
return 0; & Y) X9 z* w# h9 v3 D# E* S7 z
}
9 ~1 u/ `- k/ a" {3 N8 ]3 |4 L& d$ O6 [' G( a5 X
int isOpr(char c)1 L! s: I9 ]$ Y+ Q' j
{
9 Q1 z0 l5 Z$ o) Z, Q7 f if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='): D. W# u) o m! s! q0 r: U6 O1 S9 u
return 0;
+ ~) _7 J: s, W$ k2 J else 5 J0 \7 J+ o* q) S
return 1;
B, I' D& P) D+ F' v3 Q9 U}( F0 n6 n/ _. Y# B. G
3 W6 Y% c; Y+ z1 c: ~8 k3 Ofloat operate(float x, char opr, float y)/ Y1 I1 n l4 ]4 `
{( r# b/ a+ P( v9 Q) [$ X6 t, Q
float result;: q( M& u0 G9 ~4 B! A
switch (opr)5 j8 L* Y- F4 K' [; d$ h
{
8 z4 ^2 m/ g/ H! Y; d case '+':
3 C% X1 q. S6 s* {; _2 t, ^0 F# k result = x + y;
; |) |; H' \ E break;6 u9 x2 o8 i# V9 x# c, ^
case '-':
7 J# J! \& e# {! i, X ~& y result = x - y;: \+ x0 D! x5 w* z8 Y# D& B
break;: ^+ K" u! e! ]' I: e% l4 v* X
case '*':
: W9 u2 U$ K* M) H result = x * y;$ h1 f- i& ^2 M% L
break;
- d" |" v) g; e2 O9 h# J) P4 e case '/':
+ G3 \0 m# b5 M if (y == 0)
$ U) Z! V- i( [: J$ m0 k {
# O6 r% C7 p; \3 T N0 B printf("Divided by zero!\n");* z+ }! n a' F k; C' S' q
return 0;9 }9 v6 I7 _* \' v9 A
}: d. M& v% N: N% c4 V3 W: ^
else! F! C0 u1 x6 ]& X! _: X
{' f; c! x) z+ d
result = x / y;
; Z K; v; e7 D+ l, k& g break;
4 `2 G3 D( z) c }
3 }( H3 o/ w9 L default:
! j6 Y$ d$ F5 n9 U1 M X printf("Bad Input.\n"); - |* Z" A; Q# W9 {; s
return 0;
5 y$ v) \$ G& c }3 w0 h- c/ U: E! u$ T4 T0 K
return result;
3 ^+ O/ N, ]& r} 9 M/ f' N7 j5 k7 p
* e* o+ s3 L1 u8 ifloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
7 P$ _9 @) E' @3 ~" b{
& a3 w9 m4 I7 L# X Stack optr,opnd;
6 ^0 k; k; b" |9 d. W* | struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;/ L5 U& h9 k x+ E' t
char c;$ b: d) [, z6 a7 q
char buf[16];8 t6 u) X# q4 n9 ~2 V
int i=0;; ^- E! q( z( v$ O, P* I5 g6 ~
- t. t' z+ v0 P InitStack(optr); /*用于寄存运算符*/( ?8 s5 W* k+ |1 X; d% N4 C, m' E
InitStack(opnd); /*用于寄存操作数和计算结果*/
9 D1 x$ M. S5 j& @ memset(buf,0,sizeof(buf));- q. C' t) g: r
. J' _* w O/ D( K( | P5 p9 z
printf("Enter your expression:");
. y5 I% U" n+ P& Y* I+ i: } , B5 @ J& e8 ^* X& `" W* h+ }
opr_in.ch='#';
0 f8 N& T1 t& |6 L Push(optr,opr_in); /*'#'入栈*/( O8 h( E7 Q, h+ K) ]+ H" ~, J
GetTop(optr,opr_top);3 \& D6 B* C3 J
c=getchar();9 R6 l$ F6 d: u4 B& N) ]6 a
while(c!='='||opr_top.ch!='#')
6 d1 A! R! ~' }# t' I {
1 y! _8 Y" {2 L if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/! o4 L$ O/ [& e3 T
{
* Z+ _6 z) M: U4 L buf=c;
( Q+ Q* F/ k: x& G2 _+ c i++;
$ S5 y! b/ y- v c=getchar();
& x: K. d1 ]: z/ s4 Y) S }" _9 p% ~% R! k% @( @% l9 [8 h
else /*是运算符*/
/ }) Y4 v+ P' y# u2 \$ ^2 E {
/ p4 ]2 X- E/ z buf='\0';
9 Q+ @! w& g3 j. y0 U# G2 w' d if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
* N- z$ B, ?0 p. U. v* i {) [/ e0 D5 C9 }% q1 n* c
opn_in.data=(float)atof(buf);
4 A. {* z/ P: N" ` Push(opnd,opn_in);5 W# i; J- f6 ] r9 m; T
printf("opnd入栈:[%f]\n",opn_in.data);
" D |0 ?: c" V$ V% i, y( G i=0;
2 p5 w0 C5 v- e3 v9 J memset(buf,0,sizeof(buf));3 Q! j3 q/ t: }7 Y
}
0 P9 H2 a4 ` s5 w opr_in.ch=c;
2 h8 l6 b1 w) U. Y* q5 D8 d switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/! b7 h* @# ~+ b- e7 ]9 W% M: j
{
, {7 a' C, E9 k* ?% P case '<': /*优先级小于栈顶结点,则运算符入栈*/7 m% p) @, J" I# i4 `$ S
Push(optr,opr_in);- s8 k/ H. h N' V8 O+ m/ r" H
printf("optr入栈:[%c]\n",opr_in.ch);
6 m3 N8 S+ k; |$ W c=getchar();
4 T* E% G3 W: Q `3 _ break;4 e. n: f$ q5 N3 [! b. m( }! p
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/# K' Q; P5 O- y4 @( U: U
Pop(optr,e);
( ?6 |# c# K5 A- [$ R5 y printf("optr出栈:去掉括号\n");% d$ l. x4 j9 `# O, \8 L
c=getchar();1 K0 M/ b q4 G5 H
break;
p4 b7 {# ~% F* ^+ ^ case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/5 `& I- E" b2 p: n/ ]
Pop(optr,opr_t);$ M* _% n' y6 U! x; \# Z7 P
printf("optr出栈:[%c]\n",opr_t.ch);
' B1 p3 R4 m$ M' f if(Pop(opnd,b)<0)
5 a( ]/ U7 M/ l8 y7 r: z0 \ {& `& o2 ] J4 I% V/ G8 G
printf("Bad Input!\n");
0 s. n; c9 E) A) T% `, a8 q fflush(stdin);; ]- d, q% `) R3 e: [
return -1;
0 E! i3 B: A1 H' \! n0 }- x. v }
8 `$ q- i% E7 ^- ]! r+ ^6 q printf("opnd出栈:[%f]\n",b.data);
# Q# a5 X6 M9 A4 D/ L: k if(Pop(opnd,a)<0)+ Q! v" [& v0 s/ J& O
{
! x; E3 E: }4 V' v* q printf("Bad Input!\n");5 l, W+ d' I, e+ ^4 j N; V
fflush(stdin);( b5 `( U; k' y: y1 k
return -1;
1 s7 \7 `6 ]5 Z* e6 r2 u }
d; m1 ~2 O# s3 y) ] printf("opnd出栈:[%f]\n",a.data);
7 ^; f( u: B7 X" S9 z( | opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
# F4 f# N4 M4 M, I Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/, j) h9 R% o: ?7 T
printf("结果入栈:[%f]\n",opn_tmp.data);
; @1 @: U. X' B& A( }& b/ f8 B break;
( N7 e7 _, L' |% |+ K: X, A3 a/ Z }' l4 k- R3 U8 S+ A4 f2 D0 M6 q- b
}" j! b: B1 ~$ l5 [- a( i8 A
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
, C. J' o8 ]9 y8 \( R4 ?" G }
; j8 K- a8 p1 r6 C/ _( d" `$ l' }0 { GetTop(opnd,opn_tmp);
/ G: e% y6 I5 E4 Y% x. m DestroyStack(optr);
9 P8 A, n9 F$ T# U DestroyStack(opnd);
( J, b+ _) D' ]( y6 ~ return opn_tmp.data;( |6 Y, I, m$ ?4 v
}. l3 c- X9 @- R
/ s4 Z1 h; x7 R! @
char *killzero(char *res,float result)
9 p: c/ F% O9 m3 F) `{- _8 P0 X; b; L/ w
int i;
. R; E* R) J' d3 K4 I. N: {2 a$ j: a I4 h; l
sprintf(res,"%f",result);
, ]; R9 B8 {. q' r i=(int)strlen(res)-1;
9 x: M1 C: p( ]) L" u9 V9 M* b* `5 s while(i&&res=='0')
8 e$ {: N3 W" H, ]8 K9 D! @ {7 |6 y1 M1 Q: k2 L9 {' S
res='\0';+ V. f% G. C k3 z$ c- [4 f; G% k
i--;
1 Y: j3 @( G6 `5 M }& g/ m- o$ k! Y" ~
if(res=='.')
8 |( N) ~) f8 E J: d" O: \ res='\0';
5 N. ^" C& j; ] return res;
- t" K- v2 o9 u9 C6 u" x Q' B}3 B `6 S# J2 }6 y4 M5 n: I; M
! E3 N! m4 A9 F" U7 `int main()
: F8 i$ V7 l" h: t, z{
/ \( O+ i3 Q( ?! U5 v0 L0 n' k char ch;! \0 Y, [! Y/ M: l
char res[64];
8 O6 k; F; L1 |+ J( S float result;
( e& a% Z7 ~9 [. O9 _5 F4 v while(1)
; F* M4 m, I F2 l- P {" D% @- A) ^! j
result=compute();
! A: B3 V- O- L r7 _7 f. G printf("\nThe result is:%s\n",killzero(res,result));' Q% ` @% G O7 Y
printf("Do you want to continue(y/n)?:") ;
" }; \, `% z; p$ h" `% x: A, @ ch=getch();
+ D% w7 w* Q3 G; H putchar(ch);
' l4 p" s- C, G2 Q4 f% c# Q6 Z if(ch=='n'||ch=='N')/ a, V: F6 o4 X3 L
break;
( H- N: k0 o/ q2 t5 p: ]9 \ else
5 T( V: z1 Z. m; R0 j: H( }% h5 G$ V% m system("cls");/ f: T* E% u }7 u* F& d% a
}
9 H5 b) m9 m$ p; Y1 O7 E, e return 0;. ^! h' n% n( |: K
}7 e$ M0 k" Z: b* B; P
M. b8 O) s! p1 ^$ j' w[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|