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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
7 ?0 p1 A( q' N- j# {3 i, o程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
0 Y' @& o. H8 b7 i/**************表达式计算器************/
0 N' {! @" V: O* v! X& K; M+ ?1 s- s#include <stdio.h>- y7 Q8 p2 V* _2 S
#include <stdlib.h>
! G: X( X6 O @2 J$ [#include <string.h>! k: v* y: U( q) q! {: `9 q4 K; `# z& q8 b
#include <conio.h>
0 A; L' T9 s% [( p" @#include <malloc.h>
. n3 J% b. z8 x+ j
. Z6 s2 a" L0 {8 e. G9 ?) @#define STACK_SIZE 100! S. P* d, l, F" O5 x" r
#define APPEND_SIZE 10
# g p; J0 G- d$ F$ K/ q8 K$ _3 l* W5 J- k6 j
struct SNode{8 Z4 P' q% r3 p" M
float data; /*存放操作数或者计算结果*/
Z! _8 f$ x% G4 S$ q! f- } char ch; /*存放运算符*/
# S$ ~8 z; a E2 B( D, u2 H}; v" f# u# Q" o! i% P8 _
6 G5 N& o u( g" e4 x8 ~3 Mstruct Stack{
- [2 G' p/ P! u( j6 v- [1 v SNode *top;5 A$ @5 \" C/ G+ h
SNode *base;
2 \ R- V" T" b" g0 r y int size;
3 U' x) e' X+ L, q. A0 \ @};
6 |$ x( i, \. ^# B5 l2 B- a6 n1 ]6 h( T* J9 K' N
/*栈操作函数*/
" Q Y) E& v r& }int InitStack(Stack &S); /*创建栈*/
7 r, g1 j' d4 z: I6 L) a7 M. \int DestroyStack(Stack &S); /*销毁栈*/) |. c* l7 ~0 z( q4 k, z
int ClearStack(Stack &S); /*清空栈*/
; R8 c( H7 ~: t+ Sint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/. L( t: O0 z( ]# m4 V6 |
int Push(Stack &S,SNode e); /*将结点e压入栈*/
4 n Z' u0 g' p! x$ \4 |int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/& O9 l" I, W/ L6 e/ b4 y0 L
) N$ h$ E: K$ ]& ?8 E% a3 b" s/*表达式计算器相关函数*/
; o" `6 p# w6 _char get_precede(char s,char c); /*判断运算符s和c的优先级*/
, @4 _% n4 L' V/ Z3 i2 xint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
1 U' [7 X7 S7 p; n: ufloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/4 r! n2 x% U$ m
float compute(); /*表达式结算器主函数*/
1 e* n9 L/ f& J% t5 w. ~1 ?7 V/ ichar *killzero(float result); /*去掉结果后面的0*/ 7 b+ s8 u. L% {" Y& i+ i
/ V, _; h( M1 [6 J, y
int InitStack(Stack &S)
1 U+ [; C0 L( O, o; W6 {* y3 m, K$ B{
" N Q7 t8 J) U; M2 @ S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));' D5 }. _1 x/ L |; B' v0 }, r1 e' e
if(S.base==NULL): k3 \! q) }; a
{
$ o: B: ~ L' t0 @$ D2 c4 y printf("动态分配内存失败!");
6 d/ S P8 s3 w* A" L; u return -1;
- M) W* d* a, P( d: T }" B* o1 I/ X+ C/ u' W7 U$ @
S.top=S.base;( J( N. @) Q: f" |! M' Z
S.size=STACK_SIZE;4 i5 H( j0 ]" ~' q4 h2 ]
return 0;7 W% L7 }+ y# F, E' N
}6 F" b5 U8 w1 \! ]3 z
8 f* u: Q8 n5 m- [
int DestroyStack(Stack &S). x2 T2 `8 M8 m$ r
{
. F `" n- N( x* p7 A% L! v free(S.base);
% J+ b1 _ N! [ return 0;+ O- H- }' R# U9 L
}& K& N* s. E- j2 P# B; E3 R5 l$ \
0 p3 ?) b) {# V
int ClearStack(Stack &S)
6 J- m2 |+ b* H- V% z9 p6 U$ {{& E* z+ r, L8 d) w( G6 U
S.top=S.base;
; X E9 o/ n! y- u return 0;* A" @/ c; }4 a4 d! e3 D$ j5 j. t
}
( e* h4 ]1 N% c- H( m6 y- h7 ~8 j% i3 b' g
int GetTop(Stack S,SNode &e)
- Q4 w5 I$ F- J0 h( h9 t{
3 a$ _( d: K; ~" M* \ if(S.top==S.base)+ C c) ?6 y4 ?: {) }- |( D
{
& u+ @0 F/ J7 K printf("栈以为空!");1 I# x/ C5 M! z) G! k
return -1;9 }, p' B6 ^6 p- U
}) i6 u9 O7 n s* S9 L9 Q
e=*(S.top-1);
+ y0 W4 r( {6 j$ \' d0 X- I3 [0 m return 0;* h% S6 r/ m8 ^
}
2 u' Q3 e' R [/ c2 l1 _; k- | U% |$ K
int Push(Stack &S,SNode e)) W: {" ]% R ^8 v2 h4 E- h3 C+ L
{
2 \- O9 l1 s F& ~7 { g$ x8 S; p if(S.top-S.base>=S.size). M3 ^; g1 p5 A
{* |8 D* t. A- K( N# L
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
, p- `. K! i9 V if(S.base==NULL). s9 t& T9 ~7 f6 } T) t
{
1 j3 r" Q B# n7 S" U printf("动态分配内存失败!");) a0 {2 [7 I# |; S% m1 Y/ L! N# H
return -1;
; @' l; s2 k9 g$ \/ N$ k }
* J/ @1 w7 {1 ~$ k! V* q S.top=S.base+S.size;
! Y4 j' C: o1 q) |( `- m; b+ ~$ N4 B S.size+=APPEND_SIZE;+ K0 o1 C. O7 Q4 l2 E
}
, g n5 V% d2 I% ?$ q9 q *S.top=e;
/ V9 V: K) B( H1 |9 z1 K S.top++;0 l. v- ?$ Y: }' Q% Z+ T5 l
return 0;- e; n; T8 L8 U5 E; ]% _
}
5 u" p; d6 J, \, v( K3 b1 Q+ T1 X) \# T" c
int Pop(Stack &S,SNode &e)
" N9 Q' o- H* E& R{
' H; M. q- w, P9 \) z if(S.top==S.base)& ?/ m( c8 o: ~+ P9 F
{
* e; Q( \/ S+ F4 H printf("栈为空!");$ x0 Q2 t' _1 L
return -1;# z& @5 T z/ G) y7 I- i
}! c4 P5 i, \- T% ?# ^/ u! x
e=*(S.top-1);
' T5 A' u1 P2 ^; p s S.top--;
6 O$ z4 J" B- ? return 0;
2 s! m" U4 k- J( ?4 f}3 z0 y1 A4 h( ]; r* Q$ ^6 X
) d, ^1 ^5 V: W$ M2 Y
char get_precede(char s,char c). o z+ |9 H4 I, O% n
{
4 B1 T% G) s6 Q4 M switch(s)
. j/ r" E0 c2 y( v/ o& b2 Y: | {8 k& t% V; S h x3 L: v7 R
case '+': 1 v; s" z. H2 l" R
case '-':6 J, Z! {( Y+ ~6 Y0 c
if(c=='+'||c=='-')6 J; h+ u1 C7 A) K9 R x
return '>';
" M; w9 Y& j+ s4 z" I- `7 P% K7 ` else if(c=='*'||c=='/')1 u O: k- D; R$ X% @8 p$ z
return '<';
8 [: z7 a0 n$ Y% l5 ? else if(c=='(')* R1 _( ?0 @/ `) {# Z
return '<';
) a J4 i; A# ^; E' b8 W; p else if(c==')')
# i1 a; {2 ? z' n3 }! ^ return '>';- c4 V; p8 C2 f7 S, H! ?
else ; n/ g- q1 T4 V P# | \0 J5 E
return '>';5 o9 d4 a' T- e: y# U3 ^
case '*':# K$ U/ z# H0 }2 ?
case '/':5 v3 n2 d; v* T/ B( l
if(c=='+'||c=='-')
6 R% N& g9 h) S return '>';
! a& c3 J; m" A7 ]8 i* f8 @6 H else if(c=='*'||c=='/'). n+ i d$ m: v' ^
return '>';4 O! R7 m+ _6 V
else if(c=='(')# R) L, P/ H' [1 j% u
return '<';
+ J# [. w6 e' G" W. V* K! \ else if(c==')')
; L7 d1 m3 f& H5 h# X$ S, q return '>';
4 b& v- `& D! S0 H: s! s' a else2 V! h6 z t# s7 p9 L; {* G: K
return '>';
! \/ O' A x3 E# |# V0 ^ case '(':
) e( M' q, \. L3 g; K2 h if(c=='+'||c=='-')
5 |/ m* ]2 ~3 [: }, G: H% } return '<';: I o4 T4 f8 o8 y D+ n/ _9 x
else if(c=='*'||c=='/')0 G& W5 w* Z& x; }( |
return '<';3 v4 k4 z$ m+ T1 o( ?" P' ?
else if(c=='(')
/ m( d2 ?/ v) f+ T% ]! g0 V return '<';
6 U* p8 A" b" P# i else if(c==')')0 T9 ?' E' }; v# x* }
return '=';, H* g1 t4 |; y5 |% s$ g5 p
else
: C2 D% _5 ] a c. o return 'E';: Z2 i0 a5 Z( ^9 @6 F
case ')':
4 N0 \1 Q4 ]8 q# A if(c=='+'||c=='-')
4 h; r! c. e2 n* m. B: g return '>';8 p. h* U N8 d ?" B
else if(c=='*'||c=='/')4 {/ U7 y. z j! [8 j3 d
return '>';: a8 t3 i8 M, D5 w' S% ?. T
else if(c=='(') O5 ?$ y- U: X$ ?! r( }# {: d
return 'E';
3 e g7 W0 G3 L9 W else if(c==')')
y6 U( I! I* m4 b5 Q return '>';
& t$ ?. Y" M: B else
5 _( S$ @8 ]( s4 r: V# v, r return '>';" q6 T* \8 M3 P
case '#':1 i1 w/ x% L* \0 n( `
if(c=='+'||c=='-')
2 { U- g; y, a6 S/ s& o' G# q return '<';9 a9 u S" U. X( i7 @, \. _
else if(c=='*'||c=='/')
( t7 h( T1 M) h return '<'; z+ E( f1 S* R" G* E# X
else if(c=='(')
* A( m m0 }0 v% ?5 M3 h5 u$ x return '<';' ~, Q) c. f o I
else if(c==')')
( N* D2 J+ {5 L! _ return 'E';, u3 B4 n% f3 i9 K# U
else$ H* |7 o) ?0 E- x
return '=';$ Y' ?" L& d% F& h. f, _
default:+ G; ^, n7 k2 J! @+ @- c
break;1 p7 i0 Q K+ y9 I( |- G! ?
}
/ P, i p: C$ e8 n3 U( r' x& K* | return 0;
, b Y$ J+ I4 ]" |! @- s}
9 H. g, T% S; d% `) K' b# ] B# N# U1 B P( i9 }
int isOpr(char c)
: Y: y" j8 a' Y' |8 M8 l5 F{0 y( |% t1 _* | ?9 l
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='): r: u0 {0 w X; K
return 0;+ @! }# X' P! `3 ?4 X
else
$ U4 E5 w7 z* t5 R: R. i return 1;
, @2 j7 e* s; i$ d1 s}
( c! j+ F3 @5 M6 x( n8 s% E+ t: l- `5 z% b% ]+ q& d
float operate(float x, char opr, float y)& N& X V% S, p' x7 c/ p1 O
{
- I t# V9 {' d, L1 K float result;+ [& J, J* x5 y1 P: l- N5 S' y* F
switch (opr)& ?+ j. }6 E4 D# q3 e. x1 p
{/ w: v5 U" z \
case '+':
, ~; {+ J; [! T! n) k+ F$ Q; Q result = x + y;/ K, w1 f9 r9 V5 K
break; j2 N0 T6 I7 s9 v* S5 t! L
case '-': 0 ~/ Q# E! C) _9 Y" y' _
result = x - y;
' H, h \% x: a8 K i9 A break;* T1 ?! Q! F8 h3 \3 f6 u, b. C
case '*': ' i, @$ l" \! O, c# P
result = x * y;2 o/ G- ]: c5 \! e6 Z, O- S
break;0 A( a9 x+ F( C9 [5 T! t
case '/': * ]* ?1 J4 L; I8 f# A
if (y == 0)
" C6 _; h; `0 \8 ~2 c {
. [# W2 e {, R printf("Divided by zero!\n");1 Y& [1 z7 X' x4 ^; B R
return 0;6 o# h: H) L8 i) K
}
, Z& T/ I$ D# D5 F3 J! ?' ]+ J else$ \: x% h) N6 @4 c$ }; |' q9 r
{
# X8 t, h+ i' p/ x# Y" z result = x / y;/ [' T/ g$ [8 T+ w5 \" b- }* B
break;0 x$ t# I6 d$ Y5 p Q; N! N4 j# D
}
) V# |1 l- @7 ^1 z1 a2 x4 { B9 a default:
0 {8 ]% E6 V6 H# y2 ~, h printf("Bad Input.\n");
. h6 @: F8 O( l- [. S! H return 0;
( d# x3 t# r7 g% t }1 T" O9 f; d' m3 z
return result;
; B7 V: M7 m8 x: Z9 c8 H}
$ P- D+ F! g: I& a+ e1 O& o9 a- Y- `
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
. _5 J/ B3 Z8 I& {# }1 E{) ]9 A3 K3 I4 w# u
Stack optr,opnd;
% E6 V4 a. {# v; d" u+ v6 V( b- a" N struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
/ ? _8 f7 ]+ T- t char c;
0 A1 W1 b/ s/ u2 @ char buf[16];
: D' ?$ ~3 u4 D5 r; }+ g( r) u int i=0;8 T* n) y O7 K6 J! |% ^
, o& d4 P: w- p% z' o" I! }, ? InitStack(optr); /*用于寄存运算符*/
# p+ Z7 D) C1 P4 X+ Z InitStack(opnd); /*用于寄存操作数和计算结果*/5 J. W' R9 t/ k, L+ Y6 w) P! T' R
memset(buf,0,sizeof(buf));
0 N3 w3 l5 u- B" w ( _* W0 [+ J7 f
printf("Enter your expression:");
9 [3 @1 ?+ i8 g. ]
7 J! N2 e A. v& R) ^- n% n+ Q: g opr_in.ch='#';5 H' ^% O, N! Z8 F. B4 z
Push(optr,opr_in); /*'#'入栈*/
( r5 X5 J! ~/ I% r; N, B1 U& I! z GetTop(optr,opr_top);5 D/ z% v# c" e" t6 T& j
c=getchar();# |) L' X. }$ i' G. C. {' h9 ?
while(c!='='||opr_top.ch!='#')2 i7 p u0 R' i% V) l+ _" X
{
# u6 B+ n1 m# |; E* ]6 z if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/' |* D8 Q3 a6 e+ |
{' @( V; F) S3 W. N+ b
buf=c;" [" u+ M( |9 L0 b8 o
i++;
) i. z" B# ]8 E c=getchar();
1 O- P% e/ F2 Y5 q! f( T- w }# i( X) `- n- l8 X3 t
else /*是运算符*/
2 l S, ~/ m/ x; b {
% f8 G5 h c( j* k buf='\0';1 k: _( z I7 @1 K6 S! m1 K/ s1 p" l
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/$ M( t& M* r" x/ l# [. Y. n9 k
{
" |+ ~1 m( G0 S, u8 e+ n opn_in.data=(float)atof(buf);- z4 h6 C! I' U5 ~
Push(opnd,opn_in);
4 _7 s6 |* S. D0 { printf("opnd入栈:[%f]\n",opn_in.data);) a8 `) N9 w' i
i=0;
( }3 o2 q/ K% N; z memset(buf,0,sizeof(buf));
G4 f/ L2 I1 w/ s0 ?; I } }
8 a/ j2 c0 \ R* K" X% S" x opr_in.ch=c;5 Q4 ^$ a1 ^( }2 y
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
7 {6 f& ?, k: U6 Z Q {
* ]! Y8 L3 q2 N M: z" J& o case '<': /*优先级小于栈顶结点,则运算符入栈*/# Q# c- m5 Q: v% T
Push(optr,opr_in);. n% d5 h5 N! s6 ]
printf("optr入栈:[%c]\n",opr_in.ch);
9 l0 `3 T5 h& u) @' d0 C c=getchar();! \ d. H5 [3 M0 `) s. q
break;
5 J2 p9 ~ O: K; [3 H" ~% t case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
& o; L$ f/ A# s7 b Pop(optr,e);8 Y1 v) R, P' ?5 f! v9 R$ ~
printf("optr出栈:去掉括号\n");
8 E6 G9 F8 m3 v( q, i c=getchar();! L$ w3 v# C x! Q/ @" E
break;1 m; h" J. X/ }# E% F$ E
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/4 P. Y: Q0 ?; h
Pop(optr,opr_t);
6 i2 X' {5 C; P' d2 b% [1 K3 J printf("optr出栈:[%c]\n",opr_t.ch);
# W; D3 d( q6 K9 w/ c& e6 }3 i, t if(Pop(opnd,b)<0)- J' q3 u1 }0 K$ h
{+ Q& `5 c! C/ d- g7 F4 a: _
printf("Bad Input!\n");
0 A) X: F# m+ q3 ]$ ] fflush(stdin);' Q* D" Z$ F' {3 o- o
return -1;, I4 w/ A, o' f) C) N2 p+ n
}
( ?2 G+ U. N4 k4 h printf("opnd出栈:[%f]\n",b.data);- v2 [1 W+ E( A+ j& B- m- i
if(Pop(opnd,a)<0)1 r+ v$ P8 `9 b5 @) a9 u' l1 Y
{$ z1 m: }( k4 o- H g
printf("Bad Input!\n");( K$ H4 p4 g+ V _" f. L
fflush(stdin);, f& ^- a* Q$ V% G
return -1;
# i$ h* w" n6 n `9 Y" m7 |+ Q }6 Q, u; K5 E/ ?( ]
printf("opnd出栈:[%f]\n",a.data);
$ a; K. f8 Y& A. R( F, k opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
) _2 [5 x C# ` Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
% T0 D: x8 ?# f- |" o printf("结果入栈:[%f]\n",opn_tmp.data);
8 t) [+ p+ X3 z! d2 f, Y break;
. _4 N7 {% T2 ~+ ^4 X. b9 l- p$ f }, A9 f6 G: d1 M6 g5 _& i
}
+ z6 q& C6 I0 f6 j! j& J GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ % E [( T2 L" n/ [5 j1 e
}
# u Z- p$ \) k& s/ s; Y' @, X GetTop(opnd,opn_tmp);& u! F s# K$ m% z* _7 a
DestroyStack(optr);
4 I i( A# c8 D* S7 u+ _ DestroyStack(opnd);- ~" L: o7 q( h ^# D
return opn_tmp.data;, X0 R! b' ]7 a, ~3 `8 F# v3 D
}
$ V+ G: P5 L( B* Y5 Z
, i$ s& p! w# q/ q- x* P' i- t9 ychar *killzero(char *res,float result)" ?: p8 R: o5 a: _6 X5 N4 d5 B
{
. P x. Q0 A4 m- Z int i;4 d, p4 Y6 R" X# g' R8 _: K- h
% w% p2 \& D& X
sprintf(res,"%f",result);
?5 H2 s6 P f0 U i=(int)strlen(res)-1;/ A. j( A9 x) T; n+ N8 `: I7 u. M
while(i&&res=='0')" J: t7 W5 ?+ X* ~* v* J
{* H }: p( j0 o( D4 h/ n
res='\0';
5 r4 X; T5 S0 y% j, o i--;
4 \ f+ k3 l h* i) z& \8 `) W0 ~ }2 j, W* ]5 \ [2 k! I9 J3 O
if(res=='.')
3 M% w4 J6 y1 R4 t0 f: a- J7 @ res='\0'; p# ]0 G; F7 A1 K3 s
return res;
' P l$ J! Y! c: i! ~% \# ~}5 Y) n+ Q, C1 Q4 w6 p2 X- j
& C; J" B! p9 F' Q: I# S# Eint main()2 q" Y# X+ i7 z6 D% O
{3 p# o; Q4 _' C' g6 o3 i4 @& ^, U0 l
char ch;+ Z2 ~. q& K# G' k/ ]
char res[64]; Q4 x0 W- O( h3 }+ b" f' Q
float result;- o% j* Q/ m2 F% v
while(1) z: U, K9 h' Y8 i! y7 V1 O) U4 U
{
$ a' r4 r0 Q2 c; _' v result=compute();
- B" g* K. P6 p0 Q/ n printf("\nThe result is:%s\n",killzero(res,result));
" S5 L' `% ]% h printf("Do you want to continue(y/n)?:") ;
# t/ s& {9 C1 d7 Q: u ch=getch();- j! @' x% I( O# B. T9 X. I7 z
putchar(ch);" a6 p* D) J7 N# b0 y" ~
if(ch=='n'||ch=='N')) X8 C+ n% o: B* ]
break;, ]3 v; U8 H! H) @+ K- W
else
+ ?. E7 ~# R, x3 z( ` system("cls");
3 `. U$ n: z- t8 N& E- g. b9 { }4 W0 R( V3 A6 {; v: ^: n! _
return 0;2 m# Z) G5 R2 U3 L' \5 g4 C/ d
}
; Y0 g' n" U5 Y' y( o9 L
; C! Q7 t/ I# b- {! [3 V6 i# G3 {! o[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|