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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
% Q; g. o# G; Q) e5 l$ s' k+ v程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
) i% M4 h. r( K% x+ |/**************表达式计算器************/$ N" u+ C4 C! E1 j: e1 }5 n; l
#include <stdio.h>
$ C& E* [5 V0 A& [4 z$ Y#include <stdlib.h>
" n7 i5 G6 {2 T2 ]0 n- L4 Y1 A. G#include <string.h>* b/ g4 O, |. T0 T9 K
#include <conio.h>
( [/ F* f- T6 p5 H: G$ l#include <malloc.h>
6 `- ^" O0 J9 D. Z5 |' l( h1 R0 r% g# [7 z7 }9 i" s
#define STACK_SIZE 100* j2 c$ b# j; J2 g, f- ^
#define APPEND_SIZE 103 ~$ W9 g3 C. N1 ]9 `9 Q; W; a0 L
+ c, S- L w( l4 u W
struct SNode{
0 X( ^8 g) D, s, O9 z3 x float data; /*存放操作数或者计算结果*/
4 I. r' U8 g3 M* \! O- |$ h, N- b8 i char ch; /*存放运算符*/
, ^. G& [4 }7 a2 r" a};$ K! p4 T! n8 u7 H; a9 l. E
. L. O4 I, i+ Q' Z0 P1 `struct Stack{2 v v. q7 F1 P/ D8 r
SNode *top;
; j+ l" Y o$ F O! E SNode *base;% p) F! p! d5 i+ |) D. N9 g& T
int size;
2 u8 h7 z: k0 h$ a) U! a1 u};0 c! o. I7 J! S0 K/ N
% v- [5 e3 R, A- [0 w; |! C/*栈操作函数*// g# X7 ~1 Q- @
int InitStack(Stack &S); /*创建栈*/
, Y% L% h% Y. S% e4 ~9 B, gint DestroyStack(Stack &S); /*销毁栈*/) s+ V! _( B' o' }+ l6 |
int ClearStack(Stack &S); /*清空栈*/! g1 C; p( K" D( `* u( E
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
- O0 Z$ X- F: D' z* qint Push(Stack &S,SNode e); /*将结点e压入栈*/
. y: n4 O, O! ]int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
. Y5 |+ R& g/ P5 s7 y# S0 M" b) t- S8 G( s+ g4 f2 d5 d+ u
/*表达式计算器相关函数*/9 E' \' U8 U0 N% I! l
char get_precede(char s,char c); /*判断运算符s和c的优先级*/ B' Y4 l+ T& L' C% r
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/; p. K3 K7 }* s. t6 o' D o. n0 O
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/4 h, D- z7 I8 K9 g( f/ m& I
float compute(); /*表达式结算器主函数*/
" P- P7 O% n9 Hchar *killzero(float result); /*去掉结果后面的0*/
/ u6 R7 b* ]/ Z* ^! J
]2 l' j6 t- x O% uint InitStack(Stack &S)
! K$ q9 f7 I$ l3 Q. n! |5 ^% x{# b. ]+ V2 N/ w9 P
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
' F9 {1 `6 m. p if(S.base==NULL)$ F; N7 P8 I: w; Z
{$ F- I" r) F5 z2 ?: N5 r, i
printf("动态分配内存失败!");
3 C, E! U; q3 p/ b) }( i: z- y return -1;
: @8 |% X) { s0 u7 d, W }- M' ], U9 b9 N7 q3 X; d3 @
S.top=S.base;3 u6 }& N T" h; B0 P
S.size=STACK_SIZE;' Z" u: s7 S! p; o
return 0;
' ~5 x7 C }6 K/ [. H}
/ r" L3 ~- W5 R. g4 k( J9 G# c) [% [( L" b- }% k8 n) P( b, k
int DestroyStack(Stack &S)7 d6 o* Y8 ~5 V; F
{. v5 h7 p) H/ ?/ V; g
free(S.base);
; g) o$ J: a) K$ r" W6 i; } return 0;
9 a9 k9 _% R6 j* ~9 ?}
) ]4 o/ K; L- J4 G+ W+ p0 c& V+ {' m% T1 E
int ClearStack(Stack &S)/ m; B6 H8 g2 y* a; o& P, J0 {
{
+ { j/ u0 e* K7 t5 V2 v- T! c S.top=S.base;; e9 R: w: q7 `1 n( K) g
return 0;: c# y" T- Q& l3 H6 S
}: q H6 w, H1 B! g% m9 l8 }
; k8 L ?3 U* v, |int GetTop(Stack S,SNode &e)
7 u/ ~$ ^/ A" Y4 `0 K: |{
% h( O. A1 K2 s9 k6 y3 L if(S.top==S.base)
/ v) g+ }( \3 T, A1 } {. d- X4 H7 e9 o# e3 u! z: S. l! k
printf("栈以为空!");/ w4 A* H5 `' P6 O4 m
return -1;0 F! i6 ?1 I! t) I' L* h- o$ n- P
} R) h& _' F# R+ B
e=*(S.top-1);
8 M6 y/ }' j" K; C1 ~ return 0;1 }$ V5 u! O3 [# e
}
8 D( r) H8 a e$ y
! s& `+ e* a9 z' |int Push(Stack &S,SNode e)
8 m; k. q& [3 b- m2 h. Y: }{% C# x4 W, C6 g5 O& \
if(S.top-S.base>=S.size)3 k) A* o4 P3 u
{* Q) |3 m' k, U5 y5 D" u% u& @ ~# z1 f
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));0 G* X6 H+ i8 S- Y, `
if(S.base==NULL)+ L6 O! L7 I* G
{
" \- s. z2 S' Z; k' d6 w1 y, G5 ] printf("动态分配内存失败!");
# U8 h, l9 b7 q! h& t: } return -1;# ?- i0 Q0 s i, C- `2 F. y
}
* c& o2 n$ s# n& d S.top=S.base+S.size;3 P' _& w; _1 j, ^6 w+ H+ y
S.size+=APPEND_SIZE;
6 h+ G6 o8 @ [5 s; J R1 L }
( v- U3 Y# b; a" ?6 E2 k- W *S.top=e;
, a! h, M4 t3 R1 Y S.top++;' l1 I+ F! A O, G2 R4 @
return 0;7 g. p4 g* _) l; A2 l
}: f6 {3 B1 m+ i9 o# s
% J: T# b$ @% m1 O; f* Qint Pop(Stack &S,SNode &e)
' g: F# y; v8 {% P, w; A. v, C{/ s) k$ j& }" s5 Z4 g# E% m
if(S.top==S.base)) l: T: ]1 A1 {% `6 }
{. i# U8 W( p$ X7 }6 b6 `: o
printf("栈为空!");
$ q( p" |( X- [. i7 w) [! T% y+ I return -1;# V& K6 c) [5 D, w s6 A
}
4 a' ?5 @ {0 @ e=*(S.top-1);
1 o @: ]- |: p- M% k+ B, Y S.top--;! g! }' M0 r; s: [+ D- \3 {) T' x
return 0;# ~' I b# i( r3 S' y5 s
}
& \9 E% u2 s6 {* l. o4 ~7 P; y! c( R3 c
char get_precede(char s,char c)
; g2 @6 C0 r4 M& Y8 P{$ c |" T' U, M$ w/ Z
switch(s)
8 M) v! h- J6 ~ {
+ D! y2 u+ W- d% v& h case '+': + p# f/ f' Q3 K; l8 O. n7 X% }, u
case '-':
8 r% _4 g, e3 t. @5 T) a% ~5 K if(c=='+'||c=='-')
) p5 v. e' }& ]" M5 z return '>';
: d3 r& c: t3 E8 J3 o4 x else if(c=='*'||c=='/')
4 w% B; {+ p. B$ i) Z# D return '<';# A9 G. j6 s* l% W+ [
else if(c=='(')
/ d# _+ C+ X6 c! N( J4 t1 a* v5 E return '<';
1 O; q; z: R# q ~. f. M else if(c==')')
9 ?4 r0 l* |/ W; Y& |; |* o6 n return '>';
; d% ~' H) X6 k0 E0 \* d$ c* m else
5 a4 G4 L: i" D1 V+ ~$ A$ a6 E return '>';9 O8 g7 d0 Q0 I( i4 i
case '*':
# e* B; I; r2 Q; }9 j5 F case '/':
- w* W/ L K( c1 [1 v if(c=='+'||c=='-') X7 b; `- p5 F# a; E
return '>';
# ^7 H8 V0 x8 a6 W2 m& _' ?8 t0 g else if(c=='*'||c=='/')
G S' d, M# W5 H return '>';# W6 J, w4 |4 l2 s' }6 N
else if(c=='(')
t4 [0 K# W' y( o j2 T% Y return '<';& j1 v+ H8 ^! w9 I* U j- T
else if(c==')')
( V1 q6 ~: Z+ p* I( m: |- L return '>';
4 B; I5 j' r: h8 @5 H else( Z2 O) B: N8 R& |2 A& f" E5 c
return '>';
: E4 r! v* V2 }/ [! d case '(':
* G$ r5 `2 p8 I; _ if(c=='+'||c=='-')6 K; d' D! a/ J# K1 T# j2 d) e
return '<';9 P+ z) X) ^) q" }; P" z- X
else if(c=='*'||c=='/'). O5 h5 S! i" C- H; f
return '<';
& w% P/ I5 I d) q% y else if(c=='('). }3 s1 T0 j8 o' Z* Y
return '<';# I. W" o" i! K
else if(c==')')
% N- {% E o n- A. I return '=';9 g7 s8 p2 k7 w
else- Y) x( L4 C+ U2 q* @
return 'E';: ^ d' Z7 }5 {( ?* p9 Q( V
case ')':
2 ?+ }9 j4 _; {* T5 S0 ` if(c=='+'||c=='-')! n8 l4 ?, C5 m' Y- S3 Z) Z
return '>';, O' W, [) j) \! ]0 w* S- Y& \$ \" Q
else if(c=='*'||c=='/')
$ G# ~1 L9 G) V; Y# n return '>';3 u% Q# S. Q' q( R
else if(c=='(')
- m4 ]! H$ @$ [% r W& k return 'E';
1 \: W9 s) N- ^ else if(c==')')
% P6 J! t7 ^3 h# x2 I0 K return '>';
& p# P: @+ [8 D6 V& ]+ B/ T7 w$ h else
I1 ]- }3 K7 G( j: \; u. p return '>';: j; ^4 |0 ~. G* k% |5 K, A* p
case '#':
, m' H% Z: g% ~4 ]3 A if(c=='+'||c=='-')) B& l0 ~* G5 f
return '<';' t3 S5 F# L5 G4 ~' p h* ?! i
else if(c=='*'||c=='/')
5 i+ k& {) o7 W9 b return '<';/ r/ j# _/ B3 \2 ~3 i
else if(c=='(')' C# |4 o% i9 c' z
return '<';, U5 c) k( G; r, q U
else if(c==')')# t- H6 [9 ^2 e" J; N x( d5 D
return 'E';
8 N0 x* n# k" Y; [9 ], l* ~ else
' y( y K+ \$ B' y* N& M return '=';0 E3 A( m+ S# W5 @( u. R
default:' d3 ~7 O; w. w7 l
break;& \# l0 t- A4 y% U
}
9 \+ H+ Z) g! P7 `3 b return 0;
# B, H2 @3 t% ?' i}" S3 g" H B1 n$ G
2 r# k' M5 A! q N3 _) @
int isOpr(char c)! H3 W0 \% b( ?, A9 H: }, L1 P
{
% c/ \" X" b' X5 C+ E if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='), O3 i7 v0 Y+ }, M
return 0;
3 d) V- j3 U7 M else $ I A+ u# Z! D' `8 B s: Z1 Q: Z
return 1;
( k- p5 d# Q3 i# k4 ~4 P}
5 o( Q* c( k" K4 O0 J
$ |1 C! D2 a( m3 wfloat operate(float x, char opr, float y)
: c* y" m1 ~! R b/ G0 Z4 y# R{
" v) G/ D/ v* X" W, z float result;$ x5 `5 ^4 d( G, F. R* t
switch (opr)
( y- Y5 ]% S9 p% {- t {
" s6 p, a6 U. _: J: R/ d$ `3 t case '+': m. }: R! ]* b0 y
result = x + y;+ _; W9 Z8 V+ I) C4 d3 _! e
break;
2 M$ C: a- I5 v: i6 ]/ t6 ^ case '-': p( c+ c6 j! A9 K7 Y0 h* p4 n
result = x - y;
; P7 H/ o) h' d$ d' P0 m6 c. _! m break;
# i0 ^0 S# i7 k# ^ case '*': " X$ k# f2 j# z O; n8 A2 `4 ?
result = x * y;
" Q4 h; ^$ [" E; s& U2 v break;( p0 s, ?7 t. p. H8 h* b- `
case '/': # O0 n. V/ i) ~( N! J3 o1 _
if (y == 0)
1 ~9 l" F$ Z' C/ p" L6 d {: g6 S/ _3 l V4 C% ^* V
printf("Divided by zero!\n");2 z, W. l1 F. M$ g" S
return 0;
( e2 Q+ l- g6 G/ U }
1 W- c6 H7 x0 ^" @- @+ b' U else6 V* S1 @9 z# r$ M
{
' Y6 F6 u* n7 e7 g6 g result = x / y;
6 c) m. |8 f9 y7 T2 F/ m break;
: q" g. r( ~& j8 k }
8 C2 \% Z# l! p default:
2 a. n ~9 A' Y1 k% P/ e printf("Bad Input.\n"); ( o4 G8 h' y- X
return 0;3 E: L% ~* j H- s
}
Y1 Q' a4 N! r+ \2 a( Y$ g) J- Q return result;
+ r7 R+ l& G5 T0 w}
& U( g! d9 n7 ?' y. q. d# r1 [, }4 w/ H0 L& L, @& ~
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
! m4 M+ J; M$ j' L7 o' M4 R{$ Q9 r, t' T/ R
Stack optr,opnd;
! g9 z) I' s6 r: {. U" V% g7 ~! S struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
9 D2 }. F0 @" q( L1 @4 U5 N char c;
- `9 c) |+ I; z char buf[16];
" y, I4 C$ h0 c% n5 a3 X int i=0;
* F, s& A; V3 K/ C" x
8 m3 K1 C5 ?" ?0 Y+ u6 u: Y2 l; c& Q2 q InitStack(optr); /*用于寄存运算符*/# w3 n4 G7 `0 E {2 u9 G D0 Y' H
InitStack(opnd); /*用于寄存操作数和计算结果*/& I+ ?6 ]' x- Z1 J3 a! G c
memset(buf,0,sizeof(buf));
( j8 O& e- @( i" X9 ^4 v: ?0 U4 B
; {1 g# C. U# G( H( ]! C" g printf("Enter your expression:");8 A/ d% ?* y. s
+ l, Y( n% T$ E3 I7 u! ^( k% u opr_in.ch='#';6 V6 z% D# H. p3 R9 T& d
Push(optr,opr_in); /*'#'入栈*/ T/ u, T& M& ]7 S! p# ~
GetTop(optr,opr_top);
3 D) [' i( f' h# ~3 X; N c=getchar();) q/ ]3 l7 h8 ]5 R7 Z2 W6 J' [3 ?
while(c!='='||opr_top.ch!='#')' K" r9 Y) P9 n2 P' S
{
4 G! U0 m9 l) q( E4 ` if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/ X* {! s# \) Z4 {2 b5 p9 x& B" a7 ]
{" D5 b: a8 w2 ~. k
buf=c;
8 }2 Z! y; `" j; m' y" n i++;5 l1 ^- [8 O" t$ i" V
c=getchar(); x% P; i6 Y, p$ J) K
}! \; n; W; I5 }) N5 `9 P/ Q) g
else /*是运算符*/# y5 p4 z9 ?$ ~8 B9 o+ R4 K
{0 ?! J+ \; m0 L9 C
buf='\0';. D7 W. [+ l1 Q" j" D* E. A" n
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/3 u. M' t2 n* L; }
{
* R( B* Q5 W2 ~! Z6 r+ [ opn_in.data=(float)atof(buf);
7 o$ _6 m _* S( f* @5 ~$ b Push(opnd,opn_in);# |8 {: `/ E* @+ l
printf("opnd入栈:[%f]\n",opn_in.data);
, N/ u5 T2 d7 x+ {0 p/ ^% L i=0;3 {+ }% y2 Q% d) t$ _# Z
memset(buf,0,sizeof(buf));8 n, q6 d7 r H* R; R6 T& `# Y
}
3 h" r+ |/ P7 z! E5 c" ^- v opr_in.ch=c;- N. q! I& ?; ?2 t2 F. J- V) l. Q
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/; L- f7 b8 \+ M* ^
{* Q+ H' j+ k4 a
case '<': /*优先级小于栈顶结点,则运算符入栈*/( x+ b: [' e0 {" [" {* d; [
Push(optr,opr_in);) V. v+ f1 m- L, V' g6 Y! n
printf("optr入栈:[%c]\n",opr_in.ch);
! t) f, S3 Y; V7 G! S: ~, [ c=getchar();$ B; t- `6 l- i9 E: y+ [( @
break;
# C, m' r4 y I' q case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/ a. p$ i' f/ ^: F* Z- I% ^7 o9 t
Pop(optr,e);- y$ Y1 Z8 P* W9 ^$ H7 j, r
printf("optr出栈:去掉括号\n");
& t2 m9 r# {# k n9 l" u c=getchar();
1 @+ L2 `& Q) L' K break;9 u) P C" Q5 V+ N! P2 f
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
' n$ N+ t2 O! [4 r Pop(optr,opr_t);
% |" ?, l* d% F printf("optr出栈:[%c]\n",opr_t.ch);9 N8 X, Q; t# e/ W
if(Pop(opnd,b)<0)$ f) s( m7 k! l5 q% l) I
{
n7 P9 v& c! d# T printf("Bad Input!\n");* ?8 o# {7 P+ v- s5 z5 k% F) ]
fflush(stdin);
4 `: p' P H& P9 N; I) w return -1;
2 ^+ [6 X# Z( P( Z, I5 H }" m( w7 P7 U: ^/ ~. ^3 H L" L
printf("opnd出栈:[%f]\n",b.data);
. J* H& Q8 ?) \& m/ `/ k if(Pop(opnd,a)<0)" |7 {- z+ m. X, ~( i# o5 M+ Y0 v
{1 Z9 T% i$ U8 F+ C& U
printf("Bad Input!\n");
: X. M. V! [2 ^$ M% u. C fflush(stdin);
& D. Z5 @' U* f( h return -1;
1 o5 D& q/ K8 W3 x) t }( H1 H7 o7 U- _" R) t) V
printf("opnd出栈:[%f]\n",a.data);$ S5 y; j A3 H) s
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/: ]2 c' Q$ z- v6 a9 N
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
8 G( {% J7 |! Z1 Q7 N0 Q printf("结果入栈:[%f]\n",opn_tmp.data);
D. a* x, s ? o+ M break;; N! |. s+ L/ t) B/ f1 g
}
5 k1 ~9 ]9 W$ S) {, V }$ z& N1 i2 y5 L+ G
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ $ H6 r7 u; V9 B4 ?) K0 t* X
}
5 b# q0 {/ Y0 q& b, a GetTop(opnd,opn_tmp);
: a* X! }3 j+ G' r DestroyStack(optr);
6 [# ~( G. a) a. H. W* F8 F' ~ DestroyStack(opnd);
) [9 `0 F' p) M3 I5 X0 m return opn_tmp.data;
" I& z A0 [4 U) z}2 H; A" ?, |. Y9 S
2 |. K! t& j6 _$ @. t
char *killzero(char *res,float result)0 l& J* c; n# Y' _7 m
{
, R. S/ Y. m/ p int i;
9 d" i8 y/ l- n$ t t/ \3 x" B9 C: \
sprintf(res,"%f",result);5 \: j5 a4 @& f( ?3 ~( ~
i=(int)strlen(res)-1;
o0 I. p- i4 K5 ^! k6 B7 b while(i&&res=='0')
. P2 p5 t, a, ?3 h& e% V2 @ {
* j1 q# N" V$ @) w res='\0';
! r- X4 [1 H W9 t i--;' u9 k6 ?" w i6 I' i* ^
}
E* e2 g$ g* P1 ?. D7 q if(res=='.')0 y9 v1 O8 t5 R- G5 m- R
res='\0';
' N2 w) X4 l) F3 Q0 r7 m return res;3 u) y0 q' {6 \' ~4 H
}
0 o, A$ w( V) l) u# D* N: X; z5 s# I
int main()
' w+ [5 J b8 H+ v/ N9 G) Y: D{1 O1 B! g9 \* R+ @2 G
char ch;8 h4 V0 ~. l# S4 }! S* N: f
char res[64];
$ s0 v: p8 [+ @' Z& \$ t float result;
/ v5 i3 M( E+ o; j4 ^( z, A. t/ E7 D while(1)' {" y& ?: t' \0 b. L2 @
{5 M+ I. q6 g# @, p& T" i _
result=compute();
0 ]3 u8 G/ v* |9 V3 f1 l/ @& O% e) X printf("\nThe result is:%s\n",killzero(res,result));* U1 B% B: G9 X2 V3 J5 e
printf("Do you want to continue(y/n)?:") ;0 Z- D% q1 S: t) V+ d* i
ch=getch();
% k2 D: z# _9 ]" Z$ a# L, z putchar(ch);; \1 G% k5 F2 x0 |( z
if(ch=='n'||ch=='N')
! f. p: d: o& K& O break;
2 F f' v9 I% \, n else
2 H; M& w+ q+ w8 s6 f0 k9 X system("cls");
$ P3 h$ O" ^1 H: Y1 s* R }
3 V( P1 }/ o) F5 L return 0;! C3 z" i$ n* r( x! l1 `
}
9 \7 J/ S8 g1 l, ?" Q4 D8 N. }5 e" a( j! k" k2 T* t# S, G
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|