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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的." u+ ^0 `/ w/ ?: u5 L0 v$ X; h
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
/ Y* V# G1 ]9 k9 \1 O/**************表达式计算器************/
8 i+ a& P9 f: H# d, o6 E#include <stdio.h>/ ~" V1 P+ m3 v. U$ U# Q4 a
#include <stdlib.h>4 W5 A8 J2 G/ G! i( S
#include <string.h>
* N3 n* W: @4 y# Z#include <conio.h>" O, \5 p$ {6 Q3 Y( ?. f$ `4 D
#include <malloc.h>% X& E( Z2 B# z9 I' @% r5 Y9 C
# M, K' K: } ^& e3 x% i9 y
#define STACK_SIZE 100/ S& D- d5 n7 `6 a, \# }
#define APPEND_SIZE 10
8 R1 x+ W: H2 @; D" j4 l$ s( m" Z! ?4 X; W4 I8 u
struct SNode{4 o& Z) k3 D7 |& q) J$ d
float data; /*存放操作数或者计算结果*/
. w- o$ u$ q: [ char ch; /*存放运算符*/
! y/ u8 K$ H2 \% n; k, e$ |};4 b9 m9 j# d* m# _1 L& F" C
8 U# e2 p& ~3 q$ R/ _9 Z1 xstruct Stack{! m! s5 V, Q, c6 V
SNode *top;" {$ \' Z5 u, `/ N6 f5 a0 F
SNode *base;
0 L4 t/ O3 |* ], @3 f: Y int size;
# W8 ]2 i3 _& N};$ @; D6 d( `3 S. X0 {; a
) c- \: W* y2 L w& |& @3 a7 B. L' y
/*栈操作函数*/
\9 c# X$ T6 X. m. ~int InitStack(Stack &S); /*创建栈*/0 J5 N$ T5 @/ u% \$ ~" B4 r8 E! X
int DestroyStack(Stack &S); /*销毁栈*/
9 n4 p* c/ S+ p4 I- o% t, [int ClearStack(Stack &S); /*清空栈*/( _1 D! k' H. f( u
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
- E9 H/ a7 ?1 bint Push(Stack &S,SNode e); /*将结点e压入栈*/# b2 V- ?7 u, I8 L
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
6 \! d' R0 g9 N7 S u
, q, ]' z% K1 E( ~2 [/*表达式计算器相关函数*/& K/ H9 @5 o7 c- m
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
- q. c) z1 o+ [6 Aint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/3 k5 Z; g9 C5 T9 J$ \2 D# q4 w' O
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
* C7 E: X& w" o Q2 O4 lfloat compute(); /*表达式结算器主函数*/; y" A) L3 r/ m# I. d B5 D
char *killzero(float result); /*去掉结果后面的0*/
1 {! u- V# l; P
8 Y# V( }* I0 D0 A% \int InitStack(Stack &S)$ P. h9 E! H L" N0 D1 H
{; M$ t! L4 Q: O" S
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
' u) i+ O- [9 U+ x/ Y0 y if(S.base==NULL)
* ~: j& }3 S" ~; a- [/ k {
# r' _! P+ O2 E* |$ e M9 Y' w; A printf("动态分配内存失败!");3 a8 [- p" U- e5 k4 v* [0 k! w
return -1;
, S* i1 G! X4 B" B# \; D* i }. h; z; }4 p! ]7 Y8 r
S.top=S.base;
! N0 C" r4 }( f; J1 a/ X2 _ S.size=STACK_SIZE;
8 i6 R5 O( h+ X+ l/ I% [' H return 0;8 d! @# V2 y f6 P6 A |
}
% g) g2 [# O7 R9 Z
4 T+ q' t/ K, X4 d8 u8 p' Bint DestroyStack(Stack &S)! c5 W- @% ^! Q3 D6 |8 X- _9 ~7 x0 V
{- i5 `' i1 t4 J p0 E7 u
free(S.base);
0 X+ Y# z% j, d4 V7 H" m return 0;
6 }9 N1 x. l: [' c/ i}
- r/ z% [( p, |, ]& a
' ?6 u7 i) _+ rint ClearStack(Stack &S)) r, B \6 F5 I7 Y O; |6 Y2 W
{" a5 h. E0 z! q" Y& _+ X+ @
S.top=S.base;' y3 J( q# q6 h: g$ u5 |/ f
return 0;- m/ ? g6 ?) S4 [, a
}
" S, Q3 ]: ^* d2 g( @, m' H$ u5 X: i$ k }4 ^3 A$ {+ I$ b4 J
int GetTop(Stack S,SNode &e)
! b$ P4 K6 a- y7 o' Z/ t6 m- M! d{
1 B- e: J% |! J4 b$ s if(S.top==S.base)
. {- V& O* _" o" S6 Z {% S3 I1 e9 w- U0 D
printf("栈以为空!");7 T) Y8 \: Y* K. D( ?. t5 l) N
return -1;
' C9 w7 J; x1 ^2 Z I3 R# X }
' G# I9 u+ k! J: _; g5 g e=*(S.top-1);$ J& X o+ Z N8 l, L+ \, W
return 0;
4 c" k2 i6 T/ S' |& C- ? C}, |3 N9 k, r1 P4 R+ ~) G
# u& A/ P9 } K$ s$ T) ]% z2 _
int Push(Stack &S,SNode e)
+ @& \4 p5 l! s1 o, e{
& M) f# H: b- @" r if(S.top-S.base>=S.size)* X* H& U5 F4 m
{2 \. y4 S6 ?# A
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
* u+ u$ ~$ ^! X: q; P5 {1 P" v/ e) A if(S.base==NULL)+ @& m1 h3 o, ?: a" q, Z- s; g3 z
{/ S3 v% o8 |, j# c/ I+ X$ f1 g
printf("动态分配内存失败!");. t' o/ u8 @# |! ^
return -1;
8 X- ~+ R5 \# @4 H3 ~ x t+ {8 U }. ]% M! P2 N. y; ]
S.top=S.base+S.size;
% ]/ L) |9 g5 D4 Z' M S.size+=APPEND_SIZE;
5 f! [2 }: D" T0 S9 s- w- U; s8 z }
" H0 h' J' d; w# w) n0 r *S.top=e;+ z. e8 ]3 z& r' ^- e8 a
S.top++;' F* N) ?4 N2 B& y
return 0;
5 P; j( ~4 {! { b, B}
9 y5 K" |: j3 `6 X* Z& c0 E) ]7 D; J! d* Y6 j8 N
int Pop(Stack &S,SNode &e)
) Y* U$ c3 I. y, x5 w{
& n2 P7 v$ G7 l! c8 u. t# S) H if(S.top==S.base)
0 A8 T0 M1 C3 M7 s$ m {; `6 p1 r% K; A0 X$ r
printf("栈为空!");! u, V. ?3 b( k3 i3 S* v, K6 B
return -1;; {+ w% m) g) [' w5 n
}5 t# w2 w- y( ]
e=*(S.top-1);
; ~* l% N5 I" g ]* a* e' {7 a& ]. A3 f S.top--; @! m* u' I. e. H* u5 A+ A% t+ L
return 0;5 z$ C3 X9 @1 }, Y5 m
}1 [6 d3 b8 m; H8 S
& K# B. t5 q$ Dchar get_precede(char s,char c)0 a- o% { H* b
{
A1 Z3 m1 n; A+ j' H5 q' C switch(s)" U3 r0 {1 m( z2 c- i' ~+ }# N
{
x# g( P6 f$ ]: J0 K case '+':
* O! C. c) u* | `1 X case '-':. ] O1 ?; I- Z" @ y( Y
if(c=='+'||c=='-')
; S- @ V( W$ l) t return '>';( T2 [9 O: h8 I) e8 K. [
else if(c=='*'||c=='/')) x: _7 \5 v7 V
return '<';
$ k) j6 B5 z3 N8 q& V/ C else if(c=='(')- a) o0 {, T1 p+ \6 G
return '<';
, m$ _$ Z3 `9 E8 u else if(c==')')9 y- U" Y. [2 k, a6 m( x3 q( p
return '>';
~0 L% |' n4 A3 g else
& C1 s+ Y* f* G1 f8 n return '>';; b" z8 p! a# F; L+ X! s
case '*':
3 q. O6 O# Q V3 x case '/':
+ c7 b; W- j7 z" i: g if(c=='+'||c=='-')
. W' t& b e, ^2 e return '>';
7 B7 [& Q! U# e L else if(c=='*'||c=='/')7 |5 \3 [9 Y5 q9 Y6 X9 |1 w k1 m
return '>';. o1 e/ l2 v! v) }) G
else if(c=='(')
- l8 a- `) M c* ]7 b return '<';; ^5 a% b8 {2 b) m: m' p# @
else if(c==')')
+ b/ d4 L- j: U" _. K return '>';
+ m6 U; f& s' x$ j else
' D5 h* o9 s: {( [( T4 i4 U6 H( @ return '>';
, m% E( c* ~* } w/ q case '(':
( Q/ G! F* c9 [7 m( [5 U+ g& t if(c=='+'||c=='-')
5 F! E9 i- e) ^& g) s! k return '<';
& e; a. V/ T9 {$ V |& t' m8 z else if(c=='*'||c=='/')1 B6 C9 A4 s7 T, D1 [
return '<';4 W( _0 f6 n2 X1 T4 f* L4 H. L
else if(c=='(')9 p8 F$ [1 z- G8 B
return '<';4 _7 ]$ @! }; e" R! `6 `' y
else if(c==')'); G7 ?/ s6 ?( R+ e: Q9 e I, a
return '=';
3 M& s) S- K, }0 I- v, o1 C else
: f: ^7 O7 o0 s* B) q9 H0 M return 'E';
( T& O1 R6 y* {! C3 b: ^ case ')':
! m3 n. F: r# N if(c=='+'||c=='-')6 q& l$ p9 p& P- S: }- m8 N
return '>';8 j2 f3 p4 y0 ~" F5 r0 a
else if(c=='*'||c=='/')
2 ]4 ]* D6 J! W$ ?5 T1 n2 H) x return '>';1 @2 f+ n- u( t/ j
else if(c=='(')7 k2 e9 l1 q4 o" _7 X
return 'E';% F% v5 v; ~: `, P8 E V C9 ?
else if(c==')')8 p1 V/ ] Z% m/ g2 q
return '>';
4 R3 m# w @( [! D6 y else% b, K; Z; {8 o
return '>';+ ~) B. @; K* y( S4 V1 E) y1 ?3 t
case '#':
- p" i+ G( G; f7 E7 m if(c=='+'||c=='-')
0 z K7 v+ y$ ^. \% A( F! r6 g4 k return '<';0 s/ F% b! w1 q9 _+ L% _
else if(c=='*'||c=='/')
8 a. l$ P8 q/ r# Y }/ B) a return '<';0 Y/ ]* x `, \& l% C" f8 }) u
else if(c=='(')5 e) P' r: j) z) b3 [. W0 N
return '<';) W# o- z" Q$ u" h- E! D- W6 @. \! {
else if(c==')')
! e4 K$ o2 V1 U return 'E';
* X7 w0 k( M, s/ O else& l; Y6 A; u. T% G9 |
return '=';. T/ ^$ d/ y* \; n" b/ E
default:
, g2 | L. j+ g" ^7 X7 Y4 i break;
/ e! R' V; r7 \3 s$ c# f }
1 n& S- ]9 \: c) w" m return 0;
& v4 O( |/ J/ s2 K2 ] ^}
! b# A/ \! `9 e9 f
% e7 B9 D6 P8 lint isOpr(char c)
1 X. \0 o4 `+ z! U6 `5 p( a{. I7 h S* D3 m
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
, W% i" B" }; D! W8 d1 ] return 0;
3 H N% k, M$ M1 q5 T$ ` else
) c+ |/ _+ m+ M return 1;6 f( y6 F" j8 l9 [' P
}
, A2 ^7 @& r4 G9 d
% C( Z$ ^0 y/ ~$ Pfloat operate(float x, char opr, float y)" L+ K+ N) c0 v
{( n& x2 Y# O4 N! d! J
float result;
8 Z n; W# @2 w, p5 j7 C; Y switch (opr)
3 H. C9 z! i! s( V/ S {
4 u" v* q) r+ G$ E% v case '+': / |8 G2 ?" l/ w$ C8 G4 L! _" B* r
result = x + y;: J* i6 G5 q% m# y' a% g L- D
break;6 p0 Q% @1 f& R) w5 e* ?' S/ J" k
case '-': $ [: \1 n; R/ M& J% m! [4 t
result = x - y;
& S# u! B/ d0 j9 q# q: m break;
( p: [4 P- W# Q# M8 W" S case '*':
/ y5 [- \- K. ^; d result = x * y;
7 F$ H7 Q0 W! k2 H+ G break;
9 ~; g. w% A+ B2 J i6 `, V case '/': + Y" }7 \6 B/ f6 u
if (y == 0): e" H) w6 j T! c( F5 C
{. g6 _+ F' a+ l' F* r
printf("Divided by zero!\n");
8 m. K; ^: a, Q6 Y6 v* Q4 K( B return 0;3 r2 f+ e7 C7 M: \, `% E
}
' r; C; K/ @' @ else
# y* i; o3 z) E$ H% @: g8 d8 {% v {4 j8 u0 y1 ^( O& ~( \$ x
result = x / y;4 q" R+ ?3 t+ M& e/ H+ Y
break;
9 T P4 @7 w, f# l" h$ r9 [, b }- {# T* Q, X& n1 J8 }) F% m& ]
default: 7 b- y4 D% R9 r* B; j$ O, p# q
printf("Bad Input.\n");
# c) s% r! T6 \' G9 A; Y return 0;0 z& {* P% s5 g
}3 q+ H! s& w M& ^% I8 `6 ?
return result;8 ]% S$ n/ b( u1 G1 H
} 2 E! u, m2 Z2 V
) ?4 i4 _* a9 e1 a1 z. {
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
( a# J8 L, z1 i$ s2 C{
! m* E1 D% C% P/ M" c5 A) Z+ | Stack optr,opnd;. _! j$ y5 h* o2 \ c. C0 d/ W. U9 [9 Z
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
% Z8 Z5 o5 \) p4 s* m$ u char c;
& D$ c, o' z. A/ P) U char buf[16];
" \2 ?, o8 L0 l4 { int i=0;
# [! w; p4 z( a8 s" B* r4 O8 |
6 Q b d/ i+ y- z4 P3 P8 I" O- c) Q InitStack(optr); /*用于寄存运算符*/
* N+ h/ D) L( E; Q/ z InitStack(opnd); /*用于寄存操作数和计算结果*/
" a3 Q0 R8 f( L, b$ x5 c8 M' @ memset(buf,0,sizeof(buf));; |/ R6 s! L7 m/ `
. s' m7 c8 m3 t# F1 y' g* @( \
printf("Enter your expression:");* M, F) c/ P. x2 H
) v5 m. U3 e i opr_in.ch='#';
! z n) t/ f+ z, ~* c Push(optr,opr_in); /*'#'入栈*/
?& v. ?+ h" g# E3 a' t! R8 ^' u GetTop(optr,opr_top);8 C# C) f' J5 L4 c
c=getchar();
! g/ f9 y1 ?) P" p$ g, f- s: j while(c!='='||opr_top.ch!='#')2 m9 F6 c; d5 d( H5 p7 ?! I
{
/ |, \5 l8 j' f. y& e) Q if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
; R0 O+ p2 s$ m {
/ Z/ T- O( s$ r- t5 \9 x buf=c;9 z2 E2 I% t4 D2 C8 g
i++;
9 y5 G$ s. A% x c=getchar();
3 H4 _( _. l3 y* A i }
6 v3 W2 C$ A$ i$ C) A5 p2 j- v else /*是运算符*/ R$ a* Y* c* d- n8 A% u
{7 C/ q( v) n6 p* v+ y
buf='\0';4 [( U# p9 A2 k
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/) T3 `8 K# h3 Q
{
5 A# v ?% r4 K8 Y: y opn_in.data=(float)atof(buf);! c1 }+ C L3 R' Y! c h" Z
Push(opnd,opn_in);
+ L6 O& s; z- E printf("opnd入栈:[%f]\n",opn_in.data);
+ X% v' {7 L2 M1 Y* Q- ] i=0;
8 G& Z( j$ L9 \2 R/ A0 v+ d memset(buf,0,sizeof(buf));
4 s7 v9 L5 n) U' y: }' w: v5 K }
1 k+ z3 m* A" _5 g: m( _$ k opr_in.ch=c;
5 ^6 u% Z/ n1 z2 ]% E% h- A! ^ switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
3 V3 K. e0 X2 ^0 R7 O {5 M( o* D4 p5 K7 P# B! ^+ ]
case '<': /*优先级小于栈顶结点,则运算符入栈*/
1 S' ?2 ^. E- ]% b Push(optr,opr_in);9 r0 L& D! c5 {6 \5 O( X
printf("optr入栈:[%c]\n",opr_in.ch);
* ]9 X* i% r% A2 p c=getchar();
: j, S# ~/ z. k break;; C! ^) C; v8 J. V. T- E+ _* O
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/3 S+ ~1 [& w* _7 c
Pop(optr,e);
& s1 S6 r" c; F* }* ?' S# H# {2 n printf("optr出栈:去掉括号\n");
) B0 W, P R% Y( | o c=getchar();6 Z4 D l) g0 x5 M3 g, a
break;5 m& D) @9 T0 h
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/8 {, i5 W* T3 G$ a! Z
Pop(optr,opr_t);
. a* \. `# F. W2 m: X printf("optr出栈:[%c]\n",opr_t.ch);
/ J2 `6 I5 k. ^ if(Pop(opnd,b)<0)6 \: b& d& k# P) X( }1 k
{
9 A0 a5 N2 e* z' p6 ^; O2 C printf("Bad Input!\n");
! K4 C) Y0 K4 D2 z1 }0 L9 H% U fflush(stdin);9 d7 k& l# F" w
return -1;
$ c' A$ Z* k! S9 Q0 J7 O2 u }, |' h0 q0 f- O! C" u8 [( `" K
printf("opnd出栈:[%f]\n",b.data);
* B3 s3 M8 G5 q6 s0 b4 [. y* G if(Pop(opnd,a)<0)0 a" {0 G* m9 l& G
{
, N4 L# m6 j" C6 w7 y. L printf("Bad Input!\n");$ D, K& G" [5 R1 y" p1 Z
fflush(stdin);8 a3 q: w. @3 e) p/ m
return -1;
" k1 h" e# E" \6 a& w }5 h! y! t+ j+ p
printf("opnd出栈:[%f]\n",a.data);
+ ^6 U y) \' F* e" l* O5 q+ E: K opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
" z1 _5 {1 q& Y+ N, d Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
" M' Q" `1 w. v; M: `* q printf("结果入栈:[%f]\n",opn_tmp.data);3 P. g: g, e) `8 f
break;
! A: q$ m6 I5 C }1 q j( I$ ~2 `
}2 l7 c, ~$ ?5 ]8 Z) J4 g9 i( } r
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 3 W# R% c2 T( x. r# e, K
}0 g1 e! N" @8 v3 s3 y& k
GetTop(opnd,opn_tmp);
V4 w+ O; f$ g; q/ }3 E DestroyStack(optr);% {! x$ t, x& Q5 h' \
DestroyStack(opnd);8 y" Q% h; \7 u% L" o% V0 h
return opn_tmp.data;# [, G* t, i! l' o4 v
}
# w" j7 l8 [" n A7 _. e/ n
) e. a7 A9 a' Z% t k" I6 kchar *killzero(char *res,float result)
# a6 ^8 O+ {7 M) f+ E! p3 Z{; ]8 i* j0 A2 F% B5 T9 x/ K
int i;
* F) a; B2 x& c
9 L+ |9 B7 l4 K7 F0 {; p sprintf(res,"%f",result);/ P. j- t$ F4 |5 t' ` a! U
i=(int)strlen(res)-1;; F/ V* ^0 n- D) L; T3 W% F5 B
while(i&&res=='0')
/ G, O |7 p& w' H$ k* S0 b7 i# ~ {/ W& F2 @6 l: I7 p
res='\0';
& M' C% @1 S; I: Z% Y9 n# W- j i--;
4 \& J4 R& p7 P }+ e, V' `. o, K6 u; M8 {
if(res=='.')8 U, Q! f' h& q' A) F# W0 P
res='\0';
% l% u+ V& T, V) M2 F, |$ q return res;
* |2 j% k5 p' s6 i, k}
2 y* g, F8 w- h3 A; L9 w, T5 F/ r8 |! T/ S
int main()* c, n3 r4 T0 v, ^: Y; N
{: R) Z& M+ P( |, `
char ch;. V8 b. g2 P0 j+ e
char res[64];) D. ]( g1 A* D) w( d- u& j
float result;
& X: t4 ~/ x7 L) Z# U while(1)2 p4 k* I: ^0 f$ a) `
{+ s( n3 p6 k1 p2 q7 D- k! `4 k
result=compute();: e/ m1 @4 L$ M, |" e
printf("\nThe result is:%s\n",killzero(res,result));
, h: n& r, _; x! t$ ?& Z( i2 d' A5 } printf("Do you want to continue(y/n)?:") ;
# ?) W& N* R: ` \7 l& } ch=getch();- X: n, f$ k+ v. J& K4 j
putchar(ch);' J3 A* n4 T7 u! H
if(ch=='n'||ch=='N')
# E `$ T! l' Q* x# ? break;
) r0 }' Y9 N) U else
6 U7 g+ o5 e2 Y, W- ?5 Z* b2 p# n0 s system("cls");
$ S4 c* v) u7 t }% x5 A! ` A0 o, O
return 0;
) n+ d$ A- }) P3 p}
& o( c) f3 @: o0 C+ H- @, S5 N5 z I. \5 b/ }/ r
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|