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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.5 i# z8 w& n$ i! J: a
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=! r- v; b8 F+ ~, J5 w. ^
/**************表达式计算器************/, A* h1 y. R5 X# H% S' i- v
#include <stdio.h>* ]! S! o$ o. P( t0 ?6 _4 y
#include <stdlib.h>
8 v: e0 ^& ~, n' O4 t# K$ q#include <string.h>3 G& T; y9 l, v& e& ^3 J
#include <conio.h>
" _6 b9 m2 y) o0 R4 h% X! d9 j#include <malloc.h># G) F' K% K1 D, x# Q, g
; {- P% h: P0 w5 }9 O
#define STACK_SIZE 100( R R: k3 U9 ~, S& O1 r
#define APPEND_SIZE 102 [+ O6 F ^$ a6 Z$ b( ^8 Y* X
) q0 v/ ]0 ~! W% {7 f# e
struct SNode{
3 b& ~! v4 @' H float data; /*存放操作数或者计算结果*/
7 E# [% p$ f" N4 z" K5 f char ch; /*存放运算符*/
9 S/ {+ h2 ?9 f. g};) b; s0 K5 }( S8 r: B: ~
. v& R0 B& Q3 ?2 |* I% T
struct Stack{ O. D) w0 a5 e% ^* X; E
SNode *top;$ t$ b; G( n1 M! {8 B; V
SNode *base;! g9 I: |4 D( W1 d- H
int size;3 s, Y2 }3 y- W& M* _
};
& r0 e0 j, d9 h7 M8 C: G
' V. {$ P* J! u- |/*栈操作函数*/
) Y! ?% L) A/ k# Y, |int InitStack(Stack &S); /*创建栈*/" a7 W5 v0 n$ b
int DestroyStack(Stack &S); /*销毁栈*/5 y2 J2 Z8 |4 g
int ClearStack(Stack &S); /*清空栈*/3 E' ~3 E+ W: [3 ?7 ~5 x t
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
# S6 C/ \" \3 I4 l- Aint Push(Stack &S,SNode e); /*将结点e压入栈*// H0 X% J' W1 c. }' G
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/- U& \, E# ~+ ^
/ M. h3 G/ D3 l/ A( J0 Y0 O6 L8 ~. B5 J
/*表达式计算器相关函数*/
" Z& u, M" t& ~ nchar get_precede(char s,char c); /*判断运算符s和c的优先级*/- @- ]% {/ Q3 b7 {" i, N1 R" T$ m
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
4 @9 q$ E: Q* F" O6 Ifloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
! |* ]6 |/ j: L, d7 Qfloat compute(); /*表达式结算器主函数*/( P w$ p8 F9 m6 c
char *killzero(float result); /*去掉结果后面的0*/ ' ^ H; g1 L2 I% ^( B* L
# m$ y1 X: q& [8 X+ cint InitStack(Stack &S)1 b( G8 w1 O9 }# m" q; c
{/ C& X8 x+ Y9 E6 O
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
1 Z& D$ D- I: t& X if(S.base==NULL). {1 [4 N: c" c' ~
{! d+ r4 }8 X; l/ E; \
printf("动态分配内存失败!");' i, ~- D8 v( t/ K' O) \
return -1;9 B9 H4 P& `9 `6 J4 D
}* ?) P$ t, n" k! {' y# }, x
S.top=S.base;' q& ^6 e# M, }5 l6 X0 I. f/ C
S.size=STACK_SIZE;
* X8 C/ y9 Q% J, Q return 0;
0 T3 H4 {, A7 N2 p" `1 Z}
% x8 J+ J8 V0 y& G' a% X
* L' N) R5 Y& Hint DestroyStack(Stack &S)
; q+ I4 b* K* Y0 e& y0 K1 [6 D{
1 L Y! ]. p( k- k) P free(S.base);
( O' U; u: ^8 _. t2 g/ W5 U return 0;1 z- x# e: V5 M( t. |. y8 p; J
}/ }$ m1 m' }6 q. \( b6 b7 D
- B& c! C$ `1 {- hint ClearStack(Stack &S)
( u5 p, j* t( y& k7 w; o! i( j. Z{$ ~* f9 K9 W& C; v3 q5 B
S.top=S.base;4 \$ `' D( s: V2 G& j
return 0;
3 Y1 f8 e$ O4 n5 h. K+ J' i- ?}
! o% Q) `" E; n; P+ t6 |
( G l# e8 R" u4 ]! Oint GetTop(Stack S,SNode &e)
( c7 c4 \. j6 ]! u% n4 H' c; ]( o{( P6 N' X7 E/ o$ F o
if(S.top==S.base) Y7 m2 D3 q; h( N4 w: b8 _
{/ l3 v+ d- v9 D
printf("栈以为空!");
% N+ Y8 z" C P E return -1;
$ @, O N( x! L: `% j* n }
( F' n5 c: y( S! g; |# x. r e=*(S.top-1);) h0 U9 @; a' |( {( G5 C+ e' S
return 0;3 d9 N2 S' ?1 k# C5 i9 ?+ k$ h ]
}# h8 f: `0 L* Y, @! H
7 m. r4 d, d5 q- j1 f' ~int Push(Stack &S,SNode e)+ R |0 k! j' |
{
, I8 @" H) m& d3 Q if(S.top-S.base>=S.size)( q# k! |. _9 X' Q ?
{4 Z/ \0 L/ w7 h2 @
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
6 z; o0 ?4 T# T" p5 i8 I5 | if(S.base==NULL). X" h" s/ k* y. Y- }
{, m3 b1 n( S7 v! a+ P) T+ f5 x
printf("动态分配内存失败!");
8 ~. b4 a' F3 M( `% G( ` return -1;( x: u6 H1 n$ a& }
}
% O9 }- K7 k+ j3 Z0 q S.top=S.base+S.size;
7 X" J% ^! [9 ?2 n, z8 n S.size+=APPEND_SIZE;
L+ L; L) g% ?) r }
1 ]9 i4 f" P5 h3 b; y; I2 \# {, @ *S.top=e;: F$ f; E6 s# G+ [# h
S.top++;1 v3 W) C( u( k2 b$ g# j% I
return 0;
* w5 y) i0 ~, A/ f+ i. d1 A}5 |# x; }: k# x+ [4 ?. |& f
3 T2 t6 }4 q/ B. o
int Pop(Stack &S,SNode &e)( e$ [' e$ t9 o4 D( W+ K: J6 b: H
{
1 F' f, p# w7 Q: z0 N# Y if(S.top==S.base)- m" m9 Q% t* Y* O5 ]$ K
{
4 J- H% J8 e' h, S# f7 A printf("栈为空!"); O/ k# o9 s9 x5 N2 ^
return -1;
6 [6 q! ]. D4 ] }
% n3 B5 V# D% U4 |$ k$ [ e=*(S.top-1);
f5 ?5 Q( L+ F% o, {0 w' N4 S6 }8 C S.top--;/ i4 {: h5 [( z# ^, |
return 0;' S0 b" v# H7 A# M& A# m
}
$ |. {! U! @0 a Q
+ S( @# \; T8 \7 V, |. |% T2 Wchar get_precede(char s,char c)
/ O( }- G7 ^5 j: Y{( @4 ^2 ]* t; A: ~' O: K/ t
switch(s)0 a; M; t2 s1 f% g+ G
{) H8 f' o# I, E/ Q' W, ^3 O9 V
case '+':
4 C& Y9 E7 Y' u2 q6 _6 p: U case '-':
: M. I/ \! g8 ~( g if(c=='+'||c=='-')
+ M4 u& X& W# N return '>';
& `/ d: [0 H/ g3 O7 Q* c. Q3 c @ else if(c=='*'||c=='/'). l: j) J/ {& U9 z- B2 e! |, x$ h
return '<';! N% c& W; M. @# ^
else if(c=='(')8 j. H- L! l% R3 `
return '<';1 \: }1 I6 z5 q3 Z
else if(c==')')
- i' V" [$ m2 u6 c2 k$ Z. F return '>';0 r3 }6 L: |: y. N; u
else
1 [9 A* S9 _: s) d6 E# ?9 N. k return '>';
) R; b) `5 ^6 N9 ~( |5 [ case '*':( Q6 O3 l! k: z
case '/':
' Q" v7 [7 _" ] if(c=='+'||c=='-')
% M. ^7 `! Y7 m9 b; n' q return '>';6 q p# C: V( a/ p! }
else if(c=='*'||c=='/')
' i+ K6 x1 K. A+ X return '>';
, c/ z2 D. W5 ^5 X1 F1 U. { else if(c=='(')( l) a9 \0 q+ C7 g$ l" j" d
return '<';
# `+ `. _# m. E0 X else if(c==')')
% |# e+ N* V% V% v/ i* `- }5 i return '>';* Y' y; b" E9 _! n3 c0 _" ~
else- B+ L- Y8 z3 d4 j
return '>';& @2 q, o; U1 H0 f
case '(':3 T- J' M; D+ D9 b. O
if(c=='+'||c=='-')
0 Q* E& I. {. X, s$ V6 k& U return '<';
. \8 T, R3 b9 \, Z6 F else if(c=='*'||c=='/')
( T; o% Z4 p) S return '<';
9 g. i1 B1 U5 W) m/ d' i# @& a else if(c=='(')0 L( r6 Q9 |5 M# j, _) Q7 e6 `# x
return '<';( ?$ J/ i! K* w4 ]0 x
else if(c==')')6 l2 B3 I; s* m+ P- q3 k0 G& t3 p
return '=';
( X+ W' S/ `1 U2 k6 ]+ O+ O# s- \ else, g& p J! ^6 _% i1 O
return 'E';
$ [- R: c$ X/ f9 V3 H case ')':) H2 A4 l$ Q) d/ C! @' L$ B
if(c=='+'||c=='-')
- F4 z3 Y/ G% i return '>';
; s x- l B" E. Q: u+ g/ F else if(c=='*'||c=='/')
8 t3 |, q& G. a. [$ V7 M+ h; V* n return '>';( v x4 O+ p6 i( M, O" G' h5 {
else if(c=='(')
# B( U, Z5 r; n# _ ? return 'E';! g2 z/ N, G" e, j* A" k$ i0 n, M
else if(c==')')/ G; ]! q% a" x9 U* w
return '>';/ P- C! G' H2 ?5 }5 b; Y
else6 I0 c3 i% a1 P% |
return '>';
) i* U! y0 U9 f" e" S! N case '#':$ f$ _6 [' Q: |
if(c=='+'||c=='-')
1 O% P* @. G3 n* E$ l& a) ?: l return '<';
8 E \) I! W+ X9 R' j) Q+ } else if(c=='*'||c=='/')! J; J- g: i! y# N9 T
return '<';
1 u5 H: L$ h% r! P else if(c=='(')- R+ H( Q# N. ~* I: O4 J, A5 l
return '<';
2 F: k1 ?% k4 d6 w1 y+ R else if(c==')')2 c2 `/ j2 Y7 k) g
return 'E';
$ u* ^2 U. y' k2 z6 ~ else: V2 ^3 u( E+ p# d+ v6 u# t
return '=';
. W5 R5 Q8 O! c3 C/ ^ default:+ J' a2 w1 O" Z5 h4 u3 v' s/ {
break;
3 [; f" i7 G4 i. q" h }* N6 b& B u) v
return 0; 7 C/ s1 _. b' o5 d# W
}
! [" l5 W. u: H8 z& ]; ?9 a2 G2 i+ k. J; `7 n9 ]
int isOpr(char c)
5 p8 P U! M# T0 v* K; B{; K: p( S" i# }
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
2 H7 o- ]- C9 B6 |+ m7 q7 v& ^ return 0;" e9 t4 H: I1 q z) D
else
5 G( w& ^7 ] _# e return 1;& W7 G% N% r. y0 p
}5 p7 A8 e* Y: v2 k6 @
# e% y/ I. V$ ~ W5 Q, Mfloat operate(float x, char opr, float y)
' H; y* f2 P c{, T& v$ s) Q2 v0 }3 @
float result;) K; A! f. e3 }
switch (opr)
[ L/ I* {# n {0 j7 E* R2 F' p4 }$ W: d& |, f: U
case '+':
. D4 w9 C! v7 q: E result = x + y;3 I8 P! ~; ^* q* N
break;5 G& @8 E9 k' Y' }$ }- ^
case '-': ' ^8 q) {6 z# U$ J( F8 C
result = x - y;
7 r. U% N7 N. \2 C! F# `+ t break;
3 h: }& O1 ?* X t+ w" t( k# c case '*':
3 y) A8 t" u% g, g8 X. v result = x * y; S: Z( V4 N @0 l1 }, {' |& J
break;8 j3 B6 F' f. `( c% M8 n
case '/': , p& `0 b% ?* J6 F& ]0 F- }" B
if (y == 0)1 R! K) o, \+ f3 Y& ]& }# ?
{
5 C4 a/ V* D( j% s: i printf("Divided by zero!\n");
1 t/ n: i6 U$ l# e- j! E% o+ ?$ F return 0;
% k8 }# O; e& W3 H9 k0 i }0 x: e/ C5 d8 ]' I9 V; I0 Q z/ F
else+ c* ]. O/ \& O, {; t z7 E
{! L" F" n W8 d* j" n; `% D
result = x / y;' a8 S7 [+ Q+ y2 ~3 @9 ?# q; z
break;1 {' A2 M( b2 \$ e8 |0 w1 c
}
0 c- c$ V& R' J4 v1 q. e default: 1 J0 v4 J) T8 n) v% q3 s
printf("Bad Input.\n"); F5 K3 m7 q4 [
return 0;# b( f' }7 h% L; h' Z8 F7 r
}5 g7 L* k4 e1 [
return result;% \+ z! Q9 M! \8 A! F
}
) R' s' [: c8 d6 ?5 `- c
B" m$ D9 _: K: N/ R1 ifloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
% G+ ?+ ] H5 E, f8 s' \{
, E' |8 g E! Q8 R O$ Q Stack optr,opnd;: f% r: t8 I* w# c+ r) @( e5 I/ L
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
% a0 }0 w- Y8 I& o+ ^ char c;
- [- E6 o% v, y char buf[16];
" G4 z5 b+ \! x/ W" q) I/ ` int i=0;) Y6 F! s/ M* F2 j( y9 U2 y0 }
5 W2 n; W* T- A7 K8 v, Q
InitStack(optr); /*用于寄存运算符*/* H7 @0 B* F% B" t! o$ J3 N6 m
InitStack(opnd); /*用于寄存操作数和计算结果*/0 J5 {( i" V$ _1 i" T9 I1 @/ |
memset(buf,0,sizeof(buf));# r$ R9 ?: j7 A O" K5 J n
+ z2 |$ \( c: h" r% a7 ^; K, I
printf("Enter your expression:");
' p; C1 W2 }. X$ T5 u0 B
) h0 A ^# k- _( _ opr_in.ch='#';7 Q- k$ b2 a7 t2 ]0 q+ R
Push(optr,opr_in); /*'#'入栈*/
8 i. T! q, i( j0 I GetTop(optr,opr_top);( j6 ^& h9 Y5 v1 v( H5 {+ ]
c=getchar();
; a- n8 s" [" S8 G: `3 m9 N) X while(c!='='||opr_top.ch!='#')
9 b+ T1 o6 ?6 y+ V {
V: @$ Z T2 K9 J/ ~ if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
; X! ^& T2 R8 u* q" \ {* c" J, w4 b" x/ m' a; F
buf=c;; x* J/ X, ^2 z
i++;6 Z' ]& F+ ]: W; ^8 C6 M+ p
c=getchar();
3 K; b1 c, W2 @* \, c; W }
* _% K6 _7 d2 J! E3 u else /*是运算符*/
3 {0 _4 ?0 f! \: X( I { P& m- A# t" c
buf='\0';
: [7 S a$ ]# |4 J: I if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
% f2 I# R% u8 U$ B X" G1 ]- F {
$ h* @4 y/ g0 f& T. P! J opn_in.data=(float)atof(buf);3 V! f: ?: |( n7 i; c0 D
Push(opnd,opn_in);
$ G% O: ~5 M* x4 u printf("opnd入栈:[%f]\n",opn_in.data);
% w% M6 Q7 L' N+ ^ i=0;
" A# G: E- `% u memset(buf,0,sizeof(buf));
% e8 n5 |0 c5 `& U4 H m/ j3 W2 a }
7 R' ?/ o- ?# [! o" y# @ opr_in.ch=c;
! [/ s6 B0 z2 x2 p4 c0 g switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
% U' c+ U; Q0 N" ` {1 t6 M4 @- W. R9 o; D
case '<': /*优先级小于栈顶结点,则运算符入栈*/
" Z! T0 ~/ A6 X% f Push(optr,opr_in);
$ s" R; Y. r7 q2 ?0 Y. v* D2 r4 L printf("optr入栈:[%c]\n",opr_in.ch);$ }4 {: B# w' t# W& O% m
c=getchar();; o, ~" q2 B) {7 q/ X, c6 ^$ J- Q
break;
' ~9 {% [ y, R. S0 z. ` case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/" t: j8 b: u$ z/ W' c8 v* p
Pop(optr,e);8 p9 S1 R2 ]& ]
printf("optr出栈:去掉括号\n");' K) ~! h' g9 J
c=getchar();) b4 P6 P3 c4 x% S' L i" h
break;
# X' y9 K8 D/ A! X0 W' ?2 ^ case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/! M3 E' H( _* q/ c. @' w% G
Pop(optr,opr_t);8 I' p; _' M# S6 Y9 e
printf("optr出栈:[%c]\n",opr_t.ch);
* J" ~) M0 S) c+ f( _* g5 S5 l if(Pop(opnd,b)<0) f/ J) ]% r( q$ [
{" {+ e- `; c0 S' K/ r
printf("Bad Input!\n");
0 R9 N. ^: T. M' f# O fflush(stdin); g& J7 G) R9 v* N- k. g
return -1;
b o5 |$ q( a1 \) J2 M R }# \! T( S7 w+ m2 e. S; Y! @/ c1 Q
printf("opnd出栈:[%f]\n",b.data);
. \) T5 T' ]) y3 X0 w if(Pop(opnd,a)<0)
) J# \: | k9 U( `! t! v# e* E4 |8 F {( b/ W) o/ R- F
printf("Bad Input!\n");
- b: P1 q' A) _% p* @% ? fflush(stdin);
* Q( t5 q: j3 `0 H! n7 @. g- k return -1;2 }! e0 J6 g/ l5 V8 `$ U
}! e0 C& z# [5 i V
printf("opnd出栈:[%f]\n",a.data);
' L- r K" k8 O) h, U! e% a opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
+ X) Y8 @! K4 ~8 M, v0 i Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/& S4 q$ T1 \# G! U$ r* W' d! H, [
printf("结果入栈:[%f]\n",opn_tmp.data);
# T; r0 a5 y1 r' L' X' N3 l break;9 ^% ?$ w! [* P* r, u* F
}
8 C# I5 O9 w. I O }
& i5 W' l1 h% T$ F T GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ + E4 j$ i1 e8 P% v. G
}
|7 e& z- C* B4 y! [* k2 O GetTop(opnd,opn_tmp);, h* s# _- U" g5 W$ F+ Q( E
DestroyStack(optr);( V; ~) g8 _- z
DestroyStack(opnd);* v f* i5 O0 [+ e7 Q( m! f
return opn_tmp.data;
6 d \7 M1 U) [2 I% \) a- P}
; ]. r8 A; t5 R3 k7 x* U) d
( J7 K* _) q/ L' A3 Kchar *killzero(char *res,float result)) M* B! Y0 A$ s, U7 G9 S$ F. o9 Z
{) j6 d$ ]! t' s6 h
int i;' w5 B/ m5 b" N2 D* B
1 C7 {) {8 v, ^/ p- ^0 m7 x, { sprintf(res,"%f",result);
" |* J7 e: ]4 k i=(int)strlen(res)-1;% U- u) s& e. I! r" P
while(i&&res=='0')$ U% j9 o+ z1 P% Y1 a
{% B" D* [) @6 {- Z6 O9 Q* [
res='\0';
" G& y& i3 Y8 R i--;( n1 e; O9 a) a7 o* h; s, u
}5 C6 I& B9 b/ u( U: \
if(res=='.')
0 `3 _& x6 n$ h/ X! x res='\0';+ W) q/ B9 E3 h1 X3 _/ P6 v
return res;0 H$ s e1 L$ d+ t3 e
}) A1 Z5 ]: q" `( K8 ?
+ m4 Q9 F- T/ z7 q- b; ~$ v1 wint main()+ X$ @; O" T$ o- N1 H6 k
{
9 {% y) [' N* I* @/ f; |6 d$ e! r char ch;
' N' V% S9 g* N. q: j, I& r char res[64];; n5 l+ w7 ?- h+ D% H9 o8 t3 b
float result;- t) O- [1 a, Q
while(1)9 T/ R: y. [. `0 H% A# l/ a& ~+ B
{; `9 A0 G4 |3 Q4 D4 c# V9 a$ Z* |
result=compute();" @4 u. ?0 D% |7 N
printf("\nThe result is:%s\n",killzero(res,result));, x9 s& {- A7 j! `2 D
printf("Do you want to continue(y/n)?:") ;
6 ^( [3 Q6 ^! R; b! A! @0 I ch=getch();
3 A' ~* w5 y$ N. I putchar(ch);, G! x1 C4 O# \ r" d0 B
if(ch=='n'||ch=='N')' k$ t3 r% s4 i, I0 K3 g
break;4 v/ A' J5 g: I2 @2 M
else
: p3 x' e! n- n2 _2 r" k& C( p system("cls");
# {8 M- G6 C, o: |. C0 l' T }
9 x% x$ f. c y+ K0 e" B return 0;3 f% M' }& _* H a
}
5 k/ n2 j k2 f3 [
$ L7 ?5 Y c0 ~% H9 M$ P" j[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|