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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的. V( V$ q+ n# Y, C
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=* P( N6 L1 l3 h; C0 K
/**************表达式计算器************/0 M9 Q# e3 i/ l" u- v, U
#include <stdio.h>
8 n. H- ] i- P: [5 U! W, U1 K#include <stdlib.h>
* M. U0 w8 c- g1 Y8 d#include <string.h>/ t$ G5 Y' p7 G0 v4 G) ^2 `
#include <conio.h>
2 T u4 U! j: b1 L+ s; }6 @#include <malloc.h>% [9 G! p6 ~; [ O e3 I% s
W0 h, a3 ^% {) d#define STACK_SIZE 1003 H& r$ L2 I; n* P7 r
#define APPEND_SIZE 10
4 O5 t7 z4 L/ v0 S1 Y9 B+ |; w3 x, B
struct SNode{
* k1 L; T9 c' a, r float data; /*存放操作数或者计算结果*/! P, @/ O% [7 R3 @% p
char ch; /*存放运算符*/* G$ r& v1 p7 Z3 r
};5 `. T: t- m& g8 c2 I, m
# {2 F5 n" R4 N* _
struct Stack{
1 v7 V: z$ w3 Z8 E# T2 d SNode *top;
) b& u9 Q1 v& k7 M2 |1 h' t9 ]7 j SNode *base;
# {, c) N! T4 d8 ?) b, K int size;
- @+ _" P8 c7 u6 p};
: F% d$ n9 v+ z% ]/ k% ]- P2 ^' X. R0 ?/ h |8 {. [
/*栈操作函数*/, l- A: K! c! V3 ~6 Y
int InitStack(Stack &S); /*创建栈*/
" J6 \( _/ v+ M# f, Aint DestroyStack(Stack &S); /*销毁栈*/# m4 r6 o8 u/ a q3 R# L, w
int ClearStack(Stack &S); /*清空栈*/4 g6 V: m1 ^8 l
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
0 x- B* f! M. ~* z- P3 Lint Push(Stack &S,SNode e); /*将结点e压入栈*/& H. M5 @" e/ g* o' X2 X. j
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
2 J% b* A/ q, T/ R! U+ @; S
5 F6 V* i- W [/*表达式计算器相关函数*/
8 ~4 V* c1 T" c) e4 b' V+ i* wchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
" C3 V( ~+ W$ y" Vint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/4 n& H K9 a# `
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
8 u. K' {8 \ m" |6 S6 @% Xfloat compute(); /*表达式结算器主函数*/$ s" G6 J2 b% y, S ]7 w g+ B7 w
char *killzero(float result); /*去掉结果后面的0*/ 1 {( i" f1 @8 c: b$ [% W
0 W, f7 r" T0 r* I3 p/ q
int InitStack(Stack &S)
* Q% N' S6 Y: J{
5 Y+ m! Q: E$ w S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));/ R- Q6 F' m: v3 l# ~% X5 X
if(S.base==NULL)8 _8 d* B- p$ l+ @! U
{ J6 G# x& v5 b5 O% x
printf("动态分配内存失败!");! _3 v0 {- A8 Z* n
return -1;
7 t/ [; V! }. j: }* w }
4 f( x3 E B! \5 {" f S.top=S.base;' e6 Q0 ^* W# @/ _* ?8 }- a$ g, V
S.size=STACK_SIZE;
4 ~! r$ u6 a8 W6 _ return 0;0 S0 j; s7 k0 y. H3 j, s6 {2 ]2 i
}
, \ v/ O! }1 C% @7 I8 u" }% t! n* X0 `* \# K- N! ~: m+ G
int DestroyStack(Stack &S)
2 M; L/ I4 |2 g. E3 i- D) O G1 ~ p{
4 i H3 {1 H) O9 G free(S.base);, y4 y0 \; Y8 y% U C3 E
return 0;( }4 g$ S$ k5 N- h: H& t P6 b# S
} W; i" Z0 \" V
: h4 N/ P) R1 J2 M5 F
int ClearStack(Stack &S)% s8 N# ]# t1 Y4 i
{
: W; @4 Y* D$ L$ ^- ?7 { S.top=S.base; y8 W% p$ x* ]7 j- \0 V: j6 z
return 0;6 D6 z" u: i1 y+ l8 w# ]: [
}
5 R1 L6 S! ?- X5 e
2 E, ~" Y P8 tint GetTop(Stack S,SNode &e)5 }7 S9 l6 M$ Q9 B0 @
{. Z, f/ i. s* i; Y0 i! N( h9 i, {
if(S.top==S.base)
) L5 s* ]1 p# x {
+ B$ X% q& H, I# ] printf("栈以为空!");4 u7 \5 {+ M( r) U1 y w
return -1;
3 T/ G9 H1 ?6 Q9 b/ ~ }
. R8 }( G8 J4 T" i8 O. {0 [ e=*(S.top-1);2 {0 P; g. V! K% u& F( v
return 0;
& o* `$ Y4 Y3 D* e" _& Z4 o}
* ~; s; ?) Z0 \2 m: b; a+ L+ e/ F: S, K+ Y2 H+ T
int Push(Stack &S,SNode e)" d) L7 V9 N; I1 X: ]4 [: O
{
/ l2 ^, X; h5 j, m0 C if(S.top-S.base>=S.size)
8 M; T. A8 l4 @+ s- [. E {
( y1 l4 q# }4 B; e a S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));0 V- W: m9 k2 k
if(S.base==NULL); {+ H& W5 ^/ i2 |
{
) T/ P9 \: I" Z* e" b( }7 f printf("动态分配内存失败!");5 ]: {, u9 E% c# o8 ^, g- a
return -1;" I, J0 l" m, e# M/ H
}- k& E7 |2 M3 {- e
S.top=S.base+S.size;
; c+ f4 z" J ?$ } a% F- f- j S.size+=APPEND_SIZE;" B( c2 }1 Q7 G9 I3 _
}2 ?; O$ \& o1 g4 k
*S.top=e;6 [5 t! g/ L$ m+ o3 o: A
S.top++;! H9 @% t S. w9 e, ^5 \% l
return 0;
" w$ l" W& j" j2 r" y; t% u5 {}
# b7 J+ D- N7 I7 B1 G2 Q0 H; ]( q0 K7 i2 n) s
int Pop(Stack &S,SNode &e)
; D: H$ S5 c$ t8 v$ p$ W/ s{
* h- ^' |+ n9 a% S1 ?% r( r if(S.top==S.base)
0 H9 s- l0 d. R5 \- k$ ~, [ {, E ?- |# e4 } ~
printf("栈为空!");/ Q3 c0 s" R( L' R" P) e& u- j0 E
return -1;2 n! |( A- c- A: Y- l
}
]2 k: O4 I; \$ L5 B6 T- M6 G1 S( g e=*(S.top-1);
. W) J `/ @. J q) C7 k S.top--;
( b/ u2 c) c4 B( g return 0;: h9 }8 k- ]5 j. B! p2 @
}
5 k' {4 C' ]- |- c( ?
! F; u$ ^! G- f$ }7 qchar get_precede(char s,char c)8 Q3 e+ `- ?* `/ F8 W
{1 i9 D; d, l% u4 q2 r7 h4 e% U
switch(s)
- v9 I2 X8 s: j( Z0 l) f {3 L! I5 `& K! H, q% @" p
case '+': 9 u C. S$ t# H" q0 F1 k3 ^ J
case '-':
/ L- M8 z9 G' l if(c=='+'||c=='-')
+ o9 H5 o, w. I return '>';& h3 B( `1 ^; w: T: |: v3 I8 [
else if(c=='*'||c=='/')
( [! A$ s( `- _ return '<';
; d" y7 y/ D2 F. G2 I/ H( o- @6 G6 { else if(c=='(')
, F4 C) r" h3 T: r+ p. d6 O return '<';
4 Q8 ^# [! Y, Y- |. i6 x else if(c==')')
5 F) w! x# }; l* t( U' V return '>';
) m& G8 O, D i# n X f else
1 E0 H1 ?% ]) O. ` return '>';
. M V8 R0 b) f- M, B case '*':
3 a) p% s5 y% k7 k- ^5 U case '/':
+ E) N1 ?/ c# E2 y if(c=='+'||c=='-')
" R; b6 M% k' K1 x5 { return '>';
8 D9 `; p s, C! ~. C else if(c=='*'||c=='/')
0 L+ N) v' r/ D8 Z# `8 c: B3 f T5 c' i return '>';
6 S1 y" |: m' h! A- k else if(c=='(')9 g+ x' S8 ~2 D0 ]
return '<';7 e/ i" q h8 g% f
else if(c==')')
8 W6 l. D) H. q x7 `+ M4 h6 p I% Y return '>';- f8 _0 m8 H' _6 `: y
else
- U! v0 d$ ` i1 [) w* @# g; V# Q return '>';$ s7 a% u& n" C2 S* k3 b
case '(':
; U% j. G5 j* F' E8 [4 z+ r if(c=='+'||c=='-')8 ^0 J+ P, F3 Q# t; b5 P
return '<';
9 {$ ?& ~) c" z8 I( j" n$ u u4 | else if(c=='*'||c=='/')% M9 n+ K' R0 L7 e" w
return '<';" W; g- Q' p# _7 C* y& D& z
else if(c=='(')
2 V- S/ ^1 r+ A- P$ {+ E" G return '<';
( H2 g. G2 s. w5 k$ U, F else if(c==')')
& E3 I2 ~1 r+ y2 F return '=';
$ X& L. l& `$ t3 E else$ Z6 C" C/ P; r
return 'E';
+ f9 d) [* v- F, C9 L& f case ')':
8 B2 N$ e, l; d0 a- @ if(c=='+'||c=='-')
7 F. n5 m8 y5 z) }3 Z* d8 f return '>';# D7 t2 G7 p8 V5 }
else if(c=='*'||c=='/')
7 U. k1 v6 w9 G return '>';
$ _5 y- b& w* }1 b' G5 d, ^ else if(c=='(')" c7 F! d& c3 Z' s* j
return 'E';
: T8 D2 W# A- c8 I, F# u else if(c==')')
8 G! K% X$ j; b" D return '>';! M- ^' w4 P$ G
else
3 E2 P6 K' C4 f5 v" ^% Z return '>';. M+ ?& l1 A0 a- f! A) `* v
case '#':" ?9 A- N+ u3 j1 \4 ^) F
if(c=='+'||c=='-')
1 u% e1 t- U% C) M" l. x return '<';* }) y, y" y3 A
else if(c=='*'||c=='/')3 ^3 { d6 R- |3 F- P" k1 P" ^+ d
return '<';
- Y5 N8 f. y0 W* \* g' O2 D else if(c=='(')
, G& {/ K( C+ y# j0 O' P return '<';. l0 X; @: z2 [" E$ A5 _2 ]% J
else if(c==')')
# r. i. Q+ z) t& n return 'E';
7 m% e3 T& l* R else* K9 {8 k) ~) u3 j8 g# W) K' d
return '=';
4 }& W3 w; w; {: T$ S0 S, u default:9 S) _4 H' \4 b0 c4 g X4 o
break;
! l2 [1 S) g( f$ J+ B/ W, G7 \ }
( Y$ P+ m% }; F& J# B return 0; # I8 U/ \# l- O. V5 X' d
}! O! v9 z, O- e# L# r" P! ]
' G& V3 L/ \7 U+ f$ o" ~int isOpr(char c)1 y0 e& ]; t" \) p$ j1 @8 P4 t
{% s8 g7 r: c% M* X+ R
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')* Q: {& M" }1 Z
return 0;9 h( O9 p t4 Q5 }8 J6 e+ v% m
else
7 J0 Y1 l7 |% @ return 1;2 q# t+ U8 V; N. z
}9 r( b3 c2 k1 A. q" c- q
: n1 M6 ?) i* U# m, D2 k1 N9 Kfloat operate(float x, char opr, float y)$ I* P+ {! k3 ?
{% D$ q% S- k: D/ v1 y
float result; N* @0 Z' j% g8 i+ H- h% C
switch (opr)6 F9 p+ x" L0 V/ o! z( m& y3 i
{
# P, r1 [7 T; ?1 _' I, S! q case '+':
' H/ a) C8 b0 N* d p" P3 q4 z) }# P result = x + y;2 O2 A* ]; W0 m* h( Q8 \. Z
break;0 f7 H, n! Z5 q2 h7 _
case '-': % o, R5 n9 T; a& T$ w/ T
result = x - y;7 Y+ }! W, U1 ]/ z( N7 T1 w
break;& A8 Z2 T- I- ]2 O7 h2 N! F
case '*': 0 r# P+ J% t+ [7 c0 R% K! c
result = x * y;, [6 D0 E, P$ B6 o
break;
2 c2 Q* x( P. W+ F. b5 x case '/':
6 d$ ]0 T) ?* ~# w# O if (y == 0)
' T7 E* `& a- Q2 h b- n- f {
. N- [% S2 i; |, v& @+ s printf("Divided by zero!\n");
$ D0 D' v( U3 A" L/ y/ e! U return 0;
9 o j! q3 m7 x }8 p. F1 y1 n- U, O$ S* o
else
: u8 V0 d+ g5 J& ~ { r+ w' i5 y4 a4 G8 n7 [6 e& E5 l/ A
result = x / y;+ K6 A) R; R1 D# R" H3 Z( k' ^
break;
* x* m3 g% u5 _3 [& S* J! I* f- N }
. @* c) ~' s9 G default:
; I' C; J& t, P# S5 l) I printf("Bad Input.\n"); $ y3 U* j# ?- C/ t; [
return 0;1 R6 }9 s! |4 R3 k7 j1 `* u
}4 m* [. i4 C1 H9 |* N
return result;7 t( f: ^( Z" d3 ~2 r. |
}
6 {. }2 r# m( O4 B2 u6 `( Q! W; B7 L5 g% S1 w+ y3 j- u
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
9 ?% `. d! p! O8 t4 c" y1 T: f9 F{
9 b0 l1 Y' Y6 L3 d Stack optr,opnd;* S4 t+ q" O7 m P) f
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;$ S3 s1 u) `3 |/ g
char c;
1 s8 i3 N, x+ J* v* k6 F! t char buf[16];
* {! E( r0 @4 U; b c* A int i=0;
# Q) I/ |/ K% Z+ f
2 p9 q2 f+ `1 s, K/ G InitStack(optr); /*用于寄存运算符*/
, F$ q e, c$ C1 w( v& Q+ b3 k1 C InitStack(opnd); /*用于寄存操作数和计算结果*/
0 Q; z; p1 T0 [- n4 R- C memset(buf,0,sizeof(buf));: S& l" X( P! E G+ [6 v* i
5 u5 @( A$ a) e9 L+ E/ J
printf("Enter your expression:");
5 W8 `* O1 m- @% o
& F5 f; L0 i- x4 m9 t+ H- k6 c opr_in.ch='#';6 Z9 o3 n; g% M% I, J. w
Push(optr,opr_in); /*'#'入栈*/) m, a: o$ @5 r' R+ R
GetTop(optr,opr_top);0 h9 m+ Q) h6 N/ G t0 \
c=getchar();
$ }2 W8 V! T9 v) { while(c!='='||opr_top.ch!='#')( ~* D5 C0 ~4 A! s6 z% S0 H
{& F7 G( U( l/ _! Q+ `' |
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
+ {$ X3 d& b0 V" K9 _& Y, s x9 { {
7 s$ @# E, {* S' l; z/ ^ buf=c;
* e$ g/ E, U7 h; b i++;
# m+ r2 I4 h3 z+ \4 U c=getchar();
( T" a/ y% r- M: m! N }
% c0 i3 c' I, U7 p# M5 v else /*是运算符*/
+ \4 C# T. J6 A @- O- J8 i7 _ {
8 b$ ?7 G0 P, F1 i3 X' Z; s buf='\0';* j. g# F- D" r
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/7 ^; c) O# `# Z j- q
{
7 ^2 v# v/ T% P( q/ V1 c opn_in.data=(float)atof(buf);$ @' h( M+ `: T
Push(opnd,opn_in);2 j; X& n2 |3 s/ q
printf("opnd入栈:[%f]\n",opn_in.data);/ q, c# [! p& W w' g
i=0;! X! o+ S, O$ ]6 \& a
memset(buf,0,sizeof(buf));/ O+ ]6 U: V- E9 P* L" y0 v; W& [: Q
}- x" G* o% ^ V
opr_in.ch=c;
( ^3 H, f* v) E+ i2 Z switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
$ i9 I8 M* \: u4 o& k {, Z9 {( \. n; U, C
case '<': /*优先级小于栈顶结点,则运算符入栈*/) W5 Y U' N }0 u k
Push(optr,opr_in);
3 S2 r H$ P/ p5 v% v printf("optr入栈:[%c]\n",opr_in.ch);
( L$ g+ N& s k, @$ h/ k, o4 x c=getchar();
5 \8 |( _" `0 N) _' Q4 A break;# A0 Y& X7 S: c
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
8 l! |( F; T. w Pop(optr,e);
/ c2 _/ L7 _# }& u1 ~4 g printf("optr出栈:去掉括号\n");' d3 u8 {+ G1 R1 J
c=getchar();6 x! M0 y0 ^ z( _8 L0 [" g, N
break;5 n; S# ^& T, |0 b
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/$ H8 z& U/ `0 R
Pop(optr,opr_t);0 ^: e# H; R3 d8 B7 R; d) A
printf("optr出栈:[%c]\n",opr_t.ch);
: ]7 ?, U6 [4 `3 r! [( ? if(Pop(opnd,b)<0)/ {1 }* l. s% `8 G( U
{6 O. k7 `% B: g1 T
printf("Bad Input!\n");5 _' } q- R2 I. ^# J% Q
fflush(stdin);' I. K1 P( D2 z8 B
return -1;
8 ^, |* \- u1 ^9 e* H f& }3 ^ }
4 c6 o5 D9 u7 X3 j printf("opnd出栈:[%f]\n",b.data);) l8 u$ ?6 B, a& K
if(Pop(opnd,a)<0)2 E4 f7 o9 y$ J' w) X. f9 s
{8 u5 r1 q4 I7 M# a+ ~8 }
printf("Bad Input!\n");3 Q: q7 s: e" f1 t
fflush(stdin);5 [ V8 X4 W, w; p& Y! f
return -1;& X# M+ g7 @0 {/ C
}/ e- I l3 p$ l, F
printf("opnd出栈:[%f]\n",a.data);+ ^7 U! @' w6 }$ K, X6 p
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/. m% R* ?$ U0 T5 ?! `$ _
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
/ o! U3 [: r( Y) F2 f; t5 ~5 y2 W printf("结果入栈:[%f]\n",opn_tmp.data);! f( s! h: ~- c$ f6 b( k: j
break;
7 ]1 G* R8 ?9 \8 u8 {/ z4 L }
& [$ p+ K! b4 N J4 w/ h9 H2 q1 R }8 q3 ^1 [- I6 i z- ?5 T
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ , a; m y3 d, v2 R0 h# l x
}- T% {# \" R& u, x9 v R
GetTop(opnd,opn_tmp);# |7 `4 z' S$ X( k; K4 D' s
DestroyStack(optr);
; j$ h! l. D/ l: W$ X DestroyStack(opnd);* u6 i( @5 f T
return opn_tmp.data;
/ B- p) j8 n9 K) B5 b3 g}) L. q: L/ `/ V* j) ?8 L2 y4 _. Q) l
& k! B$ G/ K7 ]8 ichar *killzero(char *res,float result)
. y( u# O- m2 h4 y9 h{
6 w9 @* \2 B. b8 X' S( ? int i; T' x) X! I$ u# C1 z5 E- e: a) L7 u
( R5 @6 n9 p8 F" ] y
sprintf(res,"%f",result);* b; {% Y$ Y/ k6 Z0 y5 y W8 p. }
i=(int)strlen(res)-1;: C) o4 V/ X8 v2 E- l! H- P$ B
while(i&&res=='0')
% u5 I1 c) C0 w3 D/ _/ V3 O6 X {, W3 T) n+ o$ X
res='\0';
, }! m' h0 c7 \ i--;* I: A$ H5 C3 H: @
}& o3 I/ j, k% ?: f' o2 ]" U
if(res=='.'), v# t8 Q% D* }4 N ?
res='\0';, c! A6 T4 ]6 m* w: U
return res;9 \4 F8 W8 b# I
}8 u9 Q# l$ S: S& F4 h
9 z$ g( U7 Y8 O* E4 F; U: x$ fint main()6 O7 j' O; j; G" |" g- o4 x$ j9 C
{
, Y4 x: r. R9 @$ i5 x/ C+ ~, g* A char ch;
$ Q7 [) I" b6 S7 S5 k7 l char res[64];9 r3 s9 f/ ^& s, J
float result;) H9 N/ D2 i5 ]6 M
while(1)" p$ \1 b8 I& ~5 P
{# c x+ A1 ]4 I4 Y* ]- @4 Y; l5 g
result=compute();
6 e" n0 D6 n+ S" J; ^" A printf("\nThe result is:%s\n",killzero(res,result));
1 W$ s$ f! d7 b8 Z printf("Do you want to continue(y/n)?:") ;
* _! F+ q: A% S( E) Z5 P ch=getch();: I9 D; f/ n! R7 D, q
putchar(ch);
; Y% |; [/ g# \+ C1 u4 c: o if(ch=='n'||ch=='N') ^* \1 m9 j+ d
break;% b' s( A( k" E. e* w) p
else
: c$ r8 q4 y2 g2 a system("cls");- n% P5 `- v# u& v% A$ A1 u" a% h
}4 `. m# Y& c9 w+ q) F4 m
return 0;
2 p& l# f" L# b( K2 l1 _}! [5 A6 M9 J1 @: y" M5 E! a
& c) a0 R" A5 P% p5 _3 J* y4 s
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|