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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.) x1 s" p* w) Q. ^/ n2 h
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
! I/ ?6 j. G& `/**************表达式计算器************/
F7 V& v# v- a# H/ q' S9 d$ d" i#include <stdio.h>
2 t2 g" E5 c' z! _6 T#include <stdlib.h>
' _: h8 C: c& l; G+ [: X! z#include <string.h>
2 j7 A3 h3 q+ b! i#include <conio.h>
7 C* T' y6 F* s9 [#include <malloc.h>
+ e! A3 Y7 f; w5 b7 g0 P2 w
/ f7 D+ e) E" X, J#define STACK_SIZE 100' \0 ^ S* v: R( k2 G
#define APPEND_SIZE 10
2 w( t1 o k9 ^* d6 [0 R
* E9 {+ }# W; x9 vstruct SNode{1 i1 i: f% j& I
float data; /*存放操作数或者计算结果*/
4 H+ j; a- b( Y char ch; /*存放运算符*/
4 U8 Y |9 b# }% ]};
, O2 x4 s0 c4 K( L
$ u0 V. w% T2 Nstruct Stack{
, u: O" H2 r0 R7 n, i* [ SNode *top;6 F! m0 h3 i+ z9 J. _
SNode *base;
( o5 b' w( ], F; L int size;
. U g: U; O5 R$ a};" p) b1 }6 { q
# n) n; c6 M/ \- U
/*栈操作函数*/+ F+ [& p2 g9 h: \" [% P( w
int InitStack(Stack &S); /*创建栈*/
; z# y5 l. y* I( Nint DestroyStack(Stack &S); /*销毁栈*/) @: Y5 x1 d" l* j
int ClearStack(Stack &S); /*清空栈*/8 z9 F/ X5 N! O" m- W9 n
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
( P$ F2 q) Q- ^/ W9 i7 Tint Push(Stack &S,SNode e); /*将结点e压入栈*/9 x L" @8 F# a0 z2 d* G; j7 ]- h. C/ @
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
& J- V E3 d' _, U9 Z# v- `0 {6 p! s6 H# [# ?- ^% ^& O1 P
/*表达式计算器相关函数*/
. i+ ?0 U3 S+ B5 |& D: O2 X2 K. a: }char get_precede(char s,char c); /*判断运算符s和c的优先级*/
) t( w7 _3 z0 P" }* B" g+ vint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/8 a; p0 |7 }( o% ^
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/1 G- z/ p, o5 f; f2 P7 j
float compute(); /*表达式结算器主函数*/
; y- u' Y: e5 \! [6 rchar *killzero(float result); /*去掉结果后面的0*/ 5 w% l+ M% a$ ?
$ k% h/ V7 N+ c' h9 D$ Z- ?9 T, v
int InitStack(Stack &S)
+ j8 K4 V/ o4 Y{
. U. [1 P9 _2 _2 ]% s- H4 r S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
$ s1 ]: ^9 i7 i( X: k if(S.base==NULL)7 m& l m; \. t6 T- s( V
{
- V3 R1 V1 x9 O0 |; c5 L printf("动态分配内存失败!");5 Q" J: a. O" o5 Q) n
return -1;/ s6 K& r- b8 ?2 j$ c/ H0 v5 k
}1 z+ ^7 ^, H, S, j4 R* Q
S.top=S.base;
5 g- T& y( g6 ?& v7 } S.size=STACK_SIZE;
& i* c5 v* b. M7 J1 S7 T! ` return 0;
; i1 ^, w f6 C5 w( ^, I. [6 p}2 t) a3 q, t# ? P" i
+ i. C) G2 o6 W' o) P+ L) aint DestroyStack(Stack &S)6 h0 T# \8 f Z! q0 L' i: i
{3 |2 J0 S. t- I# d) A: {
free(S.base);
9 T. b2 j1 x# [0 ]. u return 0; p% H; ]- w; ^7 f
}
, [9 W% f; \( T/ u8 G
6 k- m! x0 D# ]8 c5 b: u+ kint ClearStack(Stack &S)
7 N9 c2 z. ?) ^0 g5 H! ?: q. z/ U{
, u4 Y/ h1 Q. q/ L& s0 A0 D S.top=S.base;
: h3 A1 S* _6 u$ ?" C return 0;- `/ ^9 U: c7 _2 x/ i
}
A* _# R. z6 q% g
/ j Y- i$ G" v+ z! Y! Cint GetTop(Stack S,SNode &e)
$ A+ T7 Z3 N* E; J2 I- C/ F{
0 \5 M/ i/ u( J1 P if(S.top==S.base)
( v& f* S8 N1 x; B {% a: x# t7 q k* e& Y# M( K
printf("栈以为空!");
5 X, W" M: Z3 a8 e. ~ q! t$ O return -1;
% s; {+ p! U: S D8 s6 R }
2 T) o% K" E- m e=*(S.top-1);1 q0 r1 {) A5 H0 l
return 0;
" x( X8 e4 x7 {( I}" }& u F; _1 A) R& G, f1 c
g- H0 v2 U ^1 _+ O; o C0 u' m" Aint Push(Stack &S,SNode e)
9 o$ }; Q8 ~$ K* E{: q+ p5 p' A1 G* W* W& J
if(S.top-S.base>=S.size)( h! W! R7 Z9 p
{
. I. p2 `- r/ U3 q/ X6 y S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
; X. _( ~5 t5 b3 o; a5 p if(S.base==NULL)
' C" E1 q! G" |0 B- A5 W' ~2 E {
6 N. f( i- O# ~ printf("动态分配内存失败!");
1 g1 Y) o; b2 r- h& r return -1;
8 t3 {; v; W2 ~& m$ ]& o% B }5 G# f; g7 a0 R/ g Z8 Z3 \
S.top=S.base+S.size;
9 s* P4 a+ I6 E: m d4 u S.size+=APPEND_SIZE;( \$ t. v$ S5 m" u& B
}
9 l3 @# n6 U0 s2 M* W$ Y *S.top=e;
7 ^' F8 i$ Y4 a$ ?0 T& k S.top++;
, t2 g: o" c" u& f; Q0 L4 s& D return 0;
; q$ ^! O+ `0 h! r' M2 u% _' [% \}
% K9 D5 n7 `( P0 p( C6 W0 v6 d1 ?. h' V' U
# n& D; W* p* H) W$ b0 Kint Pop(Stack &S,SNode &e)
* v' R* w' x* h" U{
- b1 a, I: H9 A if(S.top==S.base)
( G8 U3 k6 z/ h1 Q9 V {- o2 V y+ m2 U$ G3 s3 t X1 l
printf("栈为空!");
. S B! T/ S+ D0 @9 E' K return -1;2 `. x6 j' T4 Z) p2 l
}5 j/ }/ T6 f& ]' A1 H+ ]6 A- T
e=*(S.top-1);, A: I3 d$ b* r. R/ l; `
S.top--;
; v# J3 C& { a' D return 0; l/ A) B0 j9 W
}
2 h3 v) _& R, b `0 G5 O" }
+ R+ x: b$ D* p0 kchar get_precede(char s,char c)3 l! l5 P- S6 w) g1 `# k
{9 o3 K$ r% w: o5 H3 e+ B5 l8 p) R
switch(s)% R7 B0 b; e& j" q
{( e1 v' d" o: ^5 x1 A% y. z2 m1 e
case '+': 2 o- d" I$ q' J2 P) E
case '-':6 ]9 b1 E0 f6 s# e* ]- r
if(c=='+'||c=='-')& L. E& b1 V8 r' Q8 C% N
return '>';3 s9 ]4 A3 \1 P, f4 q3 K3 K- n
else if(c=='*'||c=='/')
- x: r( U& h7 S2 B9 E9 W1 w return '<';
" p7 Y2 A3 u! Y W, o9 u else if(c=='(')$ M5 z7 ?6 q7 w* u7 k
return '<'; |: v( B9 P$ y; t) D4 F: `
else if(c==')')6 s4 [; o, A* w6 l# A2 k* p
return '>';9 k' I7 ~0 e/ D8 u
else # U- G2 v. C. R" ? |2 k* v
return '>';! |$ S2 \7 P; Z6 d1 n7 i1 ?
case '*':" k& v2 s& y* Y, [2 `: C
case '/':
$ j- |9 V( U: e; n5 q' {, v m6 V( M if(c=='+'||c=='-')
% g; {5 k+ U& a7 e. N' i0 r return '>';
; C3 c W) H" D4 [8 s else if(c=='*'||c=='/')
9 y: G; D: p9 A return '>';0 u9 t- m. K( b, p- O- P% z( p
else if(c=='(')
: z" ]' }8 W0 Q8 O$ \ v return '<';
* r. D6 N7 l5 v) r3 i else if(c==')'); I) o' j* @; `! ]
return '>';: n2 i9 j/ s/ P$ ]0 }) W: }- z
else
7 y6 X0 C# n$ ]; L9 ? return '>';
8 k$ a9 w9 Z D. V$ r( D: } case '(':
4 s9 K) i: X0 K) n$ \, Q5 | if(c=='+'||c=='-'): ~# x1 `' v7 k( l
return '<';4 U! }3 r3 W5 r0 O2 T4 E* _
else if(c=='*'||c=='/')
/ l2 W8 n, {3 R- n" N+ g return '<';
: n# |( E# I$ K( H# [ else if(c=='(')- i/ e+ Q# f: D6 s* B- s
return '<';0 e. g; U2 g, d( Z: P" L
else if(c==')')8 v, t3 K! v9 z+ [
return '=';9 c7 l2 i" e. y2 l/ z1 P
else
# t F& O2 _9 P; q) q# J+ u4 L return 'E';
+ p1 ?" X; m y5 @2 G: ?1 c case ')':
$ {+ {- O' @& X* E% G if(c=='+'||c=='-')
$ J# H9 d% ~5 L2 p return '>';
' g. k: g$ w9 `' r2 ^6 u else if(c=='*'||c=='/')# |3 r8 `7 d% w9 i7 i+ i- R- N5 k) @
return '>';! w+ a% n# j* P/ {& i$ _( v) H
else if(c=='(')
; H/ v" S' D( e return 'E';
" r- Q2 z' R" Y5 L) M) @2 W else if(c==')')
; G% n2 h& q) X/ ]3 v* h1 M! C return '>';9 x; R: [, Z0 V% q7 b
else& M7 {' f3 _& V j4 J0 g1 I
return '>';
/ R2 y, |: W5 i case '#':
( Y5 L9 T. a" W3 u- a if(c=='+'||c=='-')
. s4 W# C! i! u8 t return '<';3 F2 Q+ v8 A2 D0 b
else if(c=='*'||c=='/')0 p1 d' T! o, n
return '<';- k6 v$ r% L: r A: m4 Q1 q$ \
else if(c=='(')$ E2 f0 M. T) E- p
return '<';
+ [5 L$ L: E- b4 C4 f0 q! y, \( z else if(c==')')5 T) \- p6 i* S' x
return 'E';
) L: R4 I3 V. _1 y+ A9 H3 d else
3 c# Y2 U7 p( m7 q0 M: S( Y' r return '=';
4 t# D: I6 W7 j default:
. s" D5 y: K" s$ o break;
3 o( i( p+ ?7 t0 @ }3 [" [, b q g7 P4 N/ g; N& V
return 0;
) J" R5 ^+ H% T}
% }( _. y- d L' b6 I2 P! `- p; _8 {
# ]7 o5 n3 B' u( _) Z) X, dint isOpr(char c)
, J8 ~# w4 d) M5 M) \' f D' |{
* V0 X. w$ \9 [! Z if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
* f" z4 v5 m4 Z4 }% C/ x2 S return 0;
5 @( _$ o$ M7 d; | else
6 o* Q' Y) h: A% b' Q return 1;
) n3 i: f: e+ H9 ]& Q}
D4 s' I* } g/ N$ r+ b, I; |; O- O* I9 P) I
float operate(float x, char opr, float y)2 h& C3 H; W. ]7 a& u
{
, Q. U7 z: r# D1 y0 O1 I7 I float result;: k/ C' G9 @$ Q/ |/ t( _
switch (opr)- I2 c) T. s# p4 a5 r) g2 @- ?
{: ~1 J+ w2 ^! V6 A7 U
case '+':
: L4 j5 O7 Q" f9 Q, Y0 Z2 \ result = x + y;, g) [5 C0 p/ I- G
break;/ B) k7 W/ V) ?: G+ F0 z$ \# l& J
case '-':
& \; M& F4 c9 [- d result = x - y;
: ?6 t/ O1 v% }$ | break;) g/ p) y( ?* G1 e/ i
case '*':
; Z; |1 H: e; H; n9 Q result = x * y;1 n. @) H" X; ~$ e1 c
break;
$ O$ i) h$ e- W: n4 c9 f case '/': 9 c. {% [1 V3 b% l y
if (y == 0)
. ?6 ~0 v+ c# T" {4 Q$ ]0 t. A* B0 |/ L {
. ]( a9 A4 q, \7 P printf("Divided by zero!\n");
3 G* A5 |: \% \ return 0;
8 K; o( u/ Z+ W; A; s5 m; o }
" x' G* F X2 g. S else& O% O3 Q1 B* F/ ~- s- R
{
) |5 i( I) K. e result = x / y;9 G! E5 J$ H6 u9 p& @! S
break;
! V& w' P& g) m! S8 N, \ }2 D8 a- `& `: }$ F) @4 V
default:
8 E: U2 i, U: D! ^ printf("Bad Input.\n"); 8 c, u& C) }: J2 K
return 0;
% G) D/ C( ~# c$ F9 f1 a1 U5 E# A1 | }
1 I: z$ |0 ^8 V' j. Q+ N return result;% R/ m k1 j9 a
}
) J+ ^: Q9 J: k& D
; T1 N4 a! E7 w: H e! K9 e _float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/: R: Y) z1 B* x
{
) H0 E2 G) ?+ q/ A: E7 ^ Stack optr,opnd;
5 J0 E- e5 P& M! ^: [, Q' n8 a! c struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;8 l6 @. C2 d7 z2 o H
char c;
( N3 j# H5 \! j4 k" Q( Q char buf[16];
: E+ Y% Z* l9 j& B) B; r: {8 I( S int i=0;" A7 }! X2 b* q
$ e# }6 Y7 l% T8 I5 R0 ] InitStack(optr); /*用于寄存运算符*/
+ C# [- s% q _ k6 B; ]2 T InitStack(opnd); /*用于寄存操作数和计算结果*/3 s$ k, ]$ m( m4 z( X4 \6 F' Q0 V
memset(buf,0,sizeof(buf));: D: d4 W: \2 E' C/ X) k8 Y
$ s( a9 ]6 R. q( K$ P! I printf("Enter your expression:");% ^ b, h- {: w* F4 t
; D) H7 H* i8 p3 D+ R) ^
opr_in.ch='#';
5 N, W5 U) L2 b: D+ n$ p' p* A* n0 A+ h( `& Z Push(optr,opr_in); /*'#'入栈*/$ t s5 Y& L t9 O x9 B( k
GetTop(optr,opr_top);! Z! i3 e, p# o& J
c=getchar();2 n8 ?" Z+ b6 |/ b9 B2 D
while(c!='='||opr_top.ch!='#')3 q& E3 f9 P1 x
{
& S4 z' T# r' }& J0 z- s+ r if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
# U! G; }. _* W( A+ J* } {# k w1 o& P0 o3 s: [
buf=c;( F a% z2 |1 D) ?
i++;
% y- _+ V" v6 I c=getchar();
/ b3 L9 S1 U* C* l7 [ }5 s! ~, U! r; E$ J
else /*是运算符*/" I9 T/ ^5 X0 D. y
{
6 Q, i0 A7 t& N! G. P% v$ z' N buf='\0';9 ~ {2 |0 T$ y6 V4 q
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/; Q* x/ W- E. K
{
( D: i: h- P4 ^9 D5 p" m7 h opn_in.data=(float)atof(buf); w+ k( z* v& V) k* \! r
Push(opnd,opn_in);
, F/ w+ R7 Z- q; p9 z, n printf("opnd入栈:[%f]\n",opn_in.data);. W% W, O) T: E- Z9 P5 {6 k6 F
i=0;
: d( s# i1 X; N% ^. T memset(buf,0,sizeof(buf));6 y0 D+ r8 p' ^4 m
}
) x0 P+ f8 }" w( t opr_in.ch=c;: k7 U! j! p; y! c& @& e
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
1 W1 [9 E. P" o* h {
3 A7 k# R) K4 E$ N4 ]5 j# X# Z case '<': /*优先级小于栈顶结点,则运算符入栈*/
9 m: T* A8 k h3 U9 z Push(optr,opr_in);
7 O/ p. U) }) j' N* a8 A, r printf("optr入栈:[%c]\n",opr_in.ch);8 D- O' m/ s% b
c=getchar();
0 ]6 o+ b6 o; V# q1 [ u break;
. Z) E2 z% E5 w; P, ~ case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/# ^$ B4 t$ q# E' o. u
Pop(optr,e);/ ^, Y6 S# P: N1 @2 e8 F
printf("optr出栈:去掉括号\n");
+ {8 [- B _( B7 g! Z c=getchar();
' E# G. v8 G3 O* A5 L( c, _+ | break;
- e6 W T9 Q9 \9 f# S9 f) n case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/# j+ D( o: k% h" E# e
Pop(optr,opr_t);
) H O: B- S* D2 a7 j% F5 ? printf("optr出栈:[%c]\n",opr_t.ch); e6 a+ e* ? o3 F, N3 V
if(Pop(opnd,b)<0)
# [9 b/ t. S. l8 x% p {; C) c, r1 o3 {, |4 d Y
printf("Bad Input!\n");9 k O4 l6 Y- E( U
fflush(stdin);
6 V4 ]0 t% Q% d# l return -1;$ i: M. n0 D9 y) N
}
! [: y0 N: l) {4 @$ R printf("opnd出栈:[%f]\n",b.data);. G4 d; x" K3 g; L
if(Pop(opnd,a)<0)
L1 e/ ]7 |+ X$ t* H5 V {
. B9 X" `. `% K/ o& r7 F printf("Bad Input!\n");; d1 d2 c2 b) H6 R
fflush(stdin);
* G/ e! h$ U v, {3 D9 i return -1;
* Y/ V& `! c( k! Z }
# O# K" e" @. [" l6 D3 P printf("opnd出栈:[%f]\n",a.data);1 k; u' K- D W0 I0 j* d' S7 I
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/* B5 n9 G7 ` x- Q' T$ y
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/6 y, ~* _* p2 n: s( B$ w
printf("结果入栈:[%f]\n",opn_tmp.data);
' R1 B! I* t0 C, K f break;
9 B1 ?7 v( [+ t4 N/ J6 Q, i) o }$ H2 ~0 U# g+ B6 W
}
* s, h) F5 O' T( U6 M; ?+ N- g" @ GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ $ V9 z8 f) z& S5 ^+ z' F# F4 T
}
/ d) X# g1 l3 O C* } GetTop(opnd,opn_tmp);
7 }, }8 _' F. T- i5 t6 ~, d DestroyStack(optr);' M* E! v1 h9 R- D# W2 Q8 n4 k
DestroyStack(opnd);+ O5 n+ q# X' s$ D
return opn_tmp.data;1 { e* z8 T. a) V$ W! M: u
}; R$ B2 a( M H
" w- j0 @% ~0 Y8 x# v
char *killzero(char *res,float result)( Z8 I2 s: y" g4 p5 e
{
" s/ h- ]" _) C int i;
9 q" e8 M: u- M7 @7 X& {" K, ~- @9 ~: ~
3 v1 t; `) [2 \9 f' S! X" c3 n& L1 J5 ` sprintf(res,"%f",result);1 h! r+ K8 k* ~& B* g2 ]3 k6 A# T
i=(int)strlen(res)-1;! s! p# u/ @' p4 r. V- L6 ~$ T
while(i&&res=='0')
4 C/ a/ D+ z# Y {# h. v4 ]( ]3 D7 w( \( B! l$ `
res='\0';
' H8 D! ^ _$ J$ y. R1 U8 U$ H i--;0 N4 J- N- a7 f) t% b) Y" N F
}. A" S! W) J$ R }0 C
if(res=='.')
, }: @7 I5 c" h& a1 W r res='\0';" B4 L. g" f! y) k# d% s- C
return res;% o3 R2 c* D. m! t8 [. x4 |9 ?
}
( d5 i3 E" }3 J& I9 _& s& E' [1 f/ v' y% ?( [
int main()( _4 m, j2 G' ~6 g0 h( U
{8 e, R- O u; L+ l: c5 Q
char ch;% C9 J, X- N+ ?) }
char res[64];0 B) b' w' t4 Q6 ?
float result;
3 k# ~" b, ?. K while(1)
" f! g# h$ i( J" p {8 ?9 ^; v# L2 |! X& Z8 D9 M( v8 J
result=compute();& q9 v) ?4 I {$ `7 U; E
printf("\nThe result is:%s\n",killzero(res,result));% G3 R+ r% j1 {2 ~' C) V
printf("Do you want to continue(y/n)?:") ;
& F' J/ _8 D+ B/ P7 }6 R: t ch=getch();
! i, i6 H! `8 Z% i7 C putchar(ch);
% b8 P# C) h7 q2 d% ?4 m: S if(ch=='n'||ch=='N')2 V5 y- m/ z2 X8 K
break;- T0 Y1 w0 Z K7 d3 I
else
, G' ^0 C1 k/ Z0 G: X3 Y system("cls");
2 l% p* ]5 R% x) p }3 T% ~ Q! `, P2 Z1 [' c1 o$ c) o) G7 ~
return 0;
( g. t! c2 E! o0 R9 L0 {. e}' M8 q6 J: U% ~3 X) T
1 d7 O! E( g l. p8 Q% {$ \ F
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|