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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.! y' V h4 c1 N! z5 a
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=! {# [: p0 H+ K# L9 O: ]" }9 i* o
/**************表达式计算器************/
9 [0 w5 K& W0 W/ a#include <stdio.h>
3 t2 k: R# e/ b' P2 p7 h#include <stdlib.h> ~ R& I$ h7 U* W; z
#include <string.h>+ I3 b: p2 Z# }/ t8 C- t$ W, Y) H
#include <conio.h>
) i& Y6 A6 @0 F8 E7 |7 D#include <malloc.h>( F9 \, y# y1 U
) W$ B* i+ G M4 P0 Q. T#define STACK_SIZE 100
% C( e8 q' L4 q6 B% v#define APPEND_SIZE 10' O- S9 T( T( d/ L {' I
- M7 g& t% E) D3 U3 @! Gstruct SNode{
; g" V/ V, k! c. n5 R4 C float data; /*存放操作数或者计算结果*// ]# t, B L$ M6 W, M+ P" I
char ch; /*存放运算符*/; i6 Y0 R8 @+ p
};
% C3 z2 g* k: Q- p
* i- N: ?5 L. B5 wstruct Stack{
3 e0 N a4 @) @/ V2 }) ] SNode *top;
# T1 P1 _1 N2 {* c SNode *base;
2 {1 I( G0 O, T" ]6 Z5 X( G int size;
s5 D+ U) I' {, S* F) s( b};/ A4 S" N, w# u% D4 N/ S# D
/ o5 [( U, K/ @) S$ e5 A; k
/*栈操作函数*/
2 o. c- t, e* tint InitStack(Stack &S); /*创建栈*/
% [6 m$ ^9 Y' P7 O" R4 Vint DestroyStack(Stack &S); /*销毁栈*/$ S- q2 L2 ~$ j3 P% T" o
int ClearStack(Stack &S); /*清空栈*/
y7 v: U' p2 nint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
0 m: P% ^+ S+ }% w; }, u+ B& cint Push(Stack &S,SNode e); /*将结点e压入栈*/
4 a# d1 o; B) |& y" t1 }! gint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/% A1 O4 p' \' ? V( S& h
' v, y( k# {7 ?/*表达式计算器相关函数*/
1 |$ e8 b9 Q2 q1 ]+ g2 ]char get_precede(char s,char c); /*判断运算符s和c的优先级*/$ B# y0 | @' W6 ~
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/) U, w' o! d2 E, N2 P
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/& }; \& V; z7 `/ h3 s0 l
float compute(); /*表达式结算器主函数*/7 k' P2 v8 i P. y# g- ]% u! e
char *killzero(float result); /*去掉结果后面的0*/ ; y, v2 }1 e- q& Q' J3 f* T, O; c
1 q9 T+ h; K8 G! @( a) B
int InitStack(Stack &S)
7 O2 S& }3 o* W" t6 K/ y" P{
. h: l4 o6 Y* v- L/ B6 t2 t S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));! l& s1 R4 g" [# k7 Y. I
if(S.base==NULL)
( w4 C; J5 U e {( B8 R& d3 A3 Z" w2 _/ e
printf("动态分配内存失败!");
6 R C( R, R5 ^1 S* A* D return -1;5 V6 U! v# q: Q$ b) P: ~% o( A$ R
}
4 v3 r# ~6 _& ^( ^0 h! ? S.top=S.base;+ a) D& _& v) Q" R8 }6 n
S.size=STACK_SIZE;
" [3 C- _( g. I4 v* g* a return 0;
" V3 V Q8 F8 U' ^' w# j4 w3 ]}4 @9 ~, O: X N* W# }1 m& j R6 p
: q. R0 n: ^" u' n# c4 u/ H2 O, c
int DestroyStack(Stack &S)
[6 D! g, J- q% N. @( x$ P{9 S7 c/ o0 V \% q' |; }1 `
free(S.base);
2 R$ \/ D; V! N9 ]; O( ?8 _ return 0;
1 ?8 O7 q# S( @ G, N o" h}$ |3 d! ^9 u D; J
/ C8 R- ?0 ] e. M- g" _9 ^1 Fint ClearStack(Stack &S)! @- h* `4 _1 Z0 j9 S- r
{
S4 Q* U( L" H$ t$ | S.top=S.base;4 k' N& F: }9 u& G* G0 s3 V
return 0;$ [1 `* C: T8 A2 D F! U5 m' C
}
- s6 p+ m3 t. U0 S8 y& g8 [* R$ D- q2 A! s: Z
int GetTop(Stack S,SNode &e)
7 I8 J, b8 u9 ^* N& Y( p3 F, G0 s' p5 X{7 ^/ x i1 d" y% B$ \( {
if(S.top==S.base)
* J# C; X# [# }5 m- m {5 l! M' D- ^2 ^+ g* b/ o0 z' @" b' t
printf("栈以为空!");) q1 v7 f! e" S7 _+ k! Z" [- a- |
return -1;
" }3 F: V! l6 g }6 o+ o* y3 g8 P: s- w
e=*(S.top-1);" g: \% [, }8 ]
return 0;3 u; m: I* _; L
}
3 F: y; V. l2 g& E9 ~8 k
2 M2 ?& A6 ?& s5 H9 vint Push(Stack &S,SNode e)5 ]2 K6 n1 x! ?3 l# d# I8 D
{
( }# b' g$ h9 W; u& s1 c if(S.top-S.base>=S.size)2 a7 ?+ R# O2 d. ~* t
{
; B6 ]0 w0 H3 {( }, M9 o S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));. h A' z0 o1 P
if(S.base==NULL)
4 s. i! C$ V5 R7 b {
- b! L: Z: j' Y8 A/ c( l printf("动态分配内存失败!");9 Q8 v/ x( _$ i6 Q' B. _
return -1;4 K/ j: Z0 h6 d0 Z) u
}5 ]9 c2 k6 Y7 i0 r( ]) ]8 k
S.top=S.base+S.size;
9 l2 ?- e) d! A( W/ I S.size+=APPEND_SIZE;
8 [3 E7 l' S, W% K( m0 I; H }+ Y7 N$ {0 h6 i) `- g& d6 G
*S.top=e;
0 w. V% p+ b+ J S.top++;
0 I2 Z8 U1 p' y! P6 h0 w. s* w( t return 0;
% \( f' |( Y- A6 C% j W0 M6 R}; [& l( m% X) X+ Z; g0 `' {, \
: m" |) V! v# @
int Pop(Stack &S,SNode &e)
* g2 q* s. ?7 h' T1 t+ ]{
: b. o; ]# k8 d( m+ Z if(S.top==S.base)# ?. [ a' ~: V: M" l9 d7 p% Q7 @
{3 ~. x# e: A! n7 w* k
printf("栈为空!");
4 x- c2 Z, V G. _ H9 P- t: b return -1;
, J( ^" _) P( r& A+ y }
/ M" l1 X+ S. b3 v6 J e=*(S.top-1);
' b' z& L& _1 m4 n: ?% Q3 R S.top--;# f1 o5 H b, i: l: w {& G
return 0;5 B9 N4 K, \) M) m7 P
}0 u! F7 I: I" e3 s4 k* j
) d$ Y, M* H& y$ `
char get_precede(char s,char c)
1 _: n, i1 \/ X; k{
m+ t q" F& Q' P0 I switch(s)# y1 L4 h; k, c) l8 `8 a3 W: S5 m
{
) o+ ~( @* ^- _+ l0 | case '+': # g) Z5 ]) t1 F) U) c
case '-':
6 z! l# k, `$ ~+ y$ n; y& t if(c=='+'||c=='-')
- C+ `. a5 w( R: \" }4 |% P return '>'; e+ }3 t# i1 `. H
else if(c=='*'||c=='/')
5 h; A, ?: P) s& r return '<';
% |; w) K0 M5 p4 n else if(c=='(')4 u% _8 g! u8 H/ c9 z5 O6 `! ^6 t
return '<';' i( A4 t" k7 v0 e1 T
else if(c==')')3 \/ a+ F) E5 E" N; t
return '>';9 a5 y" \4 y+ R( I
else / Y" e4 d. W' D
return '>';
; e9 {. E; p2 s2 ? case '*':: f) f( p( t: ^0 W
case '/':+ t% y y, _; H- i
if(c=='+'||c=='-')2 }9 N$ n6 }. w
return '>';, s; W m: r! \9 K/ h7 _; ?
else if(c=='*'||c=='/')
- o9 r3 z5 G0 O; r" |# u return '>';0 [, m0 U) p$ `9 x
else if(c=='(')$ C" x9 |$ ? l& |# g
return '<';
2 {, K0 V5 \! f* P' M2 h1 x7 r! y else if(c==')')
8 G$ Z; D: _: u# L t return '>';4 F8 g7 O7 M# b s' L( O4 B% g
else R0 ]$ n+ p: E
return '>';# [; a6 D2 }. w. @4 w; J
case '(':+ D% H9 ?8 |+ a
if(c=='+'||c=='-')
7 ]; P' E W- f( h' k$ J return '<';) n% O$ V* h& [% |
else if(c=='*'||c=='/')
( n5 g1 ^4 I2 Z8 I3 t& p5 V, i return '<';
; T8 d- H2 W0 N' y else if(c=='(')
# x% x7 `5 [$ A8 h* a6 J) \ return '<';
6 a2 p1 g/ W) j; A7 }0 L else if(c==')')( ^; R) f8 r! L4 z! y7 s
return '=';6 e% [1 _, L9 i( K( K. L ?
else( {2 t7 C$ x9 V' y/ c, a
return 'E';
3 f9 r2 G+ ?% v# e/ W case ')':% {8 z Q8 P l( c" q2 ]
if(c=='+'||c=='-')
% K* g& R# ^8 ^ K$ K) j- t8 E! D return '>';
' H! g# u/ f/ R; B& V. Z else if(c=='*'||c=='/')" a' H- v6 \' _( b
return '>';, J! Q' b$ |: U/ ~' {, c
else if(c=='(')
6 I% S' C* k/ l$ t, ? return 'E';; x: A% z8 K' ?' x) T
else if(c==')')% E1 r6 ]) f; s3 U P# {
return '>';
# O9 S: c1 J2 Y2 m6 C. x else
5 | [- Q l: ?- j# {) B- e" @ return '>';
3 u& I W" U2 U1 h case '#':
% X; L% l0 B8 S. M4 I if(c=='+'||c=='-')$ x8 P2 |2 U5 n6 s" r+ N
return '<';3 V9 W1 s% A) t1 W! o( y. e) T* b
else if(c=='*'||c=='/')4 v# y; j; M4 _/ E# ^1 W
return '<';& A* B) X5 t* u- c# N3 B* p
else if(c=='(')
8 ?/ [4 S; ?8 p; c4 C return '<';0 ^- [# I( r# j# E% Q" X9 c7 [
else if(c==')')$ m! \3 o: d; C5 q5 @" _ ~
return 'E';+ r( C1 Z. z. H3 T* J! S
else- i- H+ I; O. S& \% m5 i6 ~) J& P
return '=';
0 u" Q8 T# T! [9 I0 G: |: ]: t7 F default:
; g8 u! ^, m& S break;
c$ T, ] r. Q; C n) Q$ f9 X }; Z# ~4 C. n# _( r+ J2 E, D
return 0; 7 M- {9 n& l9 h c) g
}
' V7 C& C/ V. b+ W5 ?9 {8 s5 @* I* T. b m& \) h* n
int isOpr(char c)
, ~6 A- u4 \* Q! p2 H{
; d$ K' l6 O( \# ~' }8 j if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
n9 A& s$ m/ Z2 u9 G return 0;. W4 N5 n' y/ V" e" H. K
else Q# k( d# W6 Y$ |
return 1;
* ~7 w2 x3 S. z: w# `}. v* o9 w4 F* b% s8 o
+ @7 r4 {& \5 h" g
float operate(float x, char opr, float y)
1 F% h6 ~8 J: T% O r. E1 p/ o3 _{" H2 G, z- t0 q# g( H
float result;
, p" \2 P% U% Z: L$ d$ t `& K8 ? switch (opr)# x* T0 d* B h- c' `2 m+ g- m1 y' V
{
# [6 B' C" w% ^3 e case '+': 7 G" [& z) f% m2 `! `5 w
result = x + y;
$ w& h& q4 m# C9 `# p2 Q. v- m% Z break;
. d" a3 i3 _3 Q" ~. o case '-':
! Q, {, ^" F# i2 N- x# f result = x - y; ~& D$ e# }# t% D
break;
3 ?1 Y; I5 V+ |9 k* ~. r$ U/ Y5 G L case '*':
* I# Y! i+ R# q result = x * y;
- r9 K$ Z" o, s, q8 j6 O/ D break;: U2 r% E: H, o+ m! k: Q- r2 o
case '/': & v- ?! w- h! R5 N) k
if (y == 0)5 f6 V0 ?4 o% d9 ^3 a: x
{# Q( `5 X; U% x
printf("Divided by zero!\n");
0 m, Z2 Y7 g) Q/ E2 }4 ~( Q return 0;8 R# t$ k$ m' X8 U& O* O' i
}: i9 I l: z8 N+ ~5 V4 p! r
else
8 f! ]0 t7 S2 ~; P7 b' T {
. \. I V$ B, y; x& t' O: h result = x / y;
% t2 z9 ]: W# W break;
Y& M/ v# T+ k; Z+ b- `4 R# \ }
% S; ^/ T* [7 m( Z default:
1 R c, e. B# _ H printf("Bad Input.\n");
: k. l5 O. x0 l8 w t3 V+ K return 0;" b1 I5 W! U- ]6 S B% h; @
}# H3 C& c# s8 Z6 [! F u* z+ N" X
return result;
N6 B$ Q7 c' M} ' s+ n; p" E. Z
5 h6 P- o6 l6 M, R* K0 f+ C9 lfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/2 W" _4 @3 I1 c
{
0 O U: e7 i0 b Stack optr,opnd;
: u& Z, a; ~4 q5 l* X9 M4 @ E struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;& w6 o0 o9 _5 ]
char c;- k! u" R$ V4 ?- C) }' T3 w1 ^
char buf[16];
7 f1 S& {8 X* V+ B# B int i=0;7 H/ H# q2 p5 c/ C' H
1 {8 \2 O9 }' a% ?) G
InitStack(optr); /*用于寄存运算符*/
% G. H0 x3 i9 S! E) } InitStack(opnd); /*用于寄存操作数和计算结果*/( ]; ~" b- _: r) m
memset(buf,0,sizeof(buf));
9 }, L) [+ X3 x, S 4 ]5 z& I0 Q. @: J/ O
printf("Enter your expression:");4 K. n; W& E$ ]" o8 {/ F ]
9 w& J* C! k5 p1 u. Q" N y opr_in.ch='#';
8 T. B! s- @* V) z6 d Push(optr,opr_in); /*'#'入栈*/3 ~! F o$ S7 t8 t0 Z- J ]( Z
GetTop(optr,opr_top);
% _; B) T6 x+ g5 \% R, F2 q0 k5 y c=getchar();
. Q) \4 c0 E9 a while(c!='='||opr_top.ch!='#')
/ c! G2 R/ m0 T! C* c {
! e% u3 k' m% O; u if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/7 R, @# S7 x4 K+ {9 D$ X% P, C9 {
{
7 b; |' L, j6 A2 F; n buf=c;
& C% B- o, i# T5 w i++;
8 \1 O2 A# a @& e" |" x7 \ c=getchar();
- @$ O* i" U8 o6 P( o }. u/ P C5 S) C% I
else /*是运算符*/5 V% }' F2 _5 ?! b0 H' U- _
{
' K. u# n$ R8 h; g6 t' i buf='\0';
q/ n! t' y$ d @: U! E if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/5 E9 I) t% b2 r1 R- O
{
. K( N1 ]' f- E" N I opn_in.data=(float)atof(buf);
4 {' w1 T7 d3 k0 A8 v e Push(opnd,opn_in); n& A5 u! g$ j; _# g) H/ J2 L
printf("opnd入栈:[%f]\n",opn_in.data);
& U- l# \) I2 n4 f) W9 M7 K X i=0;! s# w# K: ^! e! G$ j9 X- R
memset(buf,0,sizeof(buf));' F$ a4 g' {) E- | H" \5 W$ b
}
5 n$ X$ Y5 Z8 f5 _1 q3 v opr_in.ch=c;
4 s2 K# Q8 m7 F switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
5 U( |0 ~" @: R' ]1 b {# V$ t# H3 O9 }
case '<': /*优先级小于栈顶结点,则运算符入栈*/# M* O; |; w/ T. W3 s1 [6 K1 z
Push(optr,opr_in);
! s; ]$ i% \8 q4 E printf("optr入栈:[%c]\n",opr_in.ch);
. w4 Q* F; R- c+ g5 D$ u4 m c=getchar(); M3 M* X& R5 [; u* |( C6 |
break;
# f. h0 M2 G1 Y( d case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/% f4 b6 |' t6 w/ ]" }( k
Pop(optr,e);" \9 V$ }3 F$ G8 y2 \
printf("optr出栈:去掉括号\n");0 P. M" K. e3 O4 r& t7 k- v. i: }
c=getchar();
c' U0 D5 {8 Q) Y. L break;" E7 n5 R3 R% |% z: B6 R
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
% E! I4 t( A; {, ?6 f& J* Z6 ^ Pop(optr,opr_t); |9 A6 ~/ t3 y: p* f9 i0 j; r
printf("optr出栈:[%c]\n",opr_t.ch);, F6 i0 L- d4 z7 S' ^
if(Pop(opnd,b)<0)
% x; o. Y" A) R( h* |( g {9 z9 Z$ J9 W& Z& T4 R$ u* {
printf("Bad Input!\n");
' s: b2 y. o9 v, U# ? fflush(stdin);
: M; F, |' b3 T return -1;/ E7 L, m! n4 i0 M% U E
}
: C, D% V9 R p8 t7 g printf("opnd出栈:[%f]\n",b.data);1 G, p# N' `8 G6 U6 Q8 m" }# i( d% v
if(Pop(opnd,a)<0)& ~0 P* W' F. U5 W/ A! w% `
{* |& S; l7 U* t, [( Q
printf("Bad Input!\n");
, h" z# u; v7 H$ Y8 l1 T fflush(stdin);4 o: o: @3 d7 l6 [. H
return -1;
" I8 k# `$ X* O! k. |2 p }
: a5 p" O5 B8 W1 g printf("opnd出栈:[%f]\n",a.data);
! ~- C1 F K% X opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
% c! C, i% ]0 U Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
/ }$ t) j& _, R) y/ H printf("结果入栈:[%f]\n",opn_tmp.data);
* n( q: A; @5 h4 o& j3 ^) |8 X3 ?3 ? _5 x break;
" C- M8 V0 I0 L7 q4 Y2 I2 s i: ? }
$ U8 B! p0 z: `8 `: L# a. \ }
# D( B5 y x( X* `; ]0 B" X5 p GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
6 b" Q$ E* M. N1 w" F6 q. X }8 ^5 ?. r4 {9 p2 Q! Y/ `
GetTop(opnd,opn_tmp);+ i0 P6 a1 i0 l0 Q
DestroyStack(optr);
# |! |/ Y: ?: e1 q6 d4 c; N6 H DestroyStack(opnd);2 |. r. L$ J5 j2 f( c
return opn_tmp.data;
% d$ ]! _, R8 M" a& h}
& {: ]0 T8 a7 F- ^0 g9 @ \
, B* `- J7 N% N& e4 p6 J& mchar *killzero(char *res,float result)7 |, k- W9 `; e" I( d0 F# h
{
* i# p7 X: z% S: v, n int i;: p; I6 {" h) W/ T" ]" [
7 h- R$ A( n+ \$ l/ J: b- K4 z sprintf(res,"%f",result);
0 ]: k6 j: G3 I+ X* v' c2 ] i=(int)strlen(res)-1;( u; ~& J2 K. J2 P7 b w7 i
while(i&&res=='0')* v' B- Q& Q# n# l9 w2 r- ^; N
{
* t6 c+ `% g6 a; \5 t5 t! I/ a4 r res='\0';3 n4 N h& V: f2 k& s/ Z& Q
i--;) z, M) n3 x/ b) b: j7 e* S2 Q
}
( W) h& b) u. c9 X% [8 T0 k if(res=='.')
6 g3 y& u# H* a res='\0';
. p" l0 l1 @: s4 e7 t return res;
. Y, D2 v, O, M2 [6 E: A% o# K}: D/ E, @$ M( {1 X4 z
* U8 M) p, c+ B) \0 o; [4 B, ~
int main(): J) W* N+ J* s1 `5 P
{9 x; _! _# _" n( R
char ch;" m# ]% f5 R3 [7 z: }( j
char res[64];0 | z1 S! ]8 [7 H% [
float result;
# k+ g4 C6 Q% p* G w while(1)
) r1 k0 g; y9 r1 C4 | {9 l* n& x* _* Y+ d8 `" x; S4 q
result=compute(); V" ^) G; Q+ o( o; z* z
printf("\nThe result is:%s\n",killzero(res,result));* U! ]2 E, k' m7 r* y, I
printf("Do you want to continue(y/n)?:") ;5 Z1 N0 U/ B: m4 z1 Y
ch=getch();
1 V7 s% Q8 t, q$ s% i putchar(ch);; d+ q: R$ j' u( I# i/ H0 {, {: o
if(ch=='n'||ch=='N')
4 Y9 L0 E% D, d break;
2 U; W' V$ T, ^+ \( G* m' N else
+ }9 M; v8 |* L U system("cls");9 B! E2 N9 o5 K; u9 Z3 n* j
}
5 `7 a$ p I0 Z+ o return 0;
' t6 q* d- W2 W' @' ]0 l}4 x _" x& `8 ~7 a: L
- o9 `. V# p; g) e: Q4 s, c
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|