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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
- N4 y6 ^ ]+ b5 u程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=. G. \0 h, j7 @2 A3 P7 c
/**************表达式计算器************/
2 ~8 Y+ L2 A! _#include <stdio.h>
% }# A! k( F" S# J2 f8 ~#include <stdlib.h>
' i2 X* ]4 o e0 O4 _8 e+ Q- \#include <string.h>
$ n7 V" Z/ o( ?4 c, j! `3 R1 N#include <conio.h>" P5 ^: m; i& q8 x8 f# J
#include <malloc.h>: |' ?( g- \9 ]- X. `9 H
3 H' c" |' P- `& ]7 _* m; a
#define STACK_SIZE 100
?; W# _' ^7 E#define APPEND_SIZE 106 z! ^- m- e' [( w9 d
" P3 f, R9 b7 gstruct SNode{# m# S# [2 h4 O' \5 Z) e1 a0 P
float data; /*存放操作数或者计算结果*/
) H2 ~9 v; `- G$ \9 S) R* L char ch; /*存放运算符*/
9 W0 G3 f* y1 v};' ?- G& j6 e" A
/ W, Z% r3 m* {8 ]struct Stack{; Z! `0 j& D* E/ o V
SNode *top;4 I+ m9 ?# q. y
SNode *base;
+ M) y* w, n2 T- ]2 V. M* y int size;
8 i; N I7 @& O$ P/ P: F/ t6 z: K};2 K$ M9 M4 G4 F3 x% |( W
' t6 @3 s8 E9 T$ D2 J/*栈操作函数*/5 }+ R0 L+ A; l( m4 {: t
int InitStack(Stack &S); /*创建栈*/: W5 I) W/ Q0 v2 C* N, l' {- z% a
int DestroyStack(Stack &S); /*销毁栈*/! f2 h- R+ c7 P, h, V$ I! h
int ClearStack(Stack &S); /*清空栈*/% v2 l. a6 b* u# G' l5 r
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
8 D( `. ~ B4 O8 Y4 |- i* R/ \int Push(Stack &S,SNode e); /*将结点e压入栈*/0 ? n9 ~5 H) y4 c) d
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/2 s) ?7 N% d2 B: M/ T7 i/ j z
% q$ v! R" r6 z+ [5 `1 l
/*表达式计算器相关函数*/3 E, \- Z' g; R" ]
char get_precede(char s,char c); /*判断运算符s和c的优先级*/. K7 i+ I3 L0 D- `
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
( u' W; z: S9 ^( e0 ]: ]' J$ {float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/( q$ g& q4 a7 |# t4 L: L+ I
float compute(); /*表达式结算器主函数*/! `9 `# l' ^4 ?8 f" Q
char *killzero(float result); /*去掉结果后面的0*/ 9 J1 W6 P" w7 o; V& ]
7 O% N3 s' S- ^& g/ Jint InitStack(Stack &S)
0 _" ?+ M$ e' M0 e% @9 P( a{5 }" c5 Q% | t" `
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));( K! ? M2 P$ M; \2 n
if(S.base==NULL)
w* m, E4 B2 ^, l0 U* E {
0 K5 R2 F1 ` @, D printf("动态分配内存失败!");
+ N. E" o9 `. M' [! m$ M return -1;; I& W) G, I1 j t
}
5 \7 W: U- H& E$ s0 q8 C S.top=S.base;6 U* t5 |; Y& M2 N* _
S.size=STACK_SIZE;
3 ^2 X( m. ?& L E return 0;
) D" ?1 e$ t A d8 n4 m}; ~7 L0 Y' z$ w8 W* t1 L9 k& C
. y. O4 f1 J# z5 mint DestroyStack(Stack &S), r7 C. o) P: z/ Y0 p: Y
{
9 F2 }9 v% _6 m6 N free(S.base);! T/ J* I ^- U" S+ Q; |# O
return 0;
" J8 Z* v. m8 { G5 q i" {( C4 l}6 y: f3 W. m4 k% }+ j
8 S) F) `5 M8 [
int ClearStack(Stack &S)) ]% s/ B% x/ f% G
{
6 Z7 H9 r- X% K' A/ E; n( Z S.top=S.base;9 ^& g8 B1 c+ O, G
return 0;
6 }# V4 l: V" p# g4 V0 J}
$ P* @+ \% j3 E) v1 ?/ n3 a' s* ?5 S+ i0 B8 D2 A
int GetTop(Stack S,SNode &e)
" O! S( E9 _* Y{& p" j% C6 v4 \+ n+ W
if(S.top==S.base)( @" b! K5 F' U* b, i: |
{6 S4 x j1 N# s' T" v
printf("栈以为空!");8 M/ \1 k8 W; g# R6 M6 e6 V" I
return -1;: t2 h M* m3 D; i* N
}' A/ P) |2 o8 c
e=*(S.top-1);
. N9 G+ {0 V! q8 ] return 0;
x+ v" N5 v1 _3 U" A}, f4 w% Z" l& [. h& Y0 c" p! x# C/ Z
: S1 z! L! u/ }/ i! o& o* K* _5 p1 s% n( n, W
int Push(Stack &S,SNode e), f0 C) n9 e" E, ~4 V3 [
{7 O6 M$ d( S# K6 j
if(S.top-S.base>=S.size) j2 K2 k M( Y8 @. C/ P" z( J1 h
{
4 B+ s3 g3 G& M- ?9 k/ }: P0 e S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); o8 M" M% {5 n. v. |( s
if(S.base==NULL)# w0 l4 _% [' k7 j: c$ k* o
{, E4 p. ^4 P2 ?/ x
printf("动态分配内存失败!");/ \3 [+ ^" V( s" q- B
return -1;
8 V/ Y4 P7 M2 p E0 T/ w; z }3 v D$ ~, T6 k7 V
S.top=S.base+S.size;5 {7 D' E) H, a
S.size+=APPEND_SIZE;7 b$ I- O. t2 s$ @% m2 {
}
9 G7 z: v8 Q u/ J *S.top=e;
. _0 e2 a$ {# X9 ~6 W9 V4 x5 i n G S.top++;- C0 C( H; P( L) Z
return 0;
, F# P$ I( H- Z( S4 B}
+ u8 C( A8 d3 I, E. Z+ ^7 T$ t! j8 L5 x& f- C# G8 q
int Pop(Stack &S,SNode &e)
$ T' Z* T; }7 ~( Z{; u# }3 I+ x# R1 ]
if(S.top==S.base)! t$ C* j4 @; v6 f+ K# n% X
{
$ T0 O+ P& y9 P/ V printf("栈为空!");
: w2 Y: K( S7 s% `9 M. e return -1;
# X' M8 ? @. a: g" q }6 `0 T6 J8 b% Q# ]( z
e=*(S.top-1);- r8 F0 e# a5 N) Y5 z& T# p
S.top--;
) _+ g2 w3 ~% p. {7 |2 P* i* y return 0;
- \: l* {1 |; z/ h0 I6 N}/ A3 g: ^8 b( N8 L; X
* A! H& `# p* Jchar get_precede(char s,char c)" W* f. p6 v. g% ?, Q
{: ~! \: P- I) F5 C. ?
switch(s)
7 [& S; f! n9 ^' l; z {, G4 T/ d3 s9 p2 n
case '+':
* _1 l4 [( u9 c' f" y) N* O0 Q case '-':
' E. @7 R' N$ o/ S& G+ E6 J if(c=='+'||c=='-')
) T- c/ r& ~3 A/ ^% [8 h# E: w return '>';, e0 c: |1 r' O- F% g7 b
else if(c=='*'||c=='/')- u$ i/ R, C; Q+ ]) p
return '<';& L4 `4 ?9 P' p
else if(c=='('), J; U$ ?+ M1 d9 F( F
return '<';" n! o# l+ c- s( N( q
else if(c==')')
* M) P1 e. u6 n) S# | return '>';1 s+ X6 v# ~& p$ z' ^
else 0 G9 o1 q; w0 R+ e3 |( M
return '>';& ^+ B3 o$ G- K8 N& c1 j
case '*':
/ x$ v2 p9 F/ f1 p, t6 P case '/':& u" Q2 N+ a3 m. y% I& Z
if(c=='+'||c=='-')+ {) G( E' F' `, I# I! x4 U3 i
return '>';
4 W F) f! t1 ^/ Q else if(c=='*'||c=='/')
+ [# O% t" N- Y! F( T0 l6 C4 A return '>';' P5 u) c6 Z: t
else if(c=='(')
2 |5 s- g: d1 @) _' N8 C return '<';7 s6 I8 z- Y) O9 ?0 ^4 M; T% a
else if(c==')'), ?/ @: f5 H: `, k8 Q4 ~
return '>';( g' |+ K1 C; x4 ]1 {/ x# z I
else
. D( M9 e8 c& s' a return '>';9 W, i- R2 }! s$ g3 B
case '(':. \3 ?2 q5 R( }1 q
if(c=='+'||c=='-') }2 T- u$ Z0 A# Y
return '<';
; @7 k) W8 a1 A4 T0 y$ B else if(c=='*'||c=='/')+ ~7 R& I! T" h4 j( F- H
return '<';
: U" [; d C3 k, f$ h1 z( } s else if(c=='(')5 Q7 B0 g. N, ^8 Q
return '<';
' R3 ?& b. t! P1 w1 t+ p n0 |5 k else if(c==')')! G5 k; A! `6 H$ i" P2 V( t5 R4 r
return '=';
& W+ j. n; C( I! {" G8 c+ g else
; J9 v) y5 K; u' V% Z) n: m7 X" o- X: \ return 'E';
! c% }6 D. u: Z5 h* J6 f1 V- |3 y5 r case ')':! ?+ a ?& v% k
if(c=='+'||c=='-')/ P8 s* d3 a+ g# x: p+ g0 l* D
return '>';
8 ]; L. j% `$ m else if(c=='*'||c=='/')! C, I+ k# ^8 k9 Z$ t+ F
return '>';
D/ v! z/ K( f- s/ m else if(c=='(')" O2 i F# H3 }' Y
return 'E';$ W- z3 Q! c9 c! w
else if(c==')')& m1 ^" x8 O. u9 X2 V- _7 S* x- n0 G0 _
return '>';
& T8 |: _$ o# F% R0 s else
9 q' J( g/ \" W0 t' ~4 b9 ~6 E6 Y return '>';
) D2 R- m6 ~( D3 y0 W! p4 C case '#':' Z- j( [, q y& ?: N/ s: E1 C
if(c=='+'||c=='-')) {" {3 Y9 O: W6 V) j
return '<';
& z6 d; E6 v! U( S else if(c=='*'||c=='/')7 B/ d; C9 E' j& ~) d2 _
return '<';$ C* x( M) @0 }5 A2 X+ y
else if(c=='(')1 _' v; T# q4 c, e1 C: C( e/ B
return '<';
4 x& X4 I. K: N3 d& g else if(c==')')
4 |& m* ?- r% [ return 'E';
2 y5 q6 y" ~ Y* z9 Z else# m9 w3 X1 s% @0 K' d P
return '=';( R# j3 B" r6 s! g. ~
default:
* j6 c7 `1 t! w% | p9 @5 y2 O# n break;
9 k2 O% R/ j4 a }* D$ W+ `: P* k, b; E4 y8 u
return 0;
7 E! y) l0 |6 p4 C- P; c; v- e}
; P* _+ I) ?$ @1 a
# {9 Y$ T3 J4 G# Zint isOpr(char c)
3 W0 x$ h, G$ d! T4 ~# J{7 ?- v" Y% j$ q4 f# z4 i J
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')& M# j4 t: K" l) i4 r4 Y
return 0;
7 W) h+ B# W5 I6 m else D2 {6 l5 e/ k) c# U% C. s
return 1;
& n* i. Q/ y" N! E! u} @( h$ Z) D* j6 H: r+ K. F
; g( i: V7 _' E5 H. d3 E6 Yfloat operate(float x, char opr, float y)
) ~8 `" L9 T& b; U% O; D. N5 s F{" Y* o b( v- i% U5 C
float result;
; r- f8 ^6 f1 G6 X5 F7 E) { switch (opr)
. g2 s8 u6 ^ ~' v {+ ~" \6 z6 D9 D" C; l
case '+':
# ]# U |; m' Z result = x + y;5 Y6 Y& M+ m4 Z( h* F
break;- M* q, X+ q. [/ h& e1 ]
case '-':
: I6 j; {% y- } result = x - y;8 l) e* W0 L7 Q" { g- ]
break;- Q) Q% s' Z1 B' q: P( Z3 E
case '*':
- E7 \' R$ Q9 E+ n result = x * y;
9 x8 @2 i3 [3 g- t( x break;* `0 j% u3 `; s$ L, R' g$ [
case '/': & d0 X9 }2 N9 _
if (y == 0)
4 p. K7 G. O4 k4 n {
# X$ p* }5 r: p& o+ p. g4 [ C printf("Divided by zero!\n");
1 y" S) U, T$ l! ?/ v1 I return 0;
: \. C7 J* `+ w- P- F$ i }* z R! W' U; e1 Z
else7 w0 R* L {, I/ ?
{) c* W: x0 A, P" \, |
result = x / y;
4 h" c7 R4 |$ d6 }$ I; E8 a1 d break;! h: Y! l' f, e O
}
- \( W4 M0 a4 B0 y M4 _$ m default: ! Z4 g; P. |. q; N8 W
printf("Bad Input.\n");
( ~& D, h& A2 K; N0 P' N7 N return 0;
, G* o& k( b5 ?2 L }+ p6 ~- a, D3 A1 Q
return result;% D/ q2 X6 {0 Q+ Q; Q: i
} ; u9 w6 w/ Q7 |( M6 K& q
$ \* j* H- w; Q! V1 l3 E
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
3 O' p3 B# z/ G' M( f{
/ p1 o9 ^' h, u+ e. `% ^ Stack optr,opnd;5 h2 r A. I7 B( Y, R
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;. R W% K3 ~' S! e, F) F, s5 F
char c;8 p% X" D) f# I+ h2 ~
char buf[16];; U+ V) q0 X" J, M1 \9 t
int i=0;6 a4 l4 {! P+ P* B# ~
: Q. G/ h( L: i) T! g# M
InitStack(optr); /*用于寄存运算符*/
+ u4 L: c; F: A# F+ w' ?. s InitStack(opnd); /*用于寄存操作数和计算结果*/
2 A) f5 A4 V) V) R9 i memset(buf,0,sizeof(buf));) j( D6 L! T3 \0 E* c5 y
# g# i2 o: ^( p; C2 K printf("Enter your expression:"); r' C% L9 q) [* ^7 \: C8 k
$ I* W6 c& u; h4 E5 Q2 A. a/ J: g
opr_in.ch='#';
" @9 F* j% F/ G/ n( w1 v, F2 h3 o Push(optr,opr_in); /*'#'入栈*/
$ M$ C) n9 Q0 t- x GetTop(optr,opr_top);
% R( o* {( ^/ Y& \# l' v& Z3 n D. K c=getchar();4 [; T4 l' m. e! v I* L
while(c!='='||opr_top.ch!='#')
; k) J0 [% e3 @0 {4 c9 D {
9 K, [* {4 H B if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/* U. k/ y U2 ~8 e* m
{
E: L+ T/ v# I6 K$ _ buf=c;
0 A2 Q+ U2 Z' I7 f& r- B i++;2 B+ j* _# g% J/ a, C9 m$ R
c=getchar();! `- f) T) w) r, H/ ^9 m6 q% I
}
$ m$ S# m! Y9 X( ], d else /*是运算符*/
0 D# ~/ B: p! `- N {( ^3 N$ h/ w7 }/ o4 x
buf='\0';+ n* R. a' t" a- k9 Q8 q* l
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/7 j$ j( ^; k8 Q) ~
{
6 b+ w9 ^' p1 d2 o, o0 B opn_in.data=(float)atof(buf);
! I2 A+ c6 S1 Z4 c" ]" ^5 x& z Push(opnd,opn_in);/ g2 [. Z6 q& `5 f& L
printf("opnd入栈:[%f]\n",opn_in.data);1 i1 ~; g6 j, [ I+ R" P
i=0;4 `, \* {3 n+ U, F
memset(buf,0,sizeof(buf));& G4 p8 ]1 a2 c
}! k, ~$ C/ t* |& H( u3 H$ \8 F
opr_in.ch=c;* c8 F+ e4 ^2 m* B* r
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
0 j4 t$ t( w# W$ Y% \) L2 S {
# j+ x2 M# T5 w* ^- p' L5 z3 o case '<': /*优先级小于栈顶结点,则运算符入栈*/2 w: h1 v6 @" J
Push(optr,opr_in);
- K2 y& c- `; L: R printf("optr入栈:[%c]\n",opr_in.ch);! G% o: e- ]" @; L ^ r
c=getchar();6 ^6 s" \) l6 w4 P$ O( @3 v
break;. {3 Z# E7 E# U) [$ L1 r. F5 r
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
: p$ p7 E) r. ? Pop(optr,e);5 R/ @& U I8 m1 g& s4 V% e N) |# v
printf("optr出栈:去掉括号\n");: ?4 j: [" I \% F1 h, M4 j- F* `
c=getchar();
8 f: w7 `, }3 G. |8 H break;
: R, I5 d- G) U* C9 H$ c0 h- _ case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/ p% Z" x- Y$ S8 x/ R) y- o
Pop(optr,opr_t);& r/ Y5 I0 F6 c2 E0 S
printf("optr出栈:[%c]\n",opr_t.ch);
* B' R) Q( a+ d8 p% v9 j if(Pop(opnd,b)<0)7 [. N9 y0 q+ G
{/ C3 P5 D( M! C" x9 T
printf("Bad Input!\n");
+ B* h U0 ]' C/ a6 n fflush(stdin);7 @; c. E1 l0 X% b) x
return -1;) m6 E8 l1 e+ _$ r
}
" I0 g* z( {5 e5 d1 v2 l printf("opnd出栈:[%f]\n",b.data);" X8 H9 m8 `$ d7 u4 w
if(Pop(opnd,a)<0)
5 }) d) h% n& O2 r0 ?0 s {2 ?5 N2 M7 e. N' C! Z% W
printf("Bad Input!\n");
$ z( I) T* s, s& h# k+ A fflush(stdin);0 B) S" |0 d! }, h. o* p; O2 z6 v
return -1;
# y, ~- g7 ^3 k2 V3 Y8 l }
$ y' f' ^* x( f4 X" b1 r3 J# o printf("opnd出栈:[%f]\n",a.data);
( R, _: R2 h3 |8 I+ a$ R opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
' V$ w1 @- \1 t9 B# ?/ n Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/' k7 k$ l' p$ t5 f
printf("结果入栈:[%f]\n",opn_tmp.data);6 f! v0 i* R) Y; m% U6 a
break;, h4 ^4 K1 Z- M x7 l* G6 f
}$ g# i0 v8 g% X# K" B
}
; ]# b. L2 Y! z0 C" } GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ / w) e) w2 a6 P4 N7 j, J
}
+ y' A) m. C8 g GetTop(opnd,opn_tmp);2 ~9 z, D& C2 _( q7 K- `
DestroyStack(optr);
6 q0 r# o7 Z% D+ r1 } DestroyStack(opnd);
+ T8 I& L, m8 z. R return opn_tmp.data;9 ?& M1 V8 w* q
}
- \$ q. k/ X0 L8 M! u& P% R& D2 ]( E4 r. F* X1 u
char *killzero(char *res,float result)
' o+ S5 u( ^" F{5 K& I% i2 z+ g/ u0 D/ P
int i;
8 {) t$ _% G F+ M! a: M Z, x$ Z* z s
sprintf(res,"%f",result);1 l, N9 |+ \! R# X
i=(int)strlen(res)-1;$ i$ w% S+ g" C6 L* v
while(i&&res=='0')
/ [ g7 I( v, J8 a9 ~: p {
+ ^. i0 W! t& B2 Z1 S res='\0';
$ _# c7 O5 v" W9 l% Z3 } i--;
# V0 ^, L/ C; [ }
2 c* Y$ E. k5 ^$ B% f) m if(res=='.')0 b! q6 o+ V- \4 \0 v) a& p9 _; K- K
res='\0';$ N+ q; t a( ?& l
return res;) c" u+ c- M3 ]3 y9 G2 i
}) N! P, n9 W# n: k
: y$ [6 s+ L3 ]3 v! m
int main()6 ^" p O4 u w* E
{
3 t* B+ i9 Z# z! @ char ch;
& B# W* ]. `' \ char res[64];; k5 O" C3 j( U) ]
float result;
. ?) p6 L) L# H0 \% Y+ ^ while(1)) L9 n: z$ D) ]; Y- g
{, p: w8 u& B5 N+ Q, x2 n3 l
result=compute();
: S! _2 S2 T: X o f# e printf("\nThe result is:%s\n",killzero(res,result));$ ?+ t& T9 m' C5 l4 @% G9 B
printf("Do you want to continue(y/n)?:") ;1 f) ^# S2 [, s4 r+ v
ch=getch();
8 A7 [4 e& t+ ~6 t putchar(ch);& ?7 ^ e) P9 |5 }( i3 q7 m/ @) U
if(ch=='n'||ch=='N')3 X2 h) c3 K. n' Z" R; ^
break;
: {- Q5 d" w4 H; | else# _3 v/ z M! r& O
system("cls");
5 T$ u! L) ]& r: [2 V7 }! o: p7 L }
% A# `. `6 h+ W. Q" g return 0;; ~) l7 g, G6 L$ @: z! _9 |
}
/ v a" I; [, h$ ^- t' y! I
7 N* I! u/ v$ M* q[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|