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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
( R! L% z2 d; T# R3 x/ c, `程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=6 q8 A( n' k" o3 f) f+ s
/**************表达式计算器************/
) r" _! Y4 Q8 I! [& ?: v1 v$ ~9 p* f#include <stdio.h>
' }; }2 ?9 r$ e7 ~* B#include <stdlib.h>
* U }' I) ]5 K0 a' X#include <string.h>3 k7 [! f7 X N
#include <conio.h> R- [& U7 k; O5 }' O
#include <malloc.h>
- C9 M, W* A' S* `% s
5 ^! ]; D& p5 ~" ~6 b; r. D2 R#define STACK_SIZE 1008 _* H: }* D% \6 i2 G" ~7 [
#define APPEND_SIZE 10
) F& a. ~4 O& m$ m" w/ u' I3 Y4 ~# y: z2 R0 v
struct SNode{
! P% l, x6 S5 L' _: V float data; /*存放操作数或者计算结果*/0 y4 C. n! x% k& J- l5 s
char ch; /*存放运算符*/2 V M) L7 x1 S. M9 R" T O" }4 h
};" T6 `4 X9 b, D2 \/ U
R4 M. H0 P/ `2 }+ Z2 ]struct Stack{8 j5 T. Y1 p4 E! p, `# F t# O8 F
SNode *top;
: h B! {8 B: o$ O. D1 j SNode *base;
1 `9 l+ e1 n8 R5 {8 K% ?- @ int size;
$ H: Y8 I% [7 C( q- d3 T2 _! O};1 Z% [+ n; ^1 v
& L* |* ^5 a7 q' f' S/*栈操作函数*/
4 J+ u' w% z# c5 H% Aint InitStack(Stack &S); /*创建栈*/
$ N3 n8 c# Y9 y0 H c' N- yint DestroyStack(Stack &S); /*销毁栈*// Y2 r" S7 n# r
int ClearStack(Stack &S); /*清空栈*/' p, P! c; d j0 x" L5 u/ y# ]
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/: H4 _: z( e7 B% N# Q9 q' `$ o
int Push(Stack &S,SNode e); /*将结点e压入栈*/3 w% B/ I) ^5 s1 S' C4 ]
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
9 Y( Z, C) l. ~0 b5 M' w
8 Z7 ]6 Y/ r7 }+ [- X/*表达式计算器相关函数*/. n e9 v1 Y7 F6 U, G9 F8 ]- |& B: s
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
2 R1 V4 D4 _* a7 i7 g! gint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/# N) Z* `9 A+ Z) U9 v* M* u( E
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
1 }5 s2 S7 v2 M9 wfloat compute(); /*表达式结算器主函数*/
3 `+ f6 \5 X' Y, F8 l! tchar *killzero(float result); /*去掉结果后面的0*/ 9 W) @$ z& h% r/ d. v6 l! d, B
9 q3 v" c9 _' K/ pint InitStack(Stack &S)
+ O# y& W2 o8 `+ V3 `{
$ Q- H9 q- M/ T8 J/ B S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
. ] X6 W9 C( M/ x! n if(S.base==NULL) j" T$ J+ c3 a, F9 I
{
0 l: Q# T9 G9 \: H5 K2 J printf("动态分配内存失败!");
, i. M; R: ~0 S" C4 X8 A: A return -1;
1 `$ h+ F+ G% ]9 C, ^ }
! d$ B- q4 ~6 A: F$ C! ~7 b S.top=S.base;
0 s9 x2 g6 G! B7 L& Q7 k S.size=STACK_SIZE;
% i1 R8 g2 k$ G. I3 Y) q return 0; t6 F7 P) J( R; x8 G" @$ k
}
: ^5 n9 a% O- G6 n/ n3 b- @3 ~9 D
int DestroyStack(Stack &S) t1 ?6 D U0 {8 z6 {: \: Y
{" S/ s/ f/ T- ]" h
free(S.base);
i' [# R8 h+ T$ \ return 0;6 Q8 p3 G: z8 B5 ?8 b# M: w
}
" S4 o% x H8 J i
2 P( Q8 f% \# {" h+ o( oint ClearStack(Stack &S)
9 G$ d+ M$ P9 q f3 E# ^3 I{& ~; t; `6 A( G9 B% d
S.top=S.base;& o0 z4 g& G: {- W) K8 C: W
return 0;
: m. L: ~% N0 a0 k/ X& r/ s}
0 F# y5 m0 e0 x/ m3 V; _/ `: R0 s) X3 b" ^4 A& {! R M
int GetTop(Stack S,SNode &e)3 u0 T+ ?5 @" i" X a5 D
{5 K# {1 J0 f( k, U# q
if(S.top==S.base)! | W" C8 g+ X
{+ |( S8 C; n" L$ P
printf("栈以为空!");
2 L5 Z$ [' t) |7 r8 X5 X! W2 g return -1;1 a$ k) \+ i' Z8 k5 B$ D% R0 B
}$ |9 B# i( P1 t. S' R( W e
e=*(S.top-1);
e2 w, H* k7 R: e& d& u return 0;
. _( n' y2 m6 ^, }) \}+ k6 |" ]$ {2 N
8 Q- s' M! x$ N2 F
int Push(Stack &S,SNode e)
' _$ O+ m9 _, w2 E{
5 ~2 Y+ R- Y* p% o" n- c if(S.top-S.base>=S.size)6 J, m) g- R1 t+ {" ?
{4 Q& }. ]2 _2 g
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
7 D5 }5 b: h, @' e# O if(S.base==NULL)" g" J( J# a# s3 a5 b' u
{
2 q- j* g5 ~8 q, X printf("动态分配内存失败!");* y$ Q7 g/ q: S/ L) l( R# N; B# T
return -1;. [3 N' q! m7 x `
}9 l' t0 O: w( | ? @
S.top=S.base+S.size;
' F7 h! o) k9 U S.size+=APPEND_SIZE;! e0 N% X1 g% r- [. k8 b- {
}+ g* q) ]5 f3 {3 V3 U0 ^* g I. M
*S.top=e;
, M( z7 o* R6 _ S.top++;
& M9 a) n; z- p& D return 0;! _; X$ ]" D- A
}2 O- M! g$ w1 B8 T
5 Z) v# r6 D- [+ {1 y
int Pop(Stack &S,SNode &e): D: s1 G! I% ]$ h. U
{
- A! _1 Q o4 ~! B8 Y if(S.top==S.base)3 h+ l! f, M! S& }
{. O7 t0 u# [/ G$ i y8 p# O
printf("栈为空!");$ R+ P# q* O# z* e8 V4 j2 K
return -1;
4 O3 ~6 K% j+ K* ?" U) a) R" | }
6 v4 M8 G* ^, r7 b+ s e=*(S.top-1);
& Y6 z! q# t0 q% O% A& i S.top--;; s( @5 N N7 j
return 0;2 M+ j, Y, j% J6 d
}- Y: b$ ~: |% W" |; m/ v
! f, `9 ]. E7 schar get_precede(char s,char c)
3 |% Z% ]* p& S, H& b2 H l{
6 t! U1 K# N% s# C U# b5 g1 h switch(s)$ o5 w l' U% [4 C- f1 e' W2 x6 P
{
7 ?, [: {+ M+ e; k9 Q3 I: X) o case '+':
8 t: d9 `( h+ o9 o, C- D. F3 b" N case '-':
0 p3 J4 C; \* o% y; U$ @6 V if(c=='+'||c=='-')
* [* W3 z$ v' | Q. b! j8 Z return '>';
1 U$ Y3 [3 E- j. @ else if(c=='*'||c=='/')0 H* g7 N! y8 y( J
return '<';/ {3 I; K8 J! ]0 Z( s
else if(c=='(')
7 q0 J. l9 h# t! t return '<';
1 E) `. i8 T" D; ]) u: `, e else if(c==')')
1 m6 m! {2 W) X' d return '>';3 Z" P7 v* E3 Q, |/ x; e0 _
else # p' J$ j* \9 a
return '>';* y2 j/ m7 b( Y# W! w- P/ Y; l; u
case '*':
9 d5 B3 A5 X) a# u; ~, K3 b" W case '/':. n v$ F/ @+ m( K! B8 w' v' R
if(c=='+'||c=='-')! C2 b5 A: l: I( i* X
return '>';, }/ T( b" k9 L6 j# {
else if(c=='*'||c=='/')
; H* d, I6 F8 d1 [9 k5 f1 D return '>';& X( ~7 S" a l; b* H; K" r
else if(c=='(')
. ~% H4 e+ g5 q' s, O7 C return '<';
) H8 u8 M$ S. H l. s; O3 ^ else if(c==')')! m# V) h; B R' W# N* f
return '>';
& v2 }* J/ X2 @& `$ r+ A8 x else# N+ r8 C/ d& S+ w: c- U
return '>';
! G3 M% D% S! }; v( l4 b case '(':
, g% ] R! o$ t) m' ? if(c=='+'||c=='-')9 y- S7 q& O0 F- @- _" Y$ Q- c
return '<';3 }7 @' ?* H4 B6 J) ?2 W1 z W" S! Z+ P
else if(c=='*'||c=='/')/ u Z5 F+ Q0 h( V& {# ] W" E4 R
return '<';
; F( A) U" h! H else if(c=='('); `* U( H/ {; S. F" p6 _
return '<';
" Z5 D% r- e- {9 v( a" M else if(c==')'): z9 i2 A5 ?8 ?# Z; y1 t: Q
return '=';
) v& M$ ? M8 M else
0 R4 Y/ X/ B0 }- ?, R$ R% X4 r return 'E';4 Q+ k+ e* `$ e) b0 `# m' m% a! s* s
case ')':0 p$ t1 H+ [) }9 @7 r9 ~
if(c=='+'||c=='-')
( {9 a" }* Z; h8 {# W* [ return '>';
1 W2 w4 [; n7 s Q else if(c=='*'||c=='/')
! }1 ]* \. r1 `2 t+ H4 R return '>';' f* B8 o- H0 H3 T' b
else if(c=='(')/ b- E# m4 @' T1 ^9 v, }( S2 u
return 'E';( y- F; @" }+ S
else if(c==')')% @2 Y# c- M1 A. P; s& s1 J* m
return '>';
, o3 x _! t8 Q1 \: P3 k; p else
$ u8 G" q( ^; g return '>';
4 R# I) e& t) |1 O case '#':0 _$ p s+ R$ | u* s. r5 |
if(c=='+'||c=='-')! f# e/ }5 f) x+ J4 g9 X# `
return '<';, x- { _ k8 b$ G, D/ A6 U: n* `; d
else if(c=='*'||c=='/')
! E1 Q0 W& l: l return '<';: l# e1 Y8 [; @. s6 H
else if(c=='(')& B3 A) C0 f% h! F
return '<';3 o1 J6 Z+ g6 B2 a# A% m
else if(c==')')# Z# q2 s$ {' i0 o( }! i& X
return 'E';# A, k& }5 D' L, W, `& P
else
# p, p' g6 B# v2 z; l& o1 a8 S return '=';7 Z6 g4 H! y4 J
default:$ R9 k* z# Q3 H" X
break;
1 j u7 b7 x8 Q6 q4 w5 N! V }
: q4 P1 V" h( `! N0 N return 0;
3 G: ?4 n+ ^! d& Q# o2 n" _}
w3 C0 W7 w8 r' Q: a- O6 p; Z9 x* ]8 D
int isOpr(char c)
4 L( z5 a6 d& W' Z4 A{
; [& i; a1 N# K) P' j: C7 X if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
N% ?5 M. a3 q9 Q4 W6 ~: | return 0;" h6 s( Y8 e" E$ u" ]* \+ T
else & U, Z! t. f( \* G5 ~
return 1;! Q$ F* ?4 E! v' w& q0 ?
}: l% o4 \+ U9 ^" J* B3 }" m
' W. y% }6 J' n' `
float operate(float x, char opr, float y)& e2 k& z% M8 I% z2 ]
{# |, d* [7 l3 ]: b* D9 U
float result;9 q0 d/ {' F2 {" L0 |( {
switch (opr), E* {- p, p( g$ `
{1 M. A5 M! f: u3 {
case '+': % s' D; J ]( V" _) C* \
result = x + y;' u4 c' o8 B; X/ F, G: p' s
break;' o, Y" d9 ]) c6 H; w \
case '-':
) ^8 S6 v4 S% ]' K result = x - y;
* k' m+ ]. G3 O9 Z0 R break;
, G( a) Z1 s M case '*': 5 y" h- w7 t& N5 T, L3 w2 l
result = x * y;1 m8 e+ Z( K" |; e* E$ a; P. S; F
break;
( e# W% E4 Z7 o. N# G4 f case '/': 1 {. V* K7 u: q0 p! e( A7 l
if (y == 0)
h8 D( L1 @/ v7 I {
) t2 N3 U% `: ^; ^, K" f printf("Divided by zero!\n");
9 ^4 J( ~- C2 A8 [. G4 t return 0;
( w7 u) w( z) k, Y; q% M }. f: j9 O) k/ ~
else
, M) I+ L% G+ Z& t6 _- N8 B$ b$ B {6 _& O% ~0 l" H: @# W7 z
result = x / y;
( b$ G8 w+ s" X; f! B* u break;
5 q9 ^9 E5 V7 J: [7 b }
' O$ d6 [; E7 m. g2 Y& P9 H default: * H6 [5 D1 o7 o# t8 y0 I; o5 J
printf("Bad Input.\n"); 8 M) z+ K/ K8 _+ Y/ `' @' t5 g: O
return 0;) T3 ^, w$ K& [4 u$ q6 R) a
}
: a8 T/ o L, Q: [# H return result;
7 {5 v3 g+ ]: v$ l} 9 N) R+ `7 G& G' |
% b! ] X! K# I/ X8 \, D4 X5 K; z# tfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
9 g, A: R& W) s# i5 h. n" b2 s3 i{
& j4 [! j% L, N7 W1 X Stack optr,opnd;
( ? t T2 `$ U4 ?- ? struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
# c( O- Z6 w" T; q/ }' I char c;( z4 r0 q k8 D D& U7 c
char buf[16];
F+ @% o$ L9 ?8 o- V$ f5 C int i=0;
! P7 v6 h8 y* p% \+ q3 j
' y8 F0 j, w( C u0 s InitStack(optr); /*用于寄存运算符*/
1 l6 p" ]* a0 X" ?7 K; z" ~! I InitStack(opnd); /*用于寄存操作数和计算结果*/7 _, T: _# _, B# A1 _
memset(buf,0,sizeof(buf));
6 ?7 q' w6 C/ \- e, @' [ - T' M \. p0 l3 z/ ]
printf("Enter your expression:");5 E+ j3 e& m: }3 A; O! [1 p9 a# Y
( |6 }, e4 j" D, b+ Z
opr_in.ch='#';
* G, s' O& k* L; ^$ Y: f4 W Push(optr,opr_in); /*'#'入栈*/
5 u* d1 \# P6 I& h' Y: Y) D GetTop(optr,opr_top);
' D$ [! C# n) y c=getchar();- [( f6 J7 w+ k! y- V; @0 E) I
while(c!='='||opr_top.ch!='#')6 C1 b1 _- @9 I8 K4 O6 `
{
% b% F% G$ m/ t% ~! D7 r( b* K if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
/ K- N; J8 X T# _# j1 R {' b+ |: K( y6 n9 a) }3 p! m9 U
buf=c;/ C3 ^8 {* S* b8 G8 R
i++;
3 z7 |1 S% [; Q5 [: ?4 p c=getchar();2 r2 g( F: e. g# \* Z
}( |2 D' p2 Y, Z1 D$ e2 H- C7 _! }- ]5 Q2 U
else /*是运算符*/% b" y# Y: k( t6 r
{
6 V: B b7 ? q% j7 w8 ~1 R/ Q" K buf='\0';
L3 w7 R% Y: ]. u6 s# V( d if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
' \: R( [% v* Q0 O. H& A6 G8 q {& d/ e6 j6 S5 F- H5 g* S7 a
opn_in.data=(float)atof(buf);. x& {2 t; g' w9 ]$ \! n# O
Push(opnd,opn_in);7 U4 Q0 c1 Q8 k# P
printf("opnd入栈:[%f]\n",opn_in.data);
( L, X/ G/ Q( z7 }- C( Z4 f i=0;
; k# K8 m/ O: Y% [ memset(buf,0,sizeof(buf));! @4 A! @& ?8 s! b0 b5 l
}+ k- ?; `/ b; O/ E4 i4 c
opr_in.ch=c;
- l( t2 L' C: B: j9 |6 S switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/7 k* j% Q+ g; H
{/ s4 O) Q' f' D% \
case '<': /*优先级小于栈顶结点,则运算符入栈*/( x+ Y F `6 O: v5 Z+ u
Push(optr,opr_in);) U. _4 |5 G) P- c
printf("optr入栈:[%c]\n",opr_in.ch);! B/ K& T0 U9 `1 Y. ]2 s! {
c=getchar();7 P5 S H1 A9 V- a7 A! l- J. O& y+ c
break;- ~9 u6 ?1 m6 T
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
5 ]" h3 G T4 S4 F) M, i6 h Pop(optr,e);9 D0 C: J. a5 M2 i& n
printf("optr出栈:去掉括号\n");* d5 g9 t1 j1 A! z. b2 Y! n
c=getchar();
. i: u: I5 S6 @5 E9 S break;- F# G9 d& f" j+ }
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
3 J! w/ F; ]; m4 ^) v* M8 ~ Pop(optr,opr_t);: e. ~7 d5 y D" q* @! G
printf("optr出栈:[%c]\n",opr_t.ch);+ N) v0 Y9 ~% v/ l: G
if(Pop(opnd,b)<0)
4 y6 ?* W# b9 z# `' S, Z {
1 g( {' ?# g# m4 U4 }4 `) o/ a printf("Bad Input!\n");2 M& D( t+ @: i7 o' p& k2 [- s5 F
fflush(stdin);
g8 Z; f/ B" ` return -1;. M0 t) ~, D, Z% M
}: j* X) f, X& H. h
printf("opnd出栈:[%f]\n",b.data);
/ v! ]' N# ?9 G& k- L& N if(Pop(opnd,a)<0)
1 f. U6 C' h& \2 B {
% G4 i* j! G9 E J% T% K printf("Bad Input!\n");4 J3 g3 S' E7 @0 y' l3 q3 L
fflush(stdin);+ g2 ]/ E4 \6 q8 \
return -1;# e5 h, _9 O( x
}+ }0 S/ F; o# u- W
printf("opnd出栈:[%f]\n",a.data);
- Q5 I% P) u$ ^8 s+ O+ i) p1 {$ ] opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/3 |1 ~4 K, ?! F1 X2 E: i; v& T
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/; B. I! B; l( O# q# S! W( Q
printf("结果入栈:[%f]\n",opn_tmp.data);
) e. K: _4 R! W# ^3 n( N) ^ break;
4 v, [! u$ ^5 |. ]: k }
5 U! d) q1 z" n' I2 ^; O: m }. C3 j+ v2 ^2 _8 p9 P8 k0 ]
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ H' U+ T# P4 V& Q
}$ k* }4 J4 e! h2 D2 ~
GetTop(opnd,opn_tmp);
1 a% A5 ~6 \( v& d% H$ g; s: _ DestroyStack(optr);) W$ s5 i2 V Q, D- b9 O/ ~# X2 k
DestroyStack(opnd);( [& D# l! f' j- N* G( ]6 {, R
return opn_tmp.data;
- o$ ~+ L. `" m/ x$ A}* @ \5 L. }$ y5 B% X& V
' W& ?7 C v2 s" V& k P* xchar *killzero(char *res,float result)
- x% G9 `3 e/ y4 E* y{
" l1 T: Y! }4 T8 v, T int i;
7 C# B3 `; a( h( f7 f7 f! E) ?
- X/ }/ M& ^( a sprintf(res,"%f",result);
' a7 C5 v: W' S5 l/ ]5 P i=(int)strlen(res)-1;+ C: q1 u3 d# t- m- ~9 _
while(i&&res=='0')
7 v; l3 w( U5 t {! o0 ]; Q, E- S7 C# ?
res='\0';, e# k( P) ?: T- l' r
i--;
6 X% q9 |+ w9 L$ E; @ }/ w/ r3 L" P: p5 Z% U
if(res=='.')
' w2 a+ o2 V8 p8 ` res='\0';
8 E- c! _, ]+ t0 h+ \* B% a0 A return res;
5 _, s* i* A' x}$ v( l6 n. N% V K' t: o! `5 l
6 W R1 R" |$ h: y3 i0 z
int main()/ K9 h* _, s& } @0 U3 e" u
{
$ I# M5 D! J8 M# g9 j0 j9 [, p char ch;
$ ?4 i5 t( W8 g. [ char res[64];
) z; b, m1 w; q; h0 Y9 o( I4 Q4 i' w' Z float result;0 C* s& P# A* k( S" Z5 j
while(1)
4 D& {+ T9 o; K( o, a# z/ U! t% y/ G {0 v2 C7 v9 S L; W, s
result=compute();- o9 s: g% U. T+ d% Q8 T& N
printf("\nThe result is:%s\n",killzero(res,result));4 G& [3 K5 g9 l1 G: g. |- u( c, @
printf("Do you want to continue(y/n)?:") ;8 ^ q0 R; I2 e' L; {* i
ch=getch();. Y' p& K; ?# K/ F. h" r1 s& K
putchar(ch);7 e! j2 R( j$ c' r. t* d& `& |
if(ch=='n'||ch=='N')
3 [5 K9 Q" K }! u; r) |0 e break;
( x7 n7 ]5 g# D3 }7 ~! z$ j; _ else) s$ U. h: c, E" i
system("cls");5 v" y7 _+ q5 w, I7 |9 W* [1 [! R
}# ?+ F9 a; K% Q# C5 z
return 0;
+ [" R7 L' j" r4 H: E6 D}
3 D( C- r( \) ~- J
/ u4 j+ `2 q" m: ^5 @+ R, p[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|