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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
2 @+ v& o* R. H" k程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
9 r# p% a- g1 w/ z1 }7 C/**************表达式计算器************/
5 r9 E; w/ \2 G9 h& u#include <stdio.h>4 g' C4 e0 m: A4 i8 R# Q) C4 M
#include <stdlib.h># b" x0 j+ F3 L! c, e
#include <string.h>
5 V. ~* i) _ k#include <conio.h>+ d* d i/ _9 g
#include <malloc.h>; z! x( S% c) n' W( V& c( ^- J4 O
: ^ ?7 p) M; R. e7 B. {4 g U
#define STACK_SIZE 100
+ p; r+ J- V7 B2 {#define APPEND_SIZE 10
" T$ q* E0 z5 h; _! }+ i
* M5 @7 v. c$ b2 [8 f2 }* b" F+ Ostruct SNode{9 n' I# Z. e) n! D
float data; /*存放操作数或者计算结果*/' m3 ?& R% B% ?6 B* X* L
char ch; /*存放运算符*/
, S: s1 N4 C, J0 @- x" G0 R& E};
8 L0 a2 {" O& F+ c: e+ L4 N* h7 @ A9 B8 C: R' w% i0 `
struct Stack{0 R: t6 |, ~, c/ U
SNode *top;
3 B+ s( a; ^$ g7 h SNode *base;
) E2 L" ]3 y4 N+ @ int size; ^% B! `* T- F4 W
};
1 Y: a" S+ ?" r5 ]3 P x5 d1 _8 O1 _5 M
& X9 V5 s" p+ u) x. g( @$ j) ~4 [: v3 c/*栈操作函数*/ g& k9 L! w/ `# m
int InitStack(Stack &S); /*创建栈*/
$ x: _! o" n4 |$ j4 iint DestroyStack(Stack &S); /*销毁栈*/
8 m p! ]5 e/ ?" i7 f! kint ClearStack(Stack &S); /*清空栈*/
/ Q+ N5 V( u# C; dint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/7 H$ V$ x2 t1 A: v/ ^+ U
int Push(Stack &S,SNode e); /*将结点e压入栈*/* i/ c) D8 u* x6 U0 c
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ @8 {# s0 z4 r4 i \, ]3 i
4 E6 u% L/ Z* s; g
/*表达式计算器相关函数*/
4 K9 g6 g. p0 g: Ichar get_precede(char s,char c); /*判断运算符s和c的优先级*/
' {% D7 l& P; ^/ c4 pint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/, H; H1 x! y6 a
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/% k% R' C$ G8 [+ p; K# Q k; B
float compute(); /*表达式结算器主函数*/
/ J$ u: F( [5 P2 t% x* `char *killzero(float result); /*去掉结果后面的0*/ 4 B7 K, T% Z1 N2 B; U
. @$ ?: n' y U% f9 O
int InitStack(Stack &S)
9 R1 h2 c* G& q8 j/ p: ~{9 n2 y) Z7 z0 m" x
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));. R- t$ z/ B) p5 f2 c/ u+ D
if(S.base==NULL)& p1 p3 ^" [) Z- B, C& |) I
{
2 k' _# h- H& T% I% e$ R printf("动态分配内存失败!");
) D4 _3 U' ?4 u% w! ?4 s return -1;
P! F5 Z- k7 O7 c" q; q }
1 e1 Q P, F6 u7 @% n S.top=S.base;" r" L, P F1 K7 p) q/ }
S.size=STACK_SIZE;$ s6 g7 K. m3 }7 o1 b
return 0;9 c6 A4 C1 i5 ^- f7 o
}& ?% P' |- G' I4 {* ]
7 k% D6 ^- V# ^% M" w) g: E. g; dint DestroyStack(Stack &S)/ u5 K" k# d3 Z& n- \
{4 ]6 g5 |4 J b: y) ]3 i" O
free(S.base);
. P% n5 V+ j3 w" V6 {, V return 0;$ ^2 L1 N3 b- U- ^4 d: o' ]
}3 } q8 Q# t, p- \' _, j# C
8 B2 V7 Z# z9 \2 J
int ClearStack(Stack &S)
$ l! e# }& @" E: n{
3 V$ @$ O: `2 H, \. }0 j, n8 b" F# A# ] S.top=S.base;
9 W9 w' B G9 X return 0;. n; e6 B- y. R, e$ }2 d" ~5 p) y! `) P
}
1 l- T& S6 X: w+ w
+ j- A6 h0 n v, k( N# eint GetTop(Stack S,SNode &e)
, L" q# |* f2 d* S, r+ N V{
$ s7 V) ?! P3 @) }4 m( b( S) @! H if(S.top==S.base)
4 E8 R1 o% B( `; n { H L( h- c8 j- S
printf("栈以为空!");
$ K5 \ N% \ U, N( Z- X return -1;& ]2 y2 C0 q5 ~+ b8 A Q
}8 Y6 e' g w6 |! B- ]; Z
e=*(S.top-1);
# w3 n0 g+ I; K6 \, }9 x9 l return 0;
8 ]) f" s! Q s9 v}8 p3 P0 |# a+ m4 e
8 E" k% {3 S0 P" @
int Push(Stack &S,SNode e)
' K1 C. W* u/ Q* c{
: o% \) c4 F* D3 W1 u$ X if(S.top-S.base>=S.size)
3 D' G9 ^( J& L' l3 ` {
0 N1 h! u3 y8 p. s0 ^( S S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
. B" P4 s$ O( j3 d0 |, N' |" i if(S.base==NULL)( }- m" z5 I5 L b( f
{
9 j0 S: @5 P8 G6 \/ @ printf("动态分配内存失败!");2 u" M& h; x, @0 l" p, r" x5 Z
return -1;
q. _8 N) c9 R$ I }; j$ m% }1 J7 l/ t$ Y0 J% k
S.top=S.base+S.size;
! x' \2 }* ~ L S.size+=APPEND_SIZE;; D9 i! R6 h3 C9 i, L
}: B+ O- A2 ]( ?7 X3 r
*S.top=e;
( A, V: o: V T% j& n% e$ m S.top++;! I7 Q& c0 i' i# D
return 0;
' ~0 l) [! Q% C- N9 [, j}# f* D( ?$ f- C3 Z
_6 p1 K* N( f* a+ @( U
int Pop(Stack &S,SNode &e)
% p4 Q; T, m8 j( k{
' G7 K0 S, S2 j( j% P5 n if(S.top==S.base)* m/ Q) ?0 s- D, j9 q& B
{6 f0 u) m; F' D
printf("栈为空!");' W/ c- l8 i3 E3 H. G
return -1; q! r6 c8 `" I# [
}
. j+ n! S) x8 k4 O a0 F: f/ } e=*(S.top-1);- R% ^; j7 h' m6 `, ^
S.top--;
" h9 z0 x0 |' d! g" R return 0;' \ Y; _" w9 x1 n$ U7 d& U
}
8 L! v4 N3 `, [
6 L+ c- ~6 p$ s/ k2 o8 N( Pchar get_precede(char s,char c)7 v. x3 G4 @* b* J
{
/ e1 I# D, I0 a switch(s)
$ g$ y% t! w% r! A6 q- k# i: a: i {
5 H* t% J& A2 j- e1 E% O/ C case '+':
! ]3 w/ A6 S! k case '-':
1 q1 T) F) C( K9 Q! Y if(c=='+'||c=='-')
, J- U# M3 Q/ [: s return '>';
' M3 _4 `0 K; n7 W else if(c=='*'||c=='/')9 A8 d& o9 I2 S3 w* D* k- q$ O
return '<';) c' `! h+ N) c+ n# o
else if(c=='(')* ?$ y2 x0 B7 [! a
return '<';
' B/ I: k+ h h' W else if(c==')')7 K/ k9 M( c+ }% u) D8 _9 i5 q7 x
return '>';7 D: V$ t% q4 `( S. n8 b3 N
else . r+ s* J7 J% c1 s) w
return '>';% ~6 o3 X [" B# Q
case '*':8 c7 p) f, s, {+ ^( E) Z$ V* P
case '/':1 a) N9 z I6 e! }7 E
if(c=='+'||c=='-')
/ R. J) _/ f2 @- m/ l1 L return '>';. S0 m+ _5 I& h" G" z1 Z3 J6 p2 w
else if(c=='*'||c=='/')
9 l) x6 b0 A: U4 V: ]0 V return '>';
& s4 C# X" K [3 \2 E else if(c=='(')
5 D2 J4 f* r z: ~: V' s return '<';
0 G2 s& Y* \9 {! B5 D else if(c==')') l7 V, |% r; \& q9 F
return '>';
1 e4 g6 }3 a( n# f r, O! y else
' L- `1 D5 d+ T5 f3 b5 ?0 z return '>';' O- `. Z3 S6 }6 j
case '(':% \8 |. \' Y \
if(c=='+'||c=='-')6 B9 a4 [* `0 n! K3 [8 e2 N
return '<';! V9 t7 K2 K# g- l
else if(c=='*'||c=='/')
( \) ~% L9 K a' x, K. D return '<';
) A- N' r) i/ k0 W else if(c=='(')
7 W7 {9 j4 f% e- R return '<';6 n' b7 [) @% w
else if(c==')')
/ X+ F r+ e% y# H) ]) e return '=';
5 p" T# u* @: m. c+ D else
: k# S8 l2 x* G5 U$ {) ^ return 'E';
( p% N W5 | x3 b case ')':. X+ N5 `. T8 {& O
if(c=='+'||c=='-'), r2 |& @3 H# t* ?; l+ @" U2 ~: f
return '>';% w3 y9 x6 N4 h3 J# p$ L$ O/ _5 {
else if(c=='*'||c=='/')
1 e2 B( t2 ^3 F return '>';
9 h4 o* F/ ^: L4 K9 H5 c9 h6 m' r else if(c=='(')
% N6 O! D) d% h1 f return 'E';5 Z" D- }# Q5 K( r4 n/ O+ g# M$ A
else if(c==')'); ~# U9 V) k: |4 D& B; t
return '>'; r8 t7 [+ Q; k
else+ N. o: A' i, T4 A4 E' }0 s' ^0 f
return '>';
F/ Y" y3 A8 g) o8 ~ case '#':8 Y5 k. z! g) x6 Y/ Z
if(c=='+'||c=='-')
X4 y8 r: b! n. {- ^- X$ {# X3 t1 M return '<';% e! |( k) H+ l1 p( f( s. F
else if(c=='*'||c=='/')
1 ]1 ]& T8 E& \; m" u return '<';
( O+ U# P% Z# r/ j% A n/ Q else if(c=='('). X7 w8 r& |3 \' A0 W! G
return '<';
; c. A1 O4 ]& S' m- @8 x/ E else if(c==')')
: Y; m- r+ X' J: ~1 ~ return 'E';& @# p5 \ y& j! |
else+ i9 p3 ^7 F3 \" ]% b
return '=';1 H" R! Q" @8 {/ ?0 j* y* g
default:
! E) t7 D1 Q, u+ F- _ break;; d* f/ M H+ [4 F
}, j; m s, B% A' L
return 0; " m. |# C5 `. u. c6 }/ l( ?7 E$ c3 F) P7 k
}5 Y8 k8 `* O4 H' Q: _- G
' T9 y- z2 g6 R9 ~0 \int isOpr(char c)
4 N0 Z2 A: _1 K/ j4 h! h2 |{
3 s* k) N* \3 T& S. _+ y0 w7 I if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
" } @+ P. U+ Q return 0;
$ D' E) @5 Z( p W. E7 p else ) p+ ^8 i" M6 t4 z& w
return 1;! m% L) \" N/ w- B
}: p+ r$ s% W K0 Q) _( F
& F! X2 N# W. l0 ffloat operate(float x, char opr, float y)
( q( {' b& E1 n5 N6 g! U{
* p2 }! ?0 B9 h9 G0 i; f float result;
1 H) N! R r6 }+ \; |- P1 u9 d switch (opr)$ h. c% `$ ?; @! }, B" U' y1 U
{
: G; B" k; V1 I3 ~ case '+': ' m4 t: W1 k' i( W8 I
result = x + y;
! X! ?/ D. Q3 `# v Y! a7 i+ B break;
: O$ c% b0 H. c f* b d. | case '-':
2 ]- S: @ v: ]8 h4 Q& g5 S result = x - y; h( {8 F5 I0 \- j! j
break;
: w. l9 m% O% B case '*': / E) z, v1 s6 o: t7 h3 x
result = x * y;
$ p1 m( n* b" v& S R# V break;$ \4 g' y" @+ m2 K. ?& Z: E9 T
case '/': % v/ m# k4 J* V3 f
if (y == 0)
; ^$ x- J/ O; I: z {
: P1 x1 A; f4 g& H& l, ? printf("Divided by zero!\n");. C% G; n; q% k; B$ v( G0 T3 q6 Y
return 0;5 a* q0 p. r! x6 p
}( H3 L9 `8 M% @
else$ p" ?: S; j0 F/ w J# S5 s n
{* T6 d8 F9 p0 J% M% e0 K
result = x / y;
3 |$ d' C a! R2 p break;3 e; R/ C, X3 ` v) e, U) }" {4 H; D. l
}
& n; J9 D. v. a default: / x( m1 G* K( ^
printf("Bad Input.\n");
! t5 p. h; _$ Q8 e return 0;9 z/ x+ K1 D5 u4 E5 K% r
}9 ?% F) N5 V j" g5 B3 v
return result;
) d" p/ [1 x+ D! S" X} " N' {/ R+ d0 m1 B5 `0 L
- p* J' m5 e8 g7 A1 E! g% Wfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/! o, e C |0 m* o: m" ^
{, V: k, L/ m, N) H- h" Q6 C& @" T4 ~, x
Stack optr,opnd;
! J. R l% N0 O( n struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;. B. Y: m5 h3 c* p8 @6 P
char c; L# h% j9 L0 V m. o
char buf[16];4 a) z6 x1 l. `5 {+ ?9 ~! G) Q
int i=0;8 Q% n5 G9 U2 F# C! j+ b' ]
1 v! t- ?( ~0 a# y* e7 H InitStack(optr); /*用于寄存运算符*/# u3 m- D2 M0 t
InitStack(opnd); /*用于寄存操作数和计算结果*/
9 }% s. [( \. K4 Q/ B# e memset(buf,0,sizeof(buf));
# @. I! X. F6 s, U. `; C
0 @/ x$ q( H `5 A* g" j3 P printf("Enter your expression:");
. v: a% q d8 |* s
& ~5 g. h2 U2 F. J& J) y/ D# y* b opr_in.ch='#';
( V9 K8 y% H6 t8 T4 g8 b Push(optr,opr_in); /*'#'入栈*/- Y$ n' D% P8 q# K
GetTop(optr,opr_top);6 ?: V+ y/ i" @
c=getchar();
& [. x; P; h+ \+ ^5 R. M while(c!='='||opr_top.ch!='#')
, |- z" h" C* V) j1 k {0 F* a9 Z- t5 {# A2 K; f* {
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/* ~! u! ^$ N p
{9 D, T' u# h% [0 R* V, V
buf=c;
% N7 \% L( _/ i1 g4 N5 s i++;
' E" u8 S* r8 K3 { c=getchar();
9 f8 E/ m/ q: `; v }) O0 `* c+ L' N3 W; R5 I
else /*是运算符*/$ b* n3 L8 j2 a& F. y
{
( I, D2 O3 J* I% Q0 x buf='\0';
# {% D: c( X. G) K. I% @# }* p9 n& U1 ` if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/7 y- x' l/ O, g( t. y1 M7 \
{
' c0 c- V9 f3 v+ y, C- H! i- M! K5 g opn_in.data=(float)atof(buf);
9 L( Z$ |( e Q; a$ ~8 V3 j' m Push(opnd,opn_in);
+ Y' b: s* g; J+ x8 V! r' \4 V8 @ printf("opnd入栈:[%f]\n",opn_in.data);
: H! w: L: W2 ] i=0;! | @$ u: r( V8 }: \. d6 F
memset(buf,0,sizeof(buf));
1 D6 R( o. ? c, N }; q5 s2 }# f( m4 }9 E
opr_in.ch=c;7 h0 p7 Y& N/ K; i; v
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
/ p1 J/ Y4 {5 M# I {, k. j. }$ G) ?
case '<': /*优先级小于栈顶结点,则运算符入栈*/3 e9 S c& K9 O/ m2 N
Push(optr,opr_in);2 z4 C0 s6 D" r) M4 Y+ O
printf("optr入栈:[%c]\n",opr_in.ch);
9 U. R: d& N N! {( J4 ^ c=getchar();
! R% x* Q0 }0 E( j! D. @0 R break;8 m+ E, X3 X3 G) C' U0 C, J
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
8 J' p+ Q, u7 v/ u6 w! v; s' d/ |9 p Pop(optr,e);% s1 L2 Q* U$ L$ D: a
printf("optr出栈:去掉括号\n");
0 |, P6 }0 u: t8 M$ Z! K- [ c=getchar();
$ c: l' o* T: D* \7 _' d6 W break;
; b( z4 K7 e" R case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
8 u& w: E: a8 U$ H! C2 J1 z Pop(optr,opr_t);
. g. t: r+ P: I" g' B9 f5 i. S printf("optr出栈:[%c]\n",opr_t.ch);% P) {: \& I' o$ S
if(Pop(opnd,b)<0)& M, A% v0 G4 z' V5 ~! Q" L1 {
{5 L/ I9 Z1 u$ \7 k/ e) Z8 O( }
printf("Bad Input!\n");0 b& M" d+ P/ h
fflush(stdin);) v. C$ D+ O3 |) ^+ _ A
return -1;
$ z: V& H' D) r! l: K, c }5 N9 {9 Q' O( M
printf("opnd出栈:[%f]\n",b.data);9 D# z. ?7 \( r) t
if(Pop(opnd,a)<0)1 M) N( t+ s, q% I8 ^; B' Y
{
9 M! y) o. I( ~+ s% V printf("Bad Input!\n");7 D v( I0 \/ k& N
fflush(stdin);9 T! p5 _! m1 U' g
return -1;
: D3 J/ J( l r* w# ] }( [) r+ U: l0 ~0 h4 x" x4 `1 r5 z/ J
printf("opnd出栈:[%f]\n",a.data);
& Y& q. b- |4 l opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
" U$ ] M t' G0 w% U# N Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
" E) I& R; v; e- c4 ]0 Z# W printf("结果入栈:[%f]\n",opn_tmp.data);
# n& A8 m8 @. e( l break;- \+ |; C7 C' T2 j8 }, N
}
( L5 e$ ^" F5 P3 v1 A }
; S+ r4 }4 a Q1 V GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
/ R9 [: ^: S/ W2 m- S N5 O+ _" i }# Y! @) y5 @. W3 q8 d) X
GetTop(opnd,opn_tmp);" h$ J8 q' r4 S
DestroyStack(optr);
) A; I5 z. r7 [. S; f" G" |% B DestroyStack(opnd);
. z. x% c- w4 F# l return opn_tmp.data;. n3 m' q' r# i) j; M. L5 Q
}2 Z3 M% K- G* f3 b/ ?& f
* k% n8 ~8 \- \% w2 [. f% ^7 \* |' Cchar *killzero(char *res,float result)
4 M' h0 l/ s% d; x1 p+ b; e# _+ U{. B7 @0 t0 l) F3 L: F0 c
int i;6 J; ^# K) |% Q' X: Q; c- L
" z9 I6 ~0 v! J# O& v sprintf(res,"%f",result);. W) L) s5 y7 z+ c! A
i=(int)strlen(res)-1;3 m' |6 S( Y$ W5 \! s. I1 J
while(i&&res=='0')$ J& O2 _ }5 w9 x" r# S( x5 m* y
{
8 Z' L) i* T: }' g' ~ res='\0';: T; s; [. D9 n m& W) [
i--;* P' E f4 K: Q6 z
}" z9 A* J/ y! R* ?3 f$ ~5 |5 L4 d
if(res=='.')( i2 u! Z6 L; E
res='\0';& D( t, O7 p7 ?' L" o& V+ C
return res;' q% J! h5 f/ m4 j# f
}1 K( i1 \- B2 z5 ] X( F
: n5 I% O$ m! L2 M9 r1 Nint main()/ V; [, |4 k+ o& |! o0 o+ A
{
# o+ O4 n5 m0 p' z# K- W char ch;' ^7 ^. r; l B" s! P, e3 X
char res[64];
# a9 q* f- X# R# G4 T) P float result;, P2 P1 x1 m. H* n0 {# n ^
while(1)
- {0 C: s8 P- F* n0 Q {
+ Q' M, u/ `% g6 ?$ H/ F5 o2 S result=compute();1 H @9 k# q0 {# n' v9 }
printf("\nThe result is:%s\n",killzero(res,result));+ E* D: G l! h. g
printf("Do you want to continue(y/n)?:") ;, D1 k. _+ V: u- o- ]
ch=getch();
; P7 r' r6 e5 T, u- b3 S& B$ N0 ~ putchar(ch);/ M' C" J& O* y9 _0 L# p
if(ch=='n'||ch=='N')
5 S1 z7 ]" _: z break;
0 p5 b m! }% x4 R: p else) \3 d- `% \) d* G2 ?( P' L
system("cls");5 r P5 o5 ?, {$ |% J
}
& F- t; Z2 S- J5 I& F! W return 0;4 N6 Z) e2 A+ ?/ h# l
}
G) d, n# [. P8 i' v% g) ]6 ~* S" a. Y: ~
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|