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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.) b, t1 { }. e. v
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
3 |9 i+ n$ d' U/**************表达式计算器************/
6 `9 }3 Y' M: s9 K% \* @* D7 g#include <stdio.h>
+ r5 F$ ?# C' u& l0 a u' q#include <stdlib.h>
7 {! j1 I) m4 ?, v5 \#include <string.h>4 W- B' {$ l8 |( B4 n0 {% A/ {. {
#include <conio.h>' }- C. t3 p# X+ N1 Y6 o
#include <malloc.h>
! k4 k. P1 ]5 u/ r" _2 z; U3 t' ?* i5 R! s& c9 w! N* W8 M0 U& [
#define STACK_SIZE 100: W C7 m5 x! Y" X
#define APPEND_SIZE 10, J# q s' B# b' x( `4 T% G0 g
5 [( X+ W# H: ]/ b2 N1 Y
struct SNode{5 m6 H4 w4 T |- B$ a# m- C+ u
float data; /*存放操作数或者计算结果*/1 R/ O+ C( s3 i T
char ch; /*存放运算符*/
* K5 v* d& |, l. f( y3 e9 Q) ?# j};
% a1 Q& M. V7 {* A% ^
# G$ {) a" I$ Q) L7 k# {8 }struct Stack{
: p* `- |- ^, z SNode *top;& m9 ?" e. f: k' x
SNode *base;* z% ~: L$ ^; d' U' [/ e- U8 m5 p
int size;6 P, `. ?# }% `3 N
};
' @. `( G; [# l% E
; _ p& H% D& C$ I% o/*栈操作函数*/; g% v& r- K2 S& r- j
int InitStack(Stack &S); /*创建栈*/( i) `+ s. R! l0 H
int DestroyStack(Stack &S); /*销毁栈*/
) w0 T" ~# j1 w( J n/ }int ClearStack(Stack &S); /*清空栈*/
8 T7 f. D: S! Iint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
% [% j, \. \& Y' Y: I- X+ I& Rint Push(Stack &S,SNode e); /*将结点e压入栈*/7 [% c' T0 N, F6 y! m
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/0 i# h- ]- S9 ^; `/ J
+ ~4 b1 l4 m( E1 f; [+ }) i, Z' N' z* E/*表达式计算器相关函数*/8 K5 s8 D; n5 f
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
! g5 U0 ?0 t8 [: B) t. Eint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
( A& U4 k# O! x& u& ~* Ufloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/. \+ W" z) K( e) G6 v
float compute(); /*表达式结算器主函数*/' M+ K* L @/ f" }2 f- h7 r% u
char *killzero(float result); /*去掉结果后面的0*/ 1 o, d M5 Y7 |: ^1 o2 G% o
2 X. d5 O$ R$ g! m; f" Sint InitStack(Stack &S)
. P0 u5 `- C* a+ ?{
) z0 c( u3 W, _5 _* M& Y S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
" _9 I& H; _. {7 a) t D$ _( E if(S.base==NULL)
1 X4 M0 f8 P; T, h0 G {
8 X( {6 _6 T. ^# f" p: U7 X2 v printf("动态分配内存失败!");% l5 `! U u' [' |( V
return -1;/ C3 T9 U9 \7 Z A& }* b z; D
}
* X8 E2 Y( L- p- Y/ K S.top=S.base;) x- M" G1 f$ Z) E) w J2 |0 o
S.size=STACK_SIZE;
! V" L3 a0 r [9 _( e) `; h1 n$ [% } return 0;; F& j5 i1 j' D* s% A8 @
}
' j1 x' r! d. v9 L0 Q6 G( p) o2 w
int DestroyStack(Stack &S)
) I( I" Q( r: m! `4 p0 M{" w/ e6 u, u8 q p& _! Z
free(S.base);
) M* ~$ U) \$ P return 0;; k2 x7 K1 D4 y2 E8 h# w6 {
}
4 I3 m, K f8 ^
7 g* ?: z9 b- r3 {" y2 Dint ClearStack(Stack &S) z/ c# f) ~6 R. o3 a6 f v
{) D) v$ y1 f' [ h+ o. s# R! E" n
S.top=S.base;
% a( B2 j; O/ K# }2 N6 L |; l return 0;, H- F( z% ~ m+ r4 E
}
# }. e! K6 g$ C
6 ^+ p% }8 d! Cint GetTop(Stack S,SNode &e)
0 {4 C" q3 s# k{' g* \) B3 Q ?
if(S.top==S.base)
* G8 @% [# s7 ^+ l" M( j {; o" g! m- s$ @4 w9 Z) T) Z5 K
printf("栈以为空!");* J R0 V6 D0 }5 T9 ^
return -1;
7 X1 G' L5 S8 y8 W& f }* p- L$ F5 {: M( _- y7 f* l
e=*(S.top-1);
1 b7 y/ \& W. Z6 h* B3 s1 O" x return 0;+ C" D- Y6 w/ q0 Y2 }
}
7 c9 ]1 W Y+ }1 I- n/ j5 g" ^2 e, f8 }+ ]1 {! s- e: r1 o. C. W- Z- [
int Push(Stack &S,SNode e)0 B& P Z2 o0 q
{4 O* L( D$ I# ~& f5 z: w S
if(S.top-S.base>=S.size)
5 S- g, ~8 t! Z: \/ a- w' v- V { r8 l. y5 \0 X; o
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));$ h' P% Y: j* \% Y0 d- G
if(S.base==NULL)
: ^9 W3 L+ b4 [4 i$ P- m {
" }1 c6 u: O5 Y0 Z0 B/ _$ x printf("动态分配内存失败!");
: j4 w$ x: W |! y# ? return -1;$ G1 u9 p2 i% H3 x5 o
}% V7 ~* X$ E4 ?6 A3 h N
S.top=S.base+S.size;3 @: F, t' H% W. E) z# L2 B1 D
S.size+=APPEND_SIZE;
; I! b& u3 h5 P5 ^, b }. @5 I& Z- g% j9 d; ]4 h
*S.top=e;
6 j1 [- C( O. K! H) W) T5 {5 [" u5 `1 } S.top++;( I# S* k! e/ O7 }
return 0;
9 P1 U: K. v* G; ^4 c* \}% y5 z' \9 a" S6 m+ ?
y0 @6 I3 I1 S/ b: {' j9 a6 R
int Pop(Stack &S,SNode &e)
. _6 s1 X" w: y4 y) y6 w{
# g8 K9 H( E3 y) |1 c: a. g if(S.top==S.base)
! d6 `9 i5 n/ ]3 M$ F) a; \6 F( V, M; z {
3 D; J2 W& I4 W& g printf("栈为空!");5 ?% d0 S, O* Z
return -1;6 I& \& G' A9 a/ `5 M. h
}
# O2 ^, N j8 n. L2 M' L x) U! F e=*(S.top-1);
, P7 O! `* x6 E, S, f S.top--;& P( E# y# A, a1 g* n8 B# m
return 0;
1 z+ s9 D9 ^; e. g% s}7 [2 s0 D$ q q; p+ j# c4 u& x }
9 ?3 |3 }/ h6 \5 M; \, b1 ochar get_precede(char s,char c)* t+ J2 t! G: t$ T6 g9 I
{/ F9 C3 p' U; ^: M6 E
switch(s)
E! O$ M, @9 v9 o {
! b' a U x4 y @- P) Q4 ~ case '+': + y6 F! w: r/ H# d5 J. n$ d
case '-':
& J' B* \/ [6 T( u, |1 J% e if(c=='+'||c=='-')
9 L, i( f& ]4 K return '>';
7 {7 e% Y" _: R+ ` else if(c=='*'||c=='/')
* W, t8 y+ j& Y8 m6 y* M* r return '<';$ [! Z! J, Z4 C/ f& ]2 m
else if(c=='(')
, V- J; V: k. ~, L5 O return '<';
. ^( [5 p) J j4 W2 {7 y7 I- r- _% p else if(c==')') m' n( k- w$ Z9 A. o
return '>';& m6 f% I5 r& Z, b* l- W, V0 c5 I- [. |
else
* u* h+ `$ A) u" Q: F B return '>';$ w/ D4 y- ~4 y* g. `
case '*':+ d0 s+ U! q$ W- K# n! U
case '/':
+ _; R* d, R: f9 \ if(c=='+'||c=='-')# m7 e" ]+ s8 _& Q3 {$ b) W8 y! x
return '>';% w) V) f# A- B" n" ~! \1 e* l
else if(c=='*'||c=='/')' f- p2 v+ V8 ^: h4 d
return '>';0 M9 x- }# r4 y% N3 C8 D
else if(c=='('): `* q+ _% V* T1 L
return '<';
g6 @, W) W/ v2 C else if(c==')')
6 U4 |+ M. W8 ~! W3 j return '>';
' a! K K5 C4 C+ ^$ I) X else
% V2 q( I5 r2 R9 K return '>';
- H* k# N, e" h! r, t% ? case '(':, R: {. ], E/ E: o) [3 p# s
if(c=='+'||c=='-')2 l/ ]. v2 H+ }0 v
return '<';6 C3 R8 M7 [) l+ U) _
else if(c=='*'||c=='/'). q4 b' g4 d. N" E& W& l f9 Q
return '<';' M& l7 t+ z8 V
else if(c=='(')/ @; d7 {( y) [; q4 ` L3 e2 X" ?
return '<';
( I7 f$ U, }# k( F$ w else if(c==')')
+ W8 T- \6 j8 r! Y) i* n6 a; e return '=';
& _$ Y7 I' t) s9 U% p+ f else
" @9 |( }5 @' o9 @ return 'E';! t! H$ d& @3 i1 X6 T. E
case ')':
3 x R; b' I2 c9 ?( D4 s5 ~- q if(c=='+'||c=='-')' l8 ~ a" c' k4 |3 k/ a' A) M) ]
return '>';% }$ K" q* ]$ ~- k5 J7 `' {# W; T
else if(c=='*'||c=='/'): h! T+ B2 E; Q' Z
return '>';% t* P) q, o0 i6 u+ U0 B' H
else if(c=='(')
' ^$ K! L! r2 u7 R9 c% \; D return 'E';
1 r5 b" ^7 |% k- p6 j else if(c==')')
) s, D, R; y5 y4 X# O- u return '>';: p1 \4 @) @* s9 {: K) q
else
; d- D% ?" R# b8 ^) [- y4 L Q return '>';
1 l- P3 E- Y9 E% i7 O case '#':% M* n& e- b+ l; ]8 C' C
if(c=='+'||c=='-')( S5 ]/ z/ E6 C8 ^" p
return '<';$ E8 U* `5 U/ V# P
else if(c=='*'||c=='/')
) z# g0 F" p. C return '<';3 |8 i: o6 o2 A7 P! X
else if(c=='(')
) D4 D4 u m* N* ^ return '<';
% B. d8 u6 @$ C& }; b3 S' A else if(c==')')6 I: m6 ]: j! _5 V( l5 [
return 'E';
5 H0 b" C& d# V else$ w/ S1 u `: g1 @
return '=';0 t+ |/ I7 j6 m9 c+ U" d( L5 t+ b1 {
default:
) @# K% n. R# q. D break;# u: ?! }! |' v. t; `- d
}
- a6 ?% E% p N: Y F& `9 \/ y return 0; * d- ^% P* B& \+ A$ o d! P/ r. u
}
* N, `! C6 V0 a- X; `) D
4 }5 B$ S( R7 W) y, w) f) r! m |int isOpr(char c)1 l" U) ?( C* z, _$ `0 |3 T* U8 I5 b& ]
{
+ [7 \% L9 s f0 {$ i% [ if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
9 A) v% `: U' p% V) f: L: u# R8 h1 K return 0;( N" R6 T* m; B& F* n3 r
else
9 B. ]% C8 J6 y( l& c: y return 1;7 y7 L* Z, B5 t- a
}# u$ f% H- c2 i' }6 x5 u% s" [8 a: U
' N& K3 e8 G g: f# Yfloat operate(float x, char opr, float y)! E# f5 f3 s# _
{
5 t+ i- V. m# }; M4 y float result;1 _6 d" {5 G- Q, l, T& o [
switch (opr)
/ S7 X- {/ L7 H3 E {
+ e, @* }" a9 | case '+':
# \& q3 X) ? q* y* G% D result = x + y;2 x+ Q, L& E, x1 A0 c, z
break;' L' {$ \8 Z' \" R- w
case '-':
# |3 p& Q# }6 w2 p: z% Y9 ~/ ^( x5 M result = x - y;
" k, T( ]( r' n( t4 z: m% {: h break;
' D5 W5 M) |. x X! o; N) d case '*':
& @4 O3 w2 O; l' r. Y5 O( J& l/ b+ p2 [% { result = x * y;# e( [& O; D, ~' C: R5 h
break;1 W5 J1 n0 j6 d
case '/':
; p; b! y1 P5 t if (y == 0)
. h6 g- ?/ A* p* K {% M5 c; _6 R( n9 X _
printf("Divided by zero!\n");5 w5 a/ w9 z2 H
return 0;
' g( N1 K2 {7 I; A }
' g! ^4 I" S' J3 O9 i6 X& Y6 d: P else
* |1 `0 @* J+ V) S) V$ V {
4 I2 ~: m& Z7 T* S4 a- g result = x / y;$ f# V$ k9 E h8 r! {# q4 W
break;% U( d8 W# p( {; S/ c2 V
}# M- s. _+ w x
default:
, F) l z( h- I+ w printf("Bad Input.\n"); 0 m _) W- {/ R3 n; c! N, ~( O
return 0;
# B/ m# _0 `+ h& x4 ~% B }3 P# J* E( Y/ q" z/ @
return result;2 B8 H( |" @& n" V
}
3 O$ f; o' E1 U; D/ ~2 J
. p* w, ~. s: X+ a+ Afloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
! L* e4 F k+ P8 n" `{" n j; P7 N' w( l& g. d5 Y0 M; V
Stack optr,opnd;
* |7 `0 M' V) k4 E+ k& \ struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;+ G# w2 M \" m5 f! W
char c;
, n) r; K1 I' y' J; f char buf[16];
2 C# ]0 h) t3 ` int i=0;
) l, w! x- a4 X* c$ a) V4 Y. ~6 B
, B) t, I8 Y t3 E9 ~2 y$ N InitStack(optr); /*用于寄存运算符*/( W( g. a7 f; I3 h
InitStack(opnd); /*用于寄存操作数和计算结果*/: \: N, v% e" H
memset(buf,0,sizeof(buf));* }/ O9 W8 U4 C7 J
+ ?+ [) L# D( c) \( D& t printf("Enter your expression:");
. S9 [5 M' [! R
. K8 y8 s. V4 ?0 B2 N. G4 {5 L* P opr_in.ch='#';% X- S$ Q& D1 V( }3 t
Push(optr,opr_in); /*'#'入栈*/
8 ^$ F9 y" K$ { GetTop(optr,opr_top);( `0 t; X% v& U9 W7 H
c=getchar();% U3 V( v2 h/ U0 V/ c
while(c!='='||opr_top.ch!='#')$ s; y! u+ Q# ^) f, A" u
{
/ r0 j: c5 l( _& w6 A1 V if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
1 P1 d, V; f& L8 k5 m1 c( N0 |$ Z# N& B, m {
' H+ |; U% v7 @; j" A7 ^ buf=c;
/ N" s0 ]+ \" M3 X$ D i++;& t" \3 X& ?9 Q) |! l% Y' U
c=getchar();
% f; u$ l6 x1 O3 H) o# } }( o! F% l6 o6 f% ?5 o
else /*是运算符*/
( `9 Z1 y) L Q% C1 N! n {( w3 E4 Y7 o1 N/ V
buf='\0';
* s! f% i3 R9 n r; u$ o4 G+ w7 F if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/! ]3 A. _( g4 X' {
{
' j3 C6 j3 Q( _+ a6 U# w1 M opn_in.data=(float)atof(buf);* g) Z/ r8 l4 l* J* y, ^1 u
Push(opnd,opn_in);
* k& j& n7 f" y printf("opnd入栈:[%f]\n",opn_in.data);5 W' R" I+ C6 N- |) _3 T
i=0;0 w! a& q0 o- w* _* `
memset(buf,0,sizeof(buf));
6 Y6 w0 `. a h; x. v# u }
3 \* u) }* a; h5 z1 v$ [7 E& Q; D, u opr_in.ch=c;; Z4 K8 e6 c6 {' @/ Q! ^) z' B2 r
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
/ N( n1 C, m8 E: x" Y6 t5 g% m {5 b; m x' Y+ m# z9 W
case '<': /*优先级小于栈顶结点,则运算符入栈*/
- i" \4 b! U4 H* u' P Push(optr,opr_in);& d5 t% Z9 ]7 q
printf("optr入栈:[%c]\n",opr_in.ch);1 T+ F4 J' T. Z9 \' Z$ S& e3 Q
c=getchar();, `9 _7 S% `2 w: r6 [6 S
break;
% {( W) K( F* B' x Q8 E$ g+ r case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/# R8 q- d4 B; }2 V
Pop(optr,e);
( a0 |. ^( a7 K printf("optr出栈:去掉括号\n");8 i: w" f/ g# q- ]4 I# d
c=getchar();
' m- i. t- g' w4 l break;
6 v; p- D( t: G% G) N case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/6 S/ _& \ W* _$ J* [, C7 O
Pop(optr,opr_t);
5 q* X3 ]4 w8 ~0 G printf("optr出栈:[%c]\n",opr_t.ch);3 k6 n8 R0 x# l
if(Pop(opnd,b)<0)
" }+ K: {4 {+ n3 M! [( B6 w {" S1 |( y8 J, P' X( |
printf("Bad Input!\n");0 [3 Z- q& o+ ^
fflush(stdin);
2 \4 y# \" ]1 i- A$ k' d2 z6 _1 u return -1;
; [" P* o; U) }# T, H }0 `) _, k3 B# a5 v
printf("opnd出栈:[%f]\n",b.data);1 _3 @+ y' l, I
if(Pop(opnd,a)<0)8 S! z6 l3 J$ K
{
% j/ U1 B& p2 `" O printf("Bad Input!\n");
! y0 k+ ^9 T/ c( c# v j) x8 s fflush(stdin);
6 ?+ P/ \# X0 ? return -1;
. s4 h& `: C+ y6 u6 e7 c }
9 h: P2 c, Q& S% `, { printf("opnd出栈:[%f]\n",a.data);
. i5 @6 R2 z' Z$ ^1 E& r+ E/ Y opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1 Z8 u5 ^6 L0 n% _0 n- j Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
. A0 p! O9 b5 p printf("结果入栈:[%f]\n",opn_tmp.data);
$ b* u. r5 _3 S! Z, z6 g3 P9 @ break;
, `% f8 R( o4 C3 w5 @0 x/ \ }- e- S$ ]6 U; g/ ` d9 ~
}+ V9 T2 ?. B% V5 O3 m
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
: A0 H8 F8 b" n$ H% @( ?2 G( Q }0 J, z9 X2 \2 G5 G& u& P* F
GetTop(opnd,opn_tmp);2 d, l# @! v0 q0 J& Z
DestroyStack(optr);
* p. \* U i" [; r0 L2 E DestroyStack(opnd);$ }- \( M+ F# M3 B' k
return opn_tmp.data;$ V y! {0 n% K4 k; F$ I+ J/ k
}+ O" _( g% J9 e8 s6 k4 ~: P
/ A. y% J7 _0 r) D6 {7 x0 n+ tchar *killzero(char *res,float result)& C/ i+ G r! k5 J; T8 p" u3 p
{
3 R3 K/ a" {0 X' z8 l p) l int i;* t2 e0 f4 x) y% y
. A% N$ F/ u* c6 j9 @ sprintf(res,"%f",result);
# ~9 x" k, \9 `- Z! ` i=(int)strlen(res)-1;
+ t! Z9 y; L s& [; @: M+ v( y while(i&&res=='0')
. v: s' C3 c2 }4 y/ U$ W/ v9 ` {
% H9 V$ L' T, x2 `- D! B% b res='\0';
+ g& W# _* X- Z! _ i--; J! C5 l, ?5 W) ~
}
+ r8 S1 v5 r# }3 t if(res=='.')
' G7 X; k( m* \5 {6 x* c res='\0';* q6 R2 u* G' }& p# A; ~ n7 r
return res;
# o0 |2 f. N, Z* x' k r; x}
0 s5 R5 H" `& B$ _- G s; J
5 V; Z5 c, P/ ]int main()
$ o5 j7 F0 f- X% p{! g* ^4 y: T9 J8 s) T9 U( A
char ch;
4 P" k5 u: x7 ]. e$ D4 @ char res[64];
( Y. u) f% y* W; M' x+ t float result;
' p( l3 J9 R& y5 i while(1)& v l/ i' |+ ]
{/ a7 C, i' ^% ]" {5 c
result=compute();# Q) |5 a9 k1 F! q9 [, z- o
printf("\nThe result is:%s\n",killzero(res,result));
1 N$ K9 y4 f+ T, q" ^0 M* M printf("Do you want to continue(y/n)?:") ;( G! z" }& z) {
ch=getch();) \, B# [2 b: Q; b! Y5 `8 q
putchar(ch);, y4 q# a$ s7 K' o- l0 I+ ~
if(ch=='n'||ch=='N')( @1 J4 S' H6 t0 U2 q. t
break;+ f. J2 M7 D# v9 e; \! u4 z# ]
else7 N9 D" S# y: H! f- j P% e" I$ ~
system("cls");, X1 O3 [. L. S! A6 ^/ H7 D9 f, z3 u
}
) I8 [& }) }# G2 G5 c: w; V return 0;% I% i$ D. q+ [8 O- G8 e4 R% w
}
7 o; O0 v1 {1 V$ n
' e# [$ l) I) n& b' y! K, |: I[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|