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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
9 A6 D! M5 J4 o& D: b, c* U程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
1 K2 C8 i" O8 \$ n% c/**************表达式计算器************/1 h7 G6 S6 b7 C% G8 u8 E
#include <stdio.h>
" m. L8 L- I& i#include <stdlib.h>3 i8 J* f: C' D% _1 I. W* d. i
#include <string.h>' O" D& c( G9 f! ?2 F' w. b. q; U
#include <conio.h>& _0 {, N; I3 X% R! `9 n
#include <malloc.h>
) {8 i, _( Y7 [6 ^' f0 d" J
6 y3 n6 @# K/ X* ^6 N#define STACK_SIZE 100- X& d( h# P4 I; A" F9 [
#define APPEND_SIZE 10& M" m& X6 Y" @2 B& k& E
4 E, v0 Z4 h6 X# n4 n1 q+ S
struct SNode{; I& ]3 @( R! \9 x0 b L
float data; /*存放操作数或者计算结果*/
! Y: |# {5 B. N0 F4 ? char ch; /*存放运算符*/
- @9 v* |0 k# n6 y) g, S; S};
( J0 ?0 U0 C) f. P( M. N7 y/ Z3 R: v+ l+ k6 j
struct Stack{5 j6 f% q1 P, y- x
SNode *top;
1 l- g& s0 c E. Q- I4 z SNode *base;
8 V$ g9 l+ [7 c p* @ int size;
- ^" Y# v4 P8 E, e$ f" C* g7 Y7 i, |5 G}; s: ]2 d8 p; V( b" i) j8 B
Z" t v$ T9 N3 l! X/ Q' m
/*栈操作函数*/% L$ L& C7 P$ f6 ~1 b
int InitStack(Stack &S); /*创建栈*/
, d! O7 _! I- e3 u% P' G7 dint DestroyStack(Stack &S); /*销毁栈*/
) ?& ^5 Y0 X; N7 R* _int ClearStack(Stack &S); /*清空栈*/
1 ]* M0 r3 ?/ A7 a L5 yint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/% e* F5 v; X' x# k
int Push(Stack &S,SNode e); /*将结点e压入栈*/% e. h) [9 w2 z; [' E
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/& N, _2 O3 c& R: X
4 m# t, E8 J$ r6 T; {* Y/*表达式计算器相关函数*/
9 ], E1 l! }3 Q4 |7 |1 w5 @char get_precede(char s,char c); /*判断运算符s和c的优先级*/
) \, w% [' R3 N& z6 d% g+ Xint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
. e( C2 r0 D8 ~2 G5 s9 ?1 hfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/3 C9 y+ j: [% z# l6 f
float compute(); /*表达式结算器主函数*/
7 e+ @, R1 G- ?4 w6 W" F) o' achar *killzero(float result); /*去掉结果后面的0*/ P% \( ]/ Y" n: h/ x
; H: [' L' V: K7 G- M0 U' o4 ~$ f
int InitStack(Stack &S)
# Q4 k& l/ [8 K; E% {{
. R' f0 K3 R4 Z8 \ G7 b S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));0 q' U! V; o& K5 L# [
if(S.base==NULL)
& {! [2 L* [" _. ] {# C' [# {9 Q* F( ?! v& Q
printf("动态分配内存失败!");
- a# ?0 w {8 |$ Q6 j* @ return -1;. p8 u1 m3 q% I1 d
} ` g0 j# ]2 G' E# ]
S.top=S.base;
0 b0 s R6 `) C S.size=STACK_SIZE;8 z9 {( g; f) z2 I; ~
return 0;* X1 y/ E, Z3 P* K7 Q9 ^7 b
}- V2 @4 v, F" q0 D) o
& w" C ]0 k: M7 Lint DestroyStack(Stack &S)
7 r3 V, ~+ V1 d1 l. p7 |{* ~: G7 ?6 ?: f1 Y
free(S.base);
7 s$ X( n1 m3 m2 o/ x7 R2 }# R4 N return 0;, ^* k; y/ d4 r! E
}" ~; }4 w4 X2 }6 X5 U
& u8 w. o8 N- a$ ?. G) s+ Vint ClearStack(Stack &S)+ w4 ~+ |% P* ~4 h$ Y V
{
% N3 U, k$ ?3 Z8 } l/ x S.top=S.base;
" P- `+ a. @. m! V2 g3 U6 J return 0;; ^; b8 m% ~! s8 D9 }$ C1 T
}
3 t: o5 m3 \4 N Y" B# @/ P, [, y0 U) m
int GetTop(Stack S,SNode &e)
6 i$ T6 J8 ]. e' o2 j{7 S& A' G; W0 S: Z% V" `4 h
if(S.top==S.base)
) `8 h) R, [( q" m3 h6 F" n4 D/ Q {
1 }% D$ u( ~% D+ m! @ printf("栈以为空!");% S+ ^7 }$ t/ Q) S/ D6 y
return -1;
& i O8 F& Z" f: l }
6 b1 |, f8 ?' f8 W' k9 K' A e=*(S.top-1);6 S/ X' t& z% ]6 z
return 0;' O6 d" |6 C* W
}
0 u4 i$ {6 s% u# X- e9 }; P+ l6 g- A4 h+ {6 X/ I( ?/ I' V4 `
int Push(Stack &S,SNode e)9 y: Q$ v# n# d! Y$ q
{" {' F# Q3 m8 M* O9 H
if(S.top-S.base>=S.size), O( P4 \% y" K9 P
{
w6 @/ T7 j0 q( K' A S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));; o S/ F/ u0 H* {8 w J# {; \! L
if(S.base==NULL)
8 m& Z. F T' e0 M9 H4 s4 Y {9 y+ r, g% B W
printf("动态分配内存失败!");
- O; P! d- H3 P ?! y% i4 V/ @ return -1;. D. W; b% Z5 Z' x4 i3 ~
}
i7 ]6 T1 S! O n7 S S.top=S.base+S.size;
% o4 [! a" J- t' k$ L7 z0 O( T, G- B S.size+=APPEND_SIZE;
{! L# ~9 e+ [3 s, L: t }, A1 E- c# t: U8 `
*S.top=e;" f' F6 r! R* J( e: \/ z
S.top++;
, Q% X' f4 ~; {" D0 d return 0;+ g/ s- l) s* O! l- I
}
. T v0 t, ]2 e) d
* x Y+ S5 C2 Y# x9 wint Pop(Stack &S,SNode &e)
" M' h/ M' b& g7 j U5 s) b' E- c! |{
! e8 G2 G1 E. B3 J if(S.top==S.base)' h; M7 F6 D" d3 G0 ]+ W4 Z
{
. E! C: S4 I' D' M: d printf("栈为空!");% F5 |% V: h: F. K
return -1;. k$ G5 N$ X9 d& ?5 Z
}
% h# |4 Z0 G+ m* h. x! W e=*(S.top-1);
* H2 Q7 t/ |7 T9 ], `- t S.top--;
/ y7 r3 P; G, C return 0;% l3 \3 ~1 b6 `% L. ~
}
4 A6 x* O- B# s( Z* D5 x7 A. g9 S$ U; B- ^0 O
char get_precede(char s,char c)8 ?/ Q! V7 \. D5 I) w
{
1 q' w7 ?1 l+ S$ ^ switch(s)# g' p. j( F0 D' {1 [; p( F r
{: p0 X: l# w! }
case '+': |. S& h3 R' U" Q. v X* {" m* O
case '-':2 C0 C* M( _" q; d. }
if(c=='+'||c=='-')) q4 ]8 a: K0 \2 f) X* A
return '>';! q( V2 T4 m& Y. U3 |1 ~
else if(c=='*'||c=='/')
+ `' T# p n9 C# E! K2 {" {: w return '<';! H# ?) j& H7 E% S$ y
else if(c=='(')
& W) c( y$ X; n8 W: M3 y return '<';4 b) }4 r0 Y, P; g
else if(c==')')6 h: M; `8 l. y2 `$ B. [
return '>';
" ? {0 K# r3 m, V6 a- F else
4 p7 y( g) ~, V" Q7 h5 U# L5 S return '>';
- h% p/ h3 R! P ~ case '*':
2 _; s% v2 K6 w% I7 r case '/':' @/ @# Y8 Z% U* [
if(c=='+'||c=='-')* z% \9 `. l7 Q. ^
return '>';: T' |7 T. S, L# w
else if(c=='*'||c=='/')% G. C S- f. J. d
return '>';2 ?5 O: M% ~) ^9 w5 j7 n3 E
else if(c=='(')) ], N7 X* C2 @# \7 C3 e0 {
return '<'; z8 @$ x( ~+ L/ r/ p
else if(c==')')$ r0 | [# K7 p# A/ a" O, q9 c
return '>';8 q& x) A0 u/ f' r: h! ^" W: E
else
3 {( r$ j+ f/ F3 q! E; j. ` return '>';$ g& s! E; L. @: v: f5 l' X- ]# O
case '(':+ C5 Q# g* h J8 T2 ~
if(c=='+'||c=='-')/ O" t! S& O" a
return '<';
6 Y* y9 @9 a R8 e; r2 m4 E% n else if(c=='*'||c=='/')
8 H% R& S4 S' j1 d: c4 f return '<';6 n9 a9 ?6 z9 m1 \' I' P; @ Q5 p
else if(c=='(')
, B: L4 {' j$ ^* j return '<';
& d0 a9 F# x) G/ V3 D: a" v else if(c==')')7 c4 [0 S4 B( D0 p
return '=';- a3 r& u2 u9 S8 c* t2 G/ M
else1 k" |9 K( d+ n" N, g+ j( G
return 'E'; {/ X+ m/ O7 Y7 \5 n R
case ')':/ D9 P F6 p6 j5 W! S; P2 E
if(c=='+'||c=='-')
1 _ Z) P z5 ]& ]% o! \0 ` return '>';
& F/ ^5 F4 Q( l0 S* P$ {' E else if(c=='*'||c=='/')
]0 R7 f& o- z1 p5 ~ return '>';
: b( }3 C8 t: f0 V% g else if(c=='(')
# P5 @0 J1 q6 p$ [ return 'E';; l5 r+ u) H E/ P8 P# k4 B
else if(c==')')
6 l1 H) _( T9 J return '>';" ~4 _& Y2 E% E% S8 d! j
else( R6 D7 d4 I" T: {0 w0 W( A
return '>';
5 v3 @( K0 t+ n3 r0 l5 F. _6 a case '#':
, Q- T( z( p% g: l if(c=='+'||c=='-')
* m+ j1 n& A9 Q$ g6 a( M" S0 \ return '<';1 B& R v; E" J
else if(c=='*'||c=='/')
) p y% [ R7 H9 ]6 S4 p return '<';' b) `& l Z1 n; D1 u
else if(c=='(')' G7 F0 S( B: B8 U+ W% Y0 a2 B
return '<';
& a2 O' m+ ?4 t! B else if(c==')')2 r1 r2 k: J. f- B% }
return 'E';
, L+ s' a& F1 V4 j% t else
3 p9 `5 p; y, p e$ f, V# c return '=';
# X. p) f2 B6 a default:' I, A) T4 }8 ]% h- B4 {/ o; r- S0 L
break;
, Z* `+ x& [# H8 ~& d4 [+ J }
6 R, t4 U8 ^- ^5 Y( s4 ]) Z return 0; 7 Q. P. V; X/ w) k9 s2 ^
}
6 D3 ]' G. j* Q( f- o0 B) D5 b+ g( [; P2 j
int isOpr(char c)
/ c8 b6 j1 D, M1 R1 A8 e' V6 W! P{
2 c3 P) a3 j* j& k/ m, I0 k0 x if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')9 z; D, d/ ^& y1 F6 I
return 0;
+ d1 Y: V6 ]2 C6 M else
~0 N4 D8 z# p; ~$ _3 w/ V; y4 f A return 1;
2 T) A9 x. ~* m, y- m9 A) A/ I}3 g7 Z/ H' F* u
9 a( N1 P) ?+ ~! Q
float operate(float x, char opr, float y)
/ x" K* [7 \! c: g5 ?1 Z. Z' Q8 V3 P{" b, D" g4 P, E h
float result;
6 v. x4 P: @3 S/ F3 P switch (opr)2 V. [. n: J9 W+ r
{- i. e+ M$ X d! j* E( `2 U
case '+':
* I$ U7 y& w" h result = x + y;- H8 i2 G! N7 R4 O3 Z" t
break;9 p7 O( K* R0 A" l E$ X- K0 F
case '-':
) c& \; R. j4 [ result = x - y;2 m6 z) ^7 i5 T5 |
break;# E9 N u! x! T" I: d. X5 U
case '*': 5 b$ }: w* T+ @8 L. o0 ~* `
result = x * y;
: [' p( _. f: E$ y break;" C$ K* I; \3 E) \
case '/':
# l0 f. q( g: Y+ k1 x2 | if (y == 0)
+ @: i& p/ u/ Z( o$ B! G4 |5 i# N {
; O7 x# P7 E+ [) u; D. o- E printf("Divided by zero!\n");+ ^( z& B; q% l9 S1 e
return 0;
# ?" J9 u& }1 e6 C8 @* C K }$ R, x, @9 g. K$ w( [( S
else
, h3 z2 A. |2 W1 A/ I: q) _ {+ \0 k5 p; U! f5 }
result = x / y;
8 S! o) E+ A: _8 W# g break;
3 {- [8 o. I; {; a4 _2 S }
7 U# T7 t: A) | default:
8 \ o' t9 V" e2 j) O printf("Bad Input.\n");
) F: L$ P/ B- w: F; `2 r return 0;# Q0 W% ~- a" K6 b
}
( C1 W: ?# b. L+ | h( A) C; @ return result;; g5 P6 r1 H9 O9 E) Y# o1 ^2 |
} + s* v) G& ?% H8 P9 n- H
% k2 M8 C V1 V4 V
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
; K7 l/ V, S7 n{
, [9 \% N1 u( \ Stack optr,opnd;/ M$ r0 [' B/ l! ~
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
. Y: k; R( A; V! m( C char c;# _6 `+ X% M: _& h+ u
char buf[16];
$ K' S4 i+ ^+ Y# Z, O5 a7 s" z6 B int i=0;! N1 C) z( C: O2 v5 ^4 f" t
2 s+ B* o1 K+ A! ^, c1 f InitStack(optr); /*用于寄存运算符*/
) a' S8 p( V d5 F8 b InitStack(opnd); /*用于寄存操作数和计算结果*/
# M5 r* h V4 k, B memset(buf,0,sizeof(buf));
0 _: P! A2 A: A: D: y; e
" m, T; M: d8 O `7 M printf("Enter your expression:");
! H' t" u1 f+ h$ d: ^
- r( }" G1 W: I1 i) F2 e& E4 e Z# b opr_in.ch='#';
" M* A. v: g+ E9 P% w/ M Push(optr,opr_in); /*'#'入栈*/
+ ]) H: f* @2 s. I! p5 ` GetTop(optr,opr_top);
* p6 Y8 E* k6 q c=getchar();
z1 L, y4 }) K2 V while(c!='='||opr_top.ch!='#')
: j5 H* u5 _' v4 j {
- n. }; f9 R$ _) @2 g" S# d3 m if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/+ k6 o4 \) g% k2 x4 I
{, \" A+ M+ {2 p* u2 |
buf=c;- }. J6 B, t* M$ O, J0 w0 E. V
i++;
1 s) d# i0 E8 ^& k% t9 d) p# A' l$ l c=getchar();
8 l- V# \, `8 X* A, b/ n }: b p6 c* X- Y3 q* [+ N
else /*是运算符*/
& X; N; P- G. o5 v" \& G {
. n+ C5 M& G* H8 u, Q" S buf='\0';
$ Z+ }( x# M" v+ F6 q if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
7 ~# N" ^/ \6 q6 } {# r- j! {$ T4 x# g* m. d& \2 M' y
opn_in.data=(float)atof(buf); j l2 E6 |/ ~1 h) K7 _+ J0 V
Push(opnd,opn_in);& I. U8 i2 j6 m* b4 z
printf("opnd入栈:[%f]\n",opn_in.data);( ?3 ^" Z2 }3 X8 T7 W
i=0;1 ?% K* x" v; {/ x0 I5 G: X' v
memset(buf,0,sizeof(buf));' E; X G3 t' q7 W2 o B
}
o+ |/ a. e4 }! ^ opr_in.ch=c;. J8 r7 T" |2 @1 q" @
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
# ?' t* _3 v7 H& M# I {
( m& M! O$ X5 }4 D. R+ d' D( t6 V case '<': /*优先级小于栈顶结点,则运算符入栈*/
4 x3 d1 G1 i# [ e, [ Push(optr,opr_in);
& |$ M' i ]! y1 g9 Q printf("optr入栈:[%c]\n",opr_in.ch);
, f r$ l) N2 q c=getchar();3 j' A$ x# n' q2 k8 f
break;
3 z& l3 c* \5 C case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/5 n. N7 S$ q: |& v# ]* D
Pop(optr,e);1 c0 P! G3 R D% e+ `
printf("optr出栈:去掉括号\n");: D7 A5 u& c( X8 l
c=getchar();
; q4 D: L. Y. E: Q; d break;
& s& g3 b# ]2 r$ A: O, G case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
3 g, |! K5 J& ^+ N0 s) _* A1 b8 K7 t Pop(optr,opr_t);
! u" B( Z) A$ k2 c printf("optr出栈:[%c]\n",opr_t.ch);/ Z- O, N3 |: M
if(Pop(opnd,b)<0)
Q8 v. u4 _- s, i# a! \ {
% I" L* _! i* e0 }/ v3 z printf("Bad Input!\n");
- H0 a `: c9 ^6 Y fflush(stdin);0 a1 N( V( y8 a
return -1;
- C4 ^- k% }% G; l8 y* [) C% I }4 P# r# O' b# t' @) h3 g5 p- J
printf("opnd出栈:[%f]\n",b.data);
) Q. N, l8 @! g5 h% ] if(Pop(opnd,a)<0)
1 w2 b. m2 O1 z& j {& r; X! q- C- a2 G- Q
printf("Bad Input!\n");" R0 P- K7 w/ z
fflush(stdin);2 Q8 s# n3 u, F
return -1;4 ~% w" P: l% v5 B( E; D$ _9 T
}0 |# [0 u" V4 f2 }' J4 \
printf("opnd出栈:[%f]\n",a.data);
! A3 g7 a) q6 g3 @% @& k$ w& W opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
8 x, O [+ Y3 @+ S }9 h Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
( {0 ?" [2 G& \. B( _3 }: X printf("结果入栈:[%f]\n",opn_tmp.data);
1 V q: Z) [* P1 e) p" O break;. ~* x' V2 v. s! p3 O% [
}# M; d/ G, c! j; G; X( K
}" P" j+ r% e. [" U
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
& U$ ]+ O% w4 J5 E }( O: n9 X$ f, n) X" ~
GetTop(opnd,opn_tmp);: }4 ]! F+ y7 t5 i0 e6 M
DestroyStack(optr);( T" |7 S7 }; O) I
DestroyStack(opnd);2 K/ @) Z" i% L) z" O! X( L3 z
return opn_tmp.data;
5 T2 Y0 G* s ?. L- y; y+ w}# h! q& N5 v i, E& `4 l
5 H5 o# p6 ~" z' k- p6 uchar *killzero(char *res,float result)
1 C, U( i# [* M* f+ l! O9 Y{# ~& a3 c n: o }6 J2 Q
int i;, j/ }$ N' A7 J) ]# l. @
- P- B: T+ B" S sprintf(res,"%f",result);
, @9 L$ o) w& h. V" s1 S7 T i=(int)strlen(res)-1;9 M' z; _: A3 I# `4 L
while(i&&res=='0')
4 T, |& u! n! m1 W9 Z, } u {
% W; }5 {2 D9 [+ D& c+ M res='\0';
# H4 i( Q$ \( M1 u0 @ i--;
) h1 i3 d8 s- y% ^ }
8 \* Z% s$ x& Q) ?/ `( R) C9 P if(res=='.')
% ~* n+ Z: H6 p! v& p; Q res='\0';& {* E$ K, V/ Z
return res;
. t2 ?& [+ g7 i$ c" ?4 a/ M}
" Z: t7 f7 H- W8 q5 ~/ [9 f* }; k$ d( B! k% W. r4 x
int main()$ ^# y2 O$ K7 q7 O7 E/ A
{: I" H2 l0 W" k3 D
char ch;
- `0 {$ n% {- }# ^ char res[64];) k% g. m8 c& O! Q4 E% z
float result;
+ ]0 S! F2 N& h- h! W* ` while(1)
1 e7 m0 Y! c! U$ o {6 s2 w9 j; B) C4 P; W) p
result=compute();
s7 |" ?# m1 I9 i' _. M) t4 @& m printf("\nThe result is:%s\n",killzero(res,result));
8 j6 ?" P+ E6 M9 Z- ]( w$ U0 k. h printf("Do you want to continue(y/n)?:") ;
6 y" l( h7 M; y6 Q7 M; V ch=getch();' f& F1 x" W2 w4 h/ @
putchar(ch);
9 m9 t( O9 Z: ^* s' f if(ch=='n'||ch=='N'); T3 d" ?4 R! z2 h: l$ J
break;. [, n$ E; J% B5 f
else6 X4 q( I: Z- u
system("cls");' z5 ]8 b6 S2 X$ c. \: V
}
/ p0 w2 F: l( M return 0;
( t P8 O8 d; B4 U5 b [. w}% Q: @5 b! {2 \# p
1 |$ `, t+ V9 h1 s
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|