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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
$ J% e0 U( X/ ?4 Z5 V1 {, X+ P" J程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
. Q& K) i! R i6 R! D/**************表达式计算器************/
, n1 [# v' h( ]#include <stdio.h>* t& c: e( o {4 Z/ D% G: ^
#include <stdlib.h>8 G2 o1 P% t, G/ Q8 V1 N! H
#include <string.h>
; z) S0 u% O* @3 g#include <conio.h>4 c, _4 _. R# V' k
#include <malloc.h>9 i2 K- M. P% }: m. @
0 x6 }! `6 K$ b& l, d( a* Y- Q#define STACK_SIZE 100
4 [4 ` [3 W9 L( C8 u* j#define APPEND_SIZE 10
6 v$ X H* d, a( [- B
, L) @# p5 ? F1 estruct SNode{5 k. B4 T7 ?: B; p
float data; /*存放操作数或者计算结果*/( N2 b: A- f( Q+ U
char ch; /*存放运算符*/* e4 {. a) z+ H, J0 M( N4 v
};
( o5 ^$ }) I+ u( w# q G# Q6 s1 e3 T. B
1 V+ ^( |4 v# ]5 xstruct Stack{+ g9 H% p! D6 I4 j: \: E
SNode *top;
& K4 O9 v0 b1 h" s8 B7 t T9 D/ i SNode *base;' a; J. E5 S4 h" C, ]: R3 O/ s8 ^0 H
int size;# l1 m+ A% I& d6 C/ Q- E4 k. F3 W1 q7 i
};( G( \' c+ x4 w& p H3 G
/ ?* Y0 Q+ L1 K; L4 u1 K) q
/*栈操作函数*/3 b, B: _* i' T! b: w) }
int InitStack(Stack &S); /*创建栈*// K4 E/ `( B5 m( l
int DestroyStack(Stack &S); /*销毁栈*/' p" n$ b( D1 C) v
int ClearStack(Stack &S); /*清空栈*/$ b# I9 ^( u8 B1 P, d# l
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/- w7 l! g, ^% K& N+ k& t" A' @
int Push(Stack &S,SNode e); /*将结点e压入栈*/
9 L/ ~: {9 T% {2 ]1 Mint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ t; c, ~& T( e/ x( m! @
: V9 |$ Z6 g' D1 K
/*表达式计算器相关函数*/- u4 X2 \' N) T1 c: y
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
. n( r$ T4 ?7 R8 d6 bint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/) ^8 B9 p- J) K. e8 I7 ~' h6 X# P
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/1 j. r) b* C- Y4 z8 L
float compute(); /*表达式结算器主函数*/1 h) S; q" w6 K7 l' y5 X
char *killzero(float result); /*去掉结果后面的0*/ ' T' |6 A4 F/ m& I9 Z8 Y7 z I
! z- z; ^! p8 i1 ]! U4 E8 Jint InitStack(Stack &S)
: z# s) w5 D3 [6 K1 N{
5 K' J5 O( G0 t8 ^' S; _0 A S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
3 E9 E, Y& d( F% f2 v if(S.base==NULL)
! `/ n; K2 G; O2 @ {
1 p; ~( C8 `# x# u3 R. v& F printf("动态分配内存失败!");
$ h* w) L5 Z( V% F" N return -1;
0 T4 @" L6 j' T- L) L( C: z! f4 \8 f }
4 W% F3 u" {" Q$ p5 s% x/ ~ S.top=S.base;
; @: T. ^& G& M S.size=STACK_SIZE;
0 a& [% l& T4 n; ~2 I return 0;: @9 v: s% j. g( |3 v
}
7 |4 t# P" N# P# E% u% T
& G1 e0 t$ x7 u8 T3 Lint DestroyStack(Stack &S)
+ {) p/ v" J4 F5 X M" e2 U; q: f5 V{
6 I( K4 Z0 j1 W free(S.base);
' R$ _/ z/ r9 R$ t' b return 0;
; y; \0 T+ M% C7 l! q# R, V}
1 p5 k7 R8 c) M7 b6 j. E |
. d7 t P: e& ], ~2 oint ClearStack(Stack &S)
& L( J' e8 w/ a( x* m( @! ?{2 G9 @7 Q: O! @3 e9 C* V0 W
S.top=S.base;6 O* o! x) [6 p6 k+ E2 v2 F# y2 G, P! N
return 0;, q+ e: d4 ]1 C% }7 w0 ?7 h
}2 h& x+ c( [6 [' E5 H
/ {; r I; @, ^- _6 p& N$ g5 H3 I
int GetTop(Stack S,SNode &e) [! C! Y8 x) @* x: X
{
7 p, e. v4 d1 K4 v* m8 s T if(S.top==S.base)& O! E/ g7 e: K# W0 d5 x& F* x
{
% Y4 [- U: E" Z2 V$ b printf("栈以为空!");& I( ^9 E+ t1 a4 K, U1 Z
return -1;5 W7 p8 e! b) G- i
}7 \+ ^2 P- w J R6 \* K
e=*(S.top-1);
- i& |4 E U1 k0 F1 M8 y return 0;3 e" L* X( w* g3 I8 W9 a' P, P
}9 V6 d C9 o6 B6 @( O( X+ O4 g. k% B
" m! b' N0 ?% m+ M( xint Push(Stack &S,SNode e)
7 B& ?" @. l7 h, }' C{% w+ D k: o/ o* r' @- Y3 ~ `
if(S.top-S.base>=S.size), u7 p S8 |+ ~& l b x
{6 d* ?6 j" X4 c. T
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));7 g5 C3 ~4 b3 z; v, Z, ?2 Q4 o
if(S.base==NULL)
6 H, f2 n) H/ M4 h {
9 V" r9 b- [% Q g printf("动态分配内存失败!");. p; z4 Y4 t2 ]. }
return -1;
) g( @9 e* d9 `& r, T) @6 M0 ? }
& `, u, h4 N7 T% n6 c. {* z, C S.top=S.base+S.size;
[$ O& y7 ~2 C: e; e S.size+=APPEND_SIZE;0 P" D. B. t: X
}6 y9 q* o0 L$ ^4 r
*S.top=e;: i) R r. b9 D) u7 [
S.top++;
2 C& ^- D) e8 ]0 J, W7 K return 0;
) M# s7 U1 q) s9 x- W. ]3 h* Z}
* ~# ~" Y6 Q5 P9 n" G1 G, Y2 [# r0 }8 i& ~
int Pop(Stack &S,SNode &e)
6 O# X `# v/ M$ i) {{' J6 c& K' |- z7 P, `- C) U
if(S.top==S.base)& U, d* g3 @" ~" Y8 a# E
{ f9 ^. t8 `6 `& H" V0 ?! X3 u1 p t% ~
printf("栈为空!");. B! ] k7 j, t2 S4 I1 G
return -1;- J/ d D0 t" I) t& H- F
}
0 X3 p1 z' D' | e=*(S.top-1);1 B! D* x4 l8 i4 a- v0 p' B3 E& b: H0 {
S.top--;
* w, L( [- H r* P# m: X return 0;- a: L% b/ ?8 {. V ]* R
}4 r# Y! o6 g+ d+ ~
# ~2 L0 ~, e+ Vchar get_precede(char s,char c)
. n# ~: R, n. A5 r8 F{
7 d" W5 P* ]* }7 o0 E3 i: O1 H5 z! A switch(s)
1 p7 O7 H, ?( X8 X5 v {
2 Y) U7 q2 {! j+ a" K case '+':
, O; q5 A6 l/ j; V case '-':
! S, q9 ~( G' d: p if(c=='+'||c=='-')4 ]6 f3 Q+ J! @. N
return '>';
* \# k* Z8 m) e+ k else if(c=='*'||c=='/')' I1 M$ X/ ?0 i2 q" C3 E- g9 q
return '<';
1 t; H; ~: {+ [$ p: G else if(c=='(')
% ]1 ~ e7 x, `) ]2 H9 D4 J return '<'; }' ~. T& b( K) d) M
else if(c==')')- @& B U S% a& v; N2 b N/ @
return '>';
, X. i" e; T& [4 O else % ]3 C5 o+ q' ~
return '>';0 e9 \4 h4 a8 w
case '*':
: ^) s, q' c1 {6 q& x& R case '/':
1 Q! d/ \) [- O k; H8 w0 W; @ if(c=='+'||c=='-')% a+ f3 H/ i2 V5 R3 o
return '>';
) E4 b$ X6 Z' a3 e else if(c=='*'||c=='/')
) Y5 V6 b. u w5 C8 d0 @ return '>';
' o/ y8 [/ _5 r+ n6 w" B else if(c=='(')
; T2 J+ p2 i; I! i return '<';+ x$ j! _8 V6 h2 V) F
else if(c==')')
2 D# z& f, T& P4 x6 Q4 P# } return '>';
" Q2 z8 k; i# c& h, E2 T; P8 M9 }3 [ else* T2 |6 H8 h$ D1 Y$ e4 ]
return '>';2 @$ o* {6 B; K- q5 G2 d9 \* w
case '(':% E4 t0 K( U' E W
if(c=='+'||c=='-')6 I7 r* W8 h8 k) l+ R" P0 A
return '<';( E/ P; X; K: ?
else if(c=='*'||c=='/')' e; N' e8 w, ^, x' ?- _% |3 s
return '<';9 ^9 K9 @7 b: o( a+ M4 w+ x
else if(c=='(')- {5 y; s0 m9 I/ X, l8 W' m
return '<';- N, h) I) E0 p+ o
else if(c==')')+ A3 d( w0 k4 g; Y& V! r
return '=';
1 P, I4 b' b' g, R2 C else8 d3 }6 Z" B% C1 ?) D
return 'E';3 r( e q+ h( h6 o; J5 l& W9 c6 F
case ')':
* H1 v9 U( `9 Q" K if(c=='+'||c=='-')
2 b0 `# O$ {8 d/ U: F" \ return '>';: G' {8 r( w4 M. G$ ?. Z8 o
else if(c=='*'||c=='/')2 h2 ~* I* @: @! o6 m' u8 h
return '>';
' m. Z1 j4 l% [. b9 J else if(c=='(')' N+ `1 B0 F. Z; C% d; q% f
return 'E';
" q) Y) @% _+ c+ `$ m0 |2 y else if(c==')')( g/ c1 \) i F2 d
return '>';3 L3 N' \# h; K# V+ K
else
/ L% C) p, K( |0 I' u7 w4 P return '>';( q" n9 K" z/ L) R4 V8 h$ y
case '#':
& M! V# T9 j b if(c=='+'||c=='-')0 l% ^; _2 p1 D; n9 f* x
return '<';6 M4 n" N9 O4 ?: T. {7 }/ u
else if(c=='*'||c=='/')# u. Z) |$ n# ^
return '<';$ F4 U* P; R W- w6 A6 D4 P7 p
else if(c=='(')
0 t9 D. f) p" l! D return '<';
3 Q3 m2 @& i! c! w, b else if(c==')')
* V7 f3 G) m+ w% G return 'E';. y; C9 x9 |* ?) d* h
else) Q, L8 m3 K, `; E8 n
return '=';
+ [, y6 _* X, h4 ~( r# T" W; B default:
( c* z6 z, k, w: E p break;
/ o2 J) }9 u! _7 i: s } A. f S7 z, j* }0 t7 D$ h; P
return 0;
6 B4 y3 r2 H% e) L}$ A; e6 A7 ~. f0 t0 j! R
8 I; `# ^7 r/ D9 G6 ~- x2 s. Q
int isOpr(char c)
6 H6 I, L* x$ w$ j; j1 K9 @7 b{1 C- d/ g0 O! K: I0 E
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='), l6 O/ F; q3 w
return 0;
/ \5 x' B+ I' _ else
6 W! h6 b" g4 D; D: K return 1;$ e+ U# f$ s# A+ P$ N; p
}
6 @' n/ c/ z: w ~9 @1 ?6 B2 d5 i9 N' a8 ?6 |9 z
float operate(float x, char opr, float y)
+ h' W- h6 e) |2 P6 \! _$ c{- D- _5 w) Z: L
float result;
; o f0 }. X4 h5 ^& ^ switch (opr)
! `1 P0 H; L7 V. A( Z- \ {
1 {. B& U, n: @& ~8 m0 y' K% _: h% M case '+': 6 R6 C, p) l, A$ A5 @& o
result = x + y;
4 r( [3 X5 d' u+ a7 S: p break; C# o! s' ?6 ?7 N
case '-':
1 l1 ]6 P0 X; c, ]; L& l1 @ result = x - y;% q7 g: B! `' a% {+ U" K" r
break;" D! y0 O0 J8 G7 {( q+ L" W# _
case '*':
" F; ]& G1 D* j2 U7 k result = x * y;
9 P4 e$ } r; V$ Q. W0 ^4 Z break;
3 m7 ^, h4 F k1 Z case '/':
& H7 r6 z4 \- r( l" z/ c if (y == 0)
, L( [/ V* g; U5 P7 l {
) l2 N' s# d0 ^* Q) Q& s4 Z5 J$ q printf("Divided by zero!\n");
1 z5 m& R6 }0 _" u# K return 0; i( T0 w4 G2 K$ S4 r
}
5 V e; x! z. d* y9 a M8 Z else
. U, p E" [ D1 F1 l0 \ {
# D1 s# z, J/ ?1 h, F result = x / y;1 p6 ?' u0 K/ l4 E( n2 i
break;5 W- [: A; a" v$ O0 Q0 h* `( z
}
: R$ b. p2 B* N" A! s2 [ default: 6 d) g6 ~/ a% f! i3 N) {8 [+ v: Z
printf("Bad Input.\n"); 6 k: I* z# d# Z3 o* x
return 0;
6 {9 Z+ {9 F( d" M- N- I6 `4 [ }& `0 o8 i' a7 ^
return result;
: Q) I* c" M: c/ E" r} 3 k. \- Z; x3 y1 f- T k/ m9 ^
& _4 k. y' Q P) Lfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/+ H2 S- s5 m5 K! N
{: ^' Q/ B- T, r8 `
Stack optr,opnd;7 r, \% v/ |) E' v9 ?3 F
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;0 P& y/ U; E/ z$ C( y
char c;# L2 @1 u' {8 J2 O1 m% x
char buf[16];
. {3 a4 h3 u; R5 Y+ b" n& X7 q int i=0;
/ e, Y3 m# _$ I m! b8 }/ e3 e
InitStack(optr); /*用于寄存运算符*/1 A7 k( W4 h2 m' C* Y1 G, @- ~
InitStack(opnd); /*用于寄存操作数和计算结果*/
9 j2 l6 Q8 @( L; N3 {. a memset(buf,0,sizeof(buf));
- Z; D' ?: ?9 G0 z
' q* \# P$ e H0 f" r. { printf("Enter your expression:");
2 Y) c+ ]2 j2 S; f& I
+ {( S* q9 P! ?3 W6 _3 \" ?$ d opr_in.ch='#';
9 {2 `1 U. s1 x6 F% G+ P M Push(optr,opr_in); /*'#'入栈*/: h" d) Z! ^ j- U8 q# }
GetTop(optr,opr_top);
6 I; k% H0 i% m3 P7 k6 X c=getchar();
' x9 ?9 X9 e9 u% l1 c while(c!='='||opr_top.ch!='#')2 l; i6 R$ \7 T5 f$ s
{. K% i/ u9 [% S
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/9 t8 {1 e6 ~0 w1 a7 X" P8 ?( p9 r
{; t" |( U7 @$ U: R4 D
buf=c;
$ @' M# c7 v( h7 [* M i++;4 q. V) p, O% R
c=getchar();- l% D7 m$ K; ^: j3 F' }, Y
}9 m' Y5 h1 v- X
else /*是运算符*/0 _- E" T: `- `5 m
{( |8 J% H/ o! w# Z; X
buf='\0';
: V' ~, y0 l! R! Z4 H: v, d, S( E1 Y if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/9 D% U. t/ ? z$ i/ q
{
% x! g9 |: L3 h7 L, \6 k0 `/ B1 ~ opn_in.data=(float)atof(buf);
9 m6 S* a# d, J5 |- g+ W( b6 i! w Push(opnd,opn_in);* b( S' l1 u/ C: E8 k' d) h# Y7 F7 a
printf("opnd入栈:[%f]\n",opn_in.data);
7 @$ q5 n0 d- P i=0;
: ~5 [& N( X4 N! Q* S" h memset(buf,0,sizeof(buf));6 k; I& ^: t# M$ b. x3 k
}3 ^" V5 U$ d+ i6 y% f! I( J
opr_in.ch=c;
/ g. p/ R2 N S switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
4 W) T) g. _, ]2 N( M {
; ^% y% T$ J4 D# ]9 I case '<': /*优先级小于栈顶结点,则运算符入栈*/' c* B. T$ Y6 ?" ?! d* P+ g
Push(optr,opr_in);3 P( p4 D7 c7 a) W: n! V, M; m
printf("optr入栈:[%c]\n",opr_in.ch);
a! z. M* [: g y2 U2 ^ c=getchar();
/ H7 y4 Q8 K- w3 }7 T c break;
% A+ j9 h# L/ S2 a' y case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
* H. i$ G: C* A" c& r Pop(optr,e);
. z$ D3 U/ h" H) B }# ~: v printf("optr出栈:去掉括号\n");
) j5 b, O, J2 w( A, i c=getchar();
" I/ F u" k3 v& `8 i: N( ? } break;8 }9 U1 [0 F5 U \
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
8 H1 C7 [2 N% |4 x' z9 s+ u Pop(optr,opr_t); B6 o1 G3 L# }/ J$ g0 B: d% d# [
printf("optr出栈:[%c]\n",opr_t.ch);2 {3 N# `# o. t4 b7 U
if(Pop(opnd,b)<0)2 Y7 P6 s% U; k
{. r; O% _9 D; c4 k6 S9 E) @) `
printf("Bad Input!\n");
* ~2 ~$ S$ p* o$ Y9 p0 n- { fflush(stdin);
* s2 c& v' d7 x Y return -1;
. y5 G8 y; f7 z* A; v9 x) S/ v }7 g: v9 X5 Q3 U$ Y8 L7 W) B* S
printf("opnd出栈:[%f]\n",b.data);2 x5 S1 G) G& j! c1 W; G
if(Pop(opnd,a)<0)
% V2 W/ A, p! @- e" m {
, V2 p' j7 X* q7 L5 |: g printf("Bad Input!\n");& S/ ]( F! q; W4 n6 Q3 x8 a+ z8 l4 A q+ v
fflush(stdin);
4 e5 U/ ?% W3 F$ {" Q return -1;
7 f3 Q* T% ?5 F, P }& w) H, W1 c( E& j2 d, Z8 M2 S: U* W
printf("opnd出栈:[%f]\n",a.data);4 _# v3 Z( f& H V% }* k$ F
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/6 x+ F( O% ~7 w, z( ^/ M
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
" n! J1 N% L5 A; Q printf("结果入栈:[%f]\n",opn_tmp.data);
( N m" Z! S. e6 r) \ break; G8 Q1 @3 L+ \9 }; C" Z# j
}
2 U" R: ^, k; E; t5 ~8 i' [, m; Q' x) j }
6 x# H- n7 z; t# x( y& V" F. K GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ # ` S& S2 M/ U, Z, `8 Q' E8 C
}
9 s' p' Q, w+ y" X GetTop(opnd,opn_tmp);
' B; W& i- l; s7 a$ C8 o DestroyStack(optr);' o2 }4 T, t7 R7 w2 q5 d; `+ Y* q
DestroyStack(opnd);
v! d% o0 R: v! i, p1 H. W! j return opn_tmp.data;. M A) b3 G. V8 z6 H
}( n# g n7 o, x [1 g; c* B
, E: C2 f, r# B G O/ k8 n+ z4 Echar *killzero(char *res,float result)' W( R) C' S( H6 g4 f5 A
{
3 y$ d$ A9 X: f9 V& \ int i;& {# c; W- l: e/ Q0 m3 Z# [9 {; x, D9 E
8 W9 E& k$ t/ B* m
sprintf(res,"%f",result);, Y6 y3 ^0 c/ y
i=(int)strlen(res)-1;
8 v4 i6 r& ^* k( A while(i&&res=='0')
/ E, f3 ]* ~! f7 p3 y( w& s {; l& F. G! b' u- ]' H5 T. _. M
res='\0';
+ |, U: ]- v1 h/ }: c' ? i--;& ^8 D7 g% _6 I/ z
}
$ g+ o1 {9 K8 R6 A1 E9 }' T+ ` if(res=='.'); r! s& S7 A- N4 Q: y+ \ j
res='\0';
4 r0 M- Z0 ~) u( X# }' U return res;0 _# Z( a4 F x* \
}
- T$ G4 p e) N" _, L7 x1 [+ ?+ `0 \7 q0 {0 {# ]1 S( i
int main()
2 I1 n$ Y2 }* q% P9 D; @& i{( p) d$ F4 ^+ q& R
char ch;
: F3 z+ K' V$ A char res[64];, j$ K6 n+ ^. b! W; j5 P
float result;$ G/ x7 a7 o- a# {
while(1)
. g% i" m# }7 J( `2 } {! T( V/ |* m" J% t4 F
result=compute();2 D5 W; a* |& t( Z ~ @0 M9 H
printf("\nThe result is:%s\n",killzero(res,result));8 `8 X! j/ m A2 g
printf("Do you want to continue(y/n)?:") ;% ?4 y! q/ e5 C8 i2 V3 n
ch=getch();
. K% H) K! \( s) t, W: ~; S putchar(ch);
. W- y; z* k: i4 Z1 Q/ s if(ch=='n'||ch=='N'), @1 b8 v7 n1 u" b
break;/ D% y/ }! K% y( m, j# k& n
else+ P) Z) u% u9 p; Z
system("cls");
9 F* X' W7 z" ?- y( J }4 X' x$ }6 h: z" G2 Y( R- z
return 0;0 C, t- g1 K M- }
}: {& k( G. v* B
- @6 P" L* l7 \7 k
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|