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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
- P9 p8 T A9 e" F: m程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=6 G/ k( ^# w( e2 f/ I
/**************表达式计算器************/9 I( h, ^" H% L c6 W: U
#include <stdio.h>
# @3 k Z' |% [2 j& A) q' d" \#include <stdlib.h>) \& X9 H4 n8 [2 L o! r
#include <string.h>
+ d1 N5 O1 l! j# T0 t#include <conio.h>9 D# y/ p0 T/ a7 i' b. L1 G, r! x; }
#include <malloc.h>1 g4 s* t+ p2 Z4 u9 ]
5 A$ u, }' U; a# Q5 }3 J
#define STACK_SIZE 100: Y4 ~2 m; j$ @ l! W, U+ x
#define APPEND_SIZE 10
3 L: {9 e1 A7 G8 ?" T: `# ?# P
1 e6 Z v4 c; Q: Hstruct SNode{6 c' R% X9 l8 e2 O
float data; /*存放操作数或者计算结果*/
4 x5 d) x) q5 u# f3 `7 o char ch; /*存放运算符*/
5 x5 T! `3 o% g: @+ U6 o( b};7 H% G/ i. C2 y( ?
* j. Z( W ^$ q" T. v% u
struct Stack{. H; N* V& p* p% z$ `/ ~' l2 D* u4 ~
SNode *top;% }# k ]" U. b' N; [5 p! q4 [
SNode *base;
; v) o. B" n0 O6 u& u+ ?* L' Q int size;8 d. ^8 n7 M J* J; {' T1 a% @. [
};- B! `3 q4 ?: n( ?5 y" W
! c9 a7 H1 F0 z0 n) J& M/*栈操作函数*/
: o4 b w+ D5 t8 p' H- [3 _int InitStack(Stack &S); /*创建栈*/
% r/ j; L) n, N2 Xint DestroyStack(Stack &S); /*销毁栈*/
z4 U9 c! Z0 b) D8 iint ClearStack(Stack &S); /*清空栈*/
4 I) h" K) ]! P/ Kint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/( f7 w' f# s! t1 O& H( D( R
int Push(Stack &S,SNode e); /*将结点e压入栈*/' V9 C- x) s0 h6 Y% q' N
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
4 B/ e2 ^3 R7 w) K' i5 h0 q( x& s
" |$ Q, d+ M2 g K) e" N) c/*表达式计算器相关函数*/
& k! B, @3 I9 {2 I( @( `char get_precede(char s,char c); /*判断运算符s和c的优先级*/
6 y k1 ?5 W+ u" Z) N) lint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/' ?3 k/ d2 m! r4 a t- r$ k
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/4 }0 d0 |- B% K# C& S2 \& \1 p* x2 ]
float compute(); /*表达式结算器主函数*/6 X: |( A- N/ W8 X: X
char *killzero(float result); /*去掉结果后面的0*/ 8 p) \+ r8 r5 D3 X: S7 A
9 }& @: W' q1 |3 z% ~$ _$ i8 l3 ?& xint InitStack(Stack &S). Y: o2 J) A( X; j# Q
{
7 w) \2 j1 }# s' t S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));# Y! {0 D! d0 D' H
if(S.base==NULL), i/ [. Y4 m4 R7 N5 h
{4 x C( Q2 ~/ l4 I, J' O
printf("动态分配内存失败!");2 ^0 t; B: Q, B. t
return -1;
; Z. v$ x( J9 s: F( z/ d- w( l }
! Q2 A- I. v$ i0 v9 p" R S.top=S.base;$ {/ N6 D# W9 D
S.size=STACK_SIZE;
$ y* V# i3 u. S% [ return 0;
* [9 K7 c; I' g% u* F: K}
3 ?! g1 o( R0 [! g7 U! r( Q2 \# U+ w* w
int DestroyStack(Stack &S)
! z( A& F- h6 C4 u: h{
' Y& @3 z, b7 E1 e: a free(S.base);
9 A! q% t7 B X; O1 ]7 P return 0;8 V- c5 V( O% O4 o- N" _1 Z
}
. S+ H" L7 E- |: M" f, I p, r1 e2 z Z) B
int ClearStack(Stack &S)
* T! |# A7 L7 y L. _+ E+ G3 ?{0 F9 x* T* S* j, q& z" K# x5 G; h
S.top=S.base;8 j. X# n1 ]/ U& e0 I1 X2 T
return 0;
1 t( E# q# i, D. |}' _6 M3 D2 F+ }
3 e2 o4 J6 X0 y# U9 j) o9 F7 m/ @int GetTop(Stack S,SNode &e). g h0 A. ]6 e$ ?6 U7 }0 d
{6 ^( E' D' E" e
if(S.top==S.base)6 |. O* j3 ~8 q. \! Z* t! I
{! L$ U0 a( P ~- f$ Z
printf("栈以为空!");
1 }4 }: _4 x7 Y7 E0 z( L return -1;
8 {0 X4 N5 B5 ] z' j9 x0 Q: R }6 u$ Z! M5 ?+ b) [+ ?' y, u
e=*(S.top-1);6 x' }; ]3 B0 W" d- r) }* e
return 0;0 }; x- _7 T, ~2 d) m
}
4 S: d4 o3 O/ t5 Y
; v0 F f; v6 |4 r# v2 w3 V9 A: a5 vint Push(Stack &S,SNode e). V% f) r: N$ A
{
+ ]( H M. b5 g+ t if(S.top-S.base>=S.size)
# p( [3 m0 u- `. t {
, F* N% E, A/ V! B8 n* ] S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
' H1 q. Q/ J8 r" d5 i0 l q' E& k if(S.base==NULL)( |% J# E6 [0 Q5 J. c# d* r* t
{
) E ~* L% |# g9 W- s printf("动态分配内存失败!");; i; g4 ^: U- [& E
return -1;
# ]. \3 ?0 ?; l! y$ W! C b& Y4 l }
* a6 }" l' i9 F, q; G* H! ~ S.top=S.base+S.size;
/ n1 [, L5 p6 K3 J3 { P0 ^. z2 x S.size+=APPEND_SIZE;7 ~1 @$ E& g" ^1 c! T
}( S" d# t% D0 N$ s
*S.top=e;/ ~. ?* I7 O! w# s4 g
S.top++;
- t7 u: f3 c8 {, U* [2 ?; |6 x return 0;, u% W* B) ]1 Q" l
}
' e" c3 n0 e7 F1 \
9 `! C+ F, m8 o1 J" S% h3 Hint Pop(Stack &S,SNode &e)9 u& J8 j% ]6 m) L- D# N
{+ e) |3 q: o8 t* ~" \
if(S.top==S.base)4 ?, x. S* K* ?: A" S+ C
{
, Q% B' y& X* s! {/ E: C* F% s printf("栈为空!");3 W9 O; B" ]. C0 N! v5 n# p- g3 A! x
return -1;
+ z/ ^' U2 a$ q& s! @ }! ?; x& m4 e" p) s' b* e% r/ d
e=*(S.top-1);
5 k7 f' w) E+ T1 g: @" E S.top--;; b) O# Z1 L5 }) ]' B9 T& |" N* D
return 0;
8 Z9 v# M9 I7 K) t) H, d" J4 s}
* M+ [* L* w5 a" g9 t
- e2 U4 t' g, I& Y* ]& Hchar get_precede(char s,char c)
: U0 K! H2 c3 o5 m5 v7 C( |{
3 z1 D: a' P9 X( Y switch(s)6 s s" `4 q; @9 T$ z* H& h
{. ?) K/ X# v' U0 [& P. S
case '+': 7 h9 J" n. x& f" E0 A
case '-':! h+ U+ v' {8 E/ \% }
if(c=='+'||c=='-')" f/ {' W: q7 u1 Z" R$ k( n1 J$ _* l
return '>';+ s' j6 M3 y$ v
else if(c=='*'||c=='/')6 a- P9 `1 E' d9 H" g: [4 {
return '<';7 s$ t5 }5 s; q) w k: p$ I
else if(c=='(') O( b/ D; M% b7 U
return '<';
0 K+ w$ X6 |; s: o+ m( Q) x1 H else if(c==')')
7 L/ | ^4 I1 w' K( o0 X: S return '>';8 j) X! U. n, g) Y8 [
else
7 W, c) ^ o" n0 Q: M, m6 L6 O return '>';- p% K1 Z" d# I) S
case '*':
/ c- [9 Y! i7 |' `) \& `! O3 p case '/':6 `4 N( B5 J0 p- t) k! q
if(c=='+'||c=='-')* |. r' A( u2 o' [
return '>';1 g0 [5 z9 O* Q9 ?% Y
else if(c=='*'||c=='/')4 R* \, t4 P! Z7 e( w$ R
return '>';9 V' q' e4 Z4 g X
else if(c=='(')% x& t& |% v3 B) D
return '<';6 C3 W) b/ U4 O8 e
else if(c==')')3 E/ j( j8 A; i0 ^9 q* ?
return '>';
! i' u3 K* O! W1 ~5 ?* N" h else
2 U& I; h) q. D6 t- I) O) O5 ` return '>';
1 g# I, l9 L6 g. V case '(':$ d! {: J4 J2 g& c% e# z- ~
if(c=='+'||c=='-')
. i+ \5 [! U8 A2 F/ J return '<';6 `) R9 g& w. K3 P) r1 N8 P y
else if(c=='*'||c=='/')
. ?, b8 ^2 D6 p: ~, q! F. w3 R/ k6 ` return '<';* ^8 z5 p' s: s
else if(c=='(')$ L3 B) F' j9 ~% T6 d- z
return '<';
2 ?2 [6 ?$ F8 M( T, L D# R else if(c==')')
5 J6 d9 L/ L# ] return '=';3 E" T" ~7 B# R4 s# [% P
else. l- ^' v o# V( K1 e$ D* N7 Y/ j4 T
return 'E';
- s9 a) |5 ?1 l- O8 h case ')':
$ x" Z, I- Z- T) ] if(c=='+'||c=='-')
' d3 H+ C" a' I; h, k$ c return '>';
& c. x" Z5 \3 z$ M; ]5 B" l else if(c=='*'||c=='/'): Y- v8 _% K9 V2 Z! H# K4 g
return '>';
- R/ i l, |9 a else if(c=='(') n2 w& B5 Q' z# A& f2 }* a$ d- M5 C
return 'E';
0 F6 S0 ?9 J4 ~ r. }2 {& G else if(c==')')" s, {2 H+ b$ P: Z
return '>';
$ s q W {2 i, F$ n$ i8 g else
9 @+ C a0 c3 G1 G" I s% M1 w return '>';
K9 B Z" x' A- {* y4 s case '#':( o, Y+ M4 A v5 m+ I' b
if(c=='+'||c=='-')
- u$ }) a8 |2 q; Z- d return '<';
( O( o. l2 t3 z, B" H' |+ m9 B- g else if(c=='*'||c=='/')
) B+ }. j5 g, r' Q- I$ T return '<';( g( j) ~3 b6 J0 O/ M
else if(c=='(')! n k5 n7 t4 [
return '<';
+ X0 J" ~7 z3 x6 X1 J3 M. A8 i else if(c==')')
|& m, ^! A1 N5 Y7 z, a- ` return 'E';
* z2 A4 ^; O" d5 e1 W9 m else8 Y1 {$ h" C3 R4 O. d' S0 _
return '=';
8 n- O, W/ V- ?3 U0 U default:' B) B8 Q: [8 B# S) m4 `/ X
break;
8 W) a l, d' E; v; R/ E; E# u }
3 s( j, y, v2 v; q return 0; , e" U) L0 I+ r
}8 ^# u+ S' o4 _% r% I. c
2 r$ g7 }, h1 h" p" |; B( M
int isOpr(char c); I5 W q$ K7 W- o( z
{
+ S7 H8 l. q+ B# c- x4 O: X% { if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')2 z4 ]; c3 a$ \" J9 U8 n3 e
return 0;
5 T9 d8 c7 X7 N7 |$ l5 p+ j* S# } else
7 [: n) w" j# \, y7 Q1 X return 1;
8 M) r \( \/ `( r6 B. F}, `# J7 b7 M* _( ?' s$ k! D/ }
: O" Z' T4 V$ c6 x, ]float operate(float x, char opr, float y)
$ ]& }/ f" b" |. f5 \( T{8 n- g- C! C# @ g# j
float result;1 f5 U9 B5 k3 t4 H' ~* N$ ^
switch (opr)7 Y7 a% c; |, p8 H* ^+ N; P
{( j0 z- O5 n# H4 @4 Y3 f
case '+':
6 k) M) Y: U4 b# R$ p# [- k result = x + y;
. E, n1 I* L' n# G; _" Z break;1 X" ^ S# g2 _2 o, g; u' {
case '-':
9 o2 |9 ]8 z7 m% t result = x - y;& b; C! G( q7 ]7 r" L. c
break;
6 c+ ?( x/ b7 A7 y5 r case '*':
$ D9 O5 M/ f! z" ^+ D: i4 Z result = x * y;
2 E- p: A3 i" Q" D( K( X break;8 H: p, n; w% }$ R3 R
case '/':
' y- ^4 G6 l) V if (y == 0)
% B7 b2 f0 R& h$ h/ x {
. P5 @ O' d- F$ u0 B; ]3 | printf("Divided by zero!\n");
/ P3 L; Q$ k2 v return 0;9 g5 |& I- i7 d6 q+ t$ g( {# _
}
" A& Q, F8 l, H# g# E& q9 l else- R& I# h$ [# i( X" Y' |: M
{5 w K5 d3 _( v" T
result = x / y;+ @7 o% B# ]4 H% e1 ?7 I
break;
& t0 n7 D$ c& N4 Y* [" |4 k- h }
; n+ P9 W/ k) G; d2 n1 ?+ L default: # w# k5 n& Y* q: B) U4 y0 r h
printf("Bad Input.\n"); $ D9 R7 U0 \! A$ i
return 0;) u1 ~. G! Z6 J ]' X6 v- b
}
/ J- g, H5 |3 o1 p return result;
" `& m6 O4 D$ P8 p}
1 z! {3 _6 F! E4 L; x
D4 ~- r+ s1 }: gfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/2 I. B6 ?2 h7 _" h" e6 z6 B5 B
{
3 Q. Q& X- X4 L A Stack optr,opnd;3 }3 U, v" z. N5 N
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;- X2 E0 Q6 E- Y ]: \
char c;
8 s0 A5 D: \! L: ] char buf[16];
. |, E* M$ s7 t: P0 M int i=0;
% ?/ m2 y/ c) ?4 f3 W
8 R$ |+ {2 N: ^0 Q9 e InitStack(optr); /*用于寄存运算符*/& |0 r9 F& M7 F% q9 p8 e H s
InitStack(opnd); /*用于寄存操作数和计算结果*/
0 B$ g4 Q j* F# F/ m memset(buf,0,sizeof(buf));* ?& N' \3 a7 w
/ f$ U+ F* S8 R8 ]6 y printf("Enter your expression:");
7 q% d# b& Q9 B. G6 O* d
/ j5 o: W: C2 z' @, J; b7 u opr_in.ch='#';
3 ?6 D" f v) y; X Push(optr,opr_in); /*'#'入栈*/6 x+ p( R* a# [
GetTop(optr,opr_top);( l) A0 t6 s. l( Z; h [0 t# h
c=getchar();0 W+ j+ _% @1 \. z) R( M8 b
while(c!='='||opr_top.ch!='#')
9 e8 m5 r7 S4 }0 P2 I8 c; i# R {. B* |& s9 v& f
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
/ E$ d" b+ I( A {- d8 N2 I5 ^- |: [' v& T/ q1 H
buf=c;+ C5 r+ s: C) {) z3 H8 k$ w
i++;
% g: B# V/ D& a! W# `) q5 b( A c=getchar();0 B; T- g5 [2 B8 G2 ?0 J+ z, {0 _
}
" [2 N# b- T( e+ s+ A, U6 f else /*是运算符*/& t8 k; i& K6 I
{/ e/ L) {2 @, l
buf='\0';
( Q4 E$ _0 j0 V0 l if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/+ r1 H. ^ a, q0 o- b" }
{
0 f) u4 Z. g6 V% Y# Y opn_in.data=(float)atof(buf);$ a) k% B7 o8 o. X) B
Push(opnd,opn_in);" p& B. b+ x A7 ]
printf("opnd入栈:[%f]\n",opn_in.data);; D& ] L' r; J& ^9 `
i=0;. B; Y. I* }/ P- b% u' C7 Y, q9 b; c1 y
memset(buf,0,sizeof(buf));) C1 v4 [2 X: C% v
} @3 b& Z ^- s9 Z9 |
opr_in.ch=c;
0 J: @( x7 h$ s I6 n2 h* ^! N) U switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
2 ~$ B6 s) _. w+ H# l% y. w/ V5 }1 W {
! C& i6 q1 I7 \6 L! T! v w0 i case '<': /*优先级小于栈顶结点,则运算符入栈*/: m8 }# }+ F7 N1 \; E! m
Push(optr,opr_in);* k% v0 ?7 v6 G1 }1 u! O; U A% y/ W; S1 p
printf("optr入栈:[%c]\n",opr_in.ch);
1 X1 Q; Y0 y. V$ d! Z% w c=getchar();
: e% A) f/ W8 A6 c break;
3 {/ q: A t9 U$ D case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/6 f$ c0 R ?) L1 j3 y' f; q
Pop(optr,e);! W: C+ o; _, B3 _+ \3 I: m
printf("optr出栈:去掉括号\n");
' T$ R9 D r7 ^ r- n6 }" Z4 c+ Z c=getchar();! p: H9 E) t9 v1 B
break;
! I6 s- r8 M6 ^! y case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/8 y' X& O) A- J1 N
Pop(optr,opr_t);: F8 p) k8 k/ u3 H- D K7 m
printf("optr出栈:[%c]\n",opr_t.ch);3 ^) U- @2 U! |8 w# T) Q
if(Pop(opnd,b)<0)
/ z8 ?5 K. a& H& j {; I; ?" M( j# C# e
printf("Bad Input!\n");1 D6 Z V: y6 ?; J
fflush(stdin);
4 o% `$ I: ~. w- c. g) V return -1;" Y8 ?9 C9 ]' J4 I* P5 i3 q, v$ u
}! e7 c- |: R% ^2 r4 M9 ^
printf("opnd出栈:[%f]\n",b.data);4 j1 ?% _' B- o2 q) K4 s' G! s" @
if(Pop(opnd,a)<0)6 S( O4 A. k; h
{
8 {& F% c) H( ^9 u printf("Bad Input!\n");
# }# r2 H3 |4 F+ Z% p fflush(stdin);+ g x* U" Q6 ]4 b. g
return -1;
: F9 ]5 a: @! i2 ?+ z }
; }" c* d6 r* t; w3 y- x' I3 V, @ printf("opnd出栈:[%f]\n",a.data);) r" P9 ?8 W5 E& x3 P
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
* l% K; A% W/ `( K [2 _ Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/& Y) q: t" @1 A! E& [& F4 J# o( i2 L
printf("结果入栈:[%f]\n",opn_tmp.data);* H# U, x0 q$ M+ W4 y9 Y: |
break;2 _0 Z/ P N M
}
& d8 v( S$ v: l0 D) B: ~ }. y" P! @* i# V. d! j9 w; i
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
2 c" u; c4 J" _ }0 a8 h( u; v& u$ p) z+ t
GetTop(opnd,opn_tmp);
8 l0 s9 P- @( H, n DestroyStack(optr);; g" d( d! V8 ?, O( _6 }+ p8 \. L! V
DestroyStack(opnd);
$ D* [7 B: w: g6 O return opn_tmp.data;
6 R% D/ E1 d2 y7 _9 k! A2 ~( K}
4 i6 T+ y2 }& J; C# p& w* T6 d: f. D
char *killzero(char *res,float result)4 T, u% s" e6 p: Q) R% Y" S1 u
{1 a) o7 [, m& J0 E% q. q
int i;
( ?1 w5 Y& m7 o/ }7 N8 G" H2 `) T6 b0 h3 s
sprintf(res,"%f",result);
3 S) }" j4 M, S/ {% } v7 r, g0 ~ i=(int)strlen(res)-1;
) i9 Z( ^& x4 u7 d' _! v; p' X% w) j while(i&&res=='0')
% K$ r# s% B$ ]% t6 V {
& u. l* {0 o& }) Z res='\0';3 @# r6 j, `+ J) Y6 G0 O7 |
i--;
7 @. r3 i# b2 g% W0 K& H8 @4 ] }
' r+ t( V% A; b9 E! v( [ if(res=='.')1 P4 Z5 K/ E! r. a6 P- n' q& ^
res='\0';
1 b5 G# ^2 w& `, b return res;6 s" w& Z' }7 m3 K
}
3 X: s8 e0 d# T
# x: |; w1 B1 I: E. z9 _# tint main()) z: T3 b( k- y3 S: f# t
{
. v; a! E r9 J% J, D( z- z$ r9 x: P char ch;* X: l, j' f) ^! W, k
char res[64];3 l) q$ s! E9 G* K2 [4 O, K2 I
float result;
7 k' I- J9 m; f/ o9 X. l while(1)
$ Y& S8 T0 f% H. s, D: e) A d {
, }$ [, T8 J- n0 P R5 A: B result=compute();
0 Z) |8 y0 F+ M printf("\nThe result is:%s\n",killzero(res,result));# N1 v: m# \* n* k7 X
printf("Do you want to continue(y/n)?:") ;
: R- W# N+ o' V( U. C ch=getch();' M8 P F# V! i/ D6 T
putchar(ch);5 P7 m, K5 L; F+ {
if(ch=='n'||ch=='N')
0 X9 i; ^$ C! a% k break;
( E0 M% [7 i8 c4 B7 r8 j else7 N% c# }! k3 _7 Q9 ?# b
system("cls");
$ g. V8 ]: ^+ `9 l. y% R }
/ W8 w1 V; m+ m& u' J" k4 O6 N+ G return 0;. P- w4 A- \: K. _
}6 G* m! n9 I! m1 r% m8 F
$ F% Z$ D% E& ]& ]
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|