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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
3 Q" ^& r) d# w程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=+ L9 x4 r+ x4 K: L' x
/**************表达式计算器************/
4 F6 f; q. C. S7 {+ B: ]0 J5 U2 @#include <stdio.h>
% g" x; t$ H( m/ C#include <stdlib.h>
$ [! _5 R& H( U1 G! j( S0 J5 e [#include <string.h>
4 b7 t5 E6 b- e, A5 L' z( V#include <conio.h>
4 F7 G8 A, F- a7 O9 Z( Q+ C#include <malloc.h>* V' y, o3 `$ g- m% [6 P+ |5 _9 u1 G
& g+ [. M" ]: z+ ^$ w# G#define STACK_SIZE 100; I- Q+ ^. {# f# U" A& D- T5 Y
#define APPEND_SIZE 10 D7 [3 Q) D6 x" K
& H2 x* @' ^6 C( ]% m( j9 r( r, H% c
struct SNode{3 v/ \/ {8 J& x3 u5 ^- {
float data; /*存放操作数或者计算结果*/
$ s/ Y. y+ b+ K8 d P( f9 _2 m2 E1 ` char ch; /*存放运算符*/
2 i3 }# J1 B1 G. y' }};
6 ?5 S5 S* m# I5 N
* t! t+ f* P g# C% F0 h D Wstruct Stack{
) i9 N: ~6 P! ]$ O q% T5 T SNode *top; |6 y% S# |/ c' E8 Y4 p" | E* |
SNode *base;
: p/ _/ g& V! ]3 I) U- t/ ^ int size;
f+ F4 I3 r: @5 _};. J+ O. J3 F; m5 a/ S4 k/ D* K+ G
. Y$ z! V- o* w5 F3 L* O
/*栈操作函数*// g4 M; b1 T3 L& C$ H
int InitStack(Stack &S); /*创建栈*/: b! t4 G3 {/ z2 T7 V7 o
int DestroyStack(Stack &S); /*销毁栈*/
& L- ?4 F8 ~$ b* `3 s' Nint ClearStack(Stack &S); /*清空栈*/
" e1 H1 E, e, s9 b' m9 Q" V7 X. Eint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
: A4 I0 }2 q* x; Eint Push(Stack &S,SNode e); /*将结点e压入栈*/
. F3 o6 C6 c# ^, j& X1 Gint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/) {" p. \5 f* O4 J1 _
6 _/ m! }9 I* L: K
/*表达式计算器相关函数*/5 ^$ b9 V& U2 p
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
3 O+ n1 E, o; C1 }5 Sint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/4 c3 U O G; }+ G
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/" X1 |0 K$ q6 D7 k: ^0 J6 n
float compute(); /*表达式结算器主函数*/
; I* z/ b/ @" o7 Zchar *killzero(float result); /*去掉结果后面的0*/
1 d9 G( o1 O& M q* v2 g8 T3 J5 H `' @+ z! @
int InitStack(Stack &S)
# D9 o9 L0 N: l" R{5 ]- k( p8 }! P4 g( U! ? e( u
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));. r0 a, u' W* g" r: P6 I( x
if(S.base==NULL)$ g+ B& s# e, A2 P) h" X
{
" B x4 c& F1 n; K6 W0 x printf("动态分配内存失败!");
* A% L3 B; ^! @, [7 j7 S0 v: D return -1;0 u' Q. I" o/ c1 g- D
}
2 v* Q6 ~. W/ c2 z' d9 f7 T- i S.top=S.base;
1 O& L- C W7 i1 e: {" L* @ S.size=STACK_SIZE;
2 G7 x/ i* \; @2 _" y; @ return 0;6 L8 t6 r' N( C9 b9 R9 o
}$ w& Y" I2 o" g V( @
% Z7 w" f- t( l. y$ Z9 X! [4 o1 y& O
int DestroyStack(Stack &S)
" m* ?" x6 |, I, g @{
3 z/ u k1 `; p8 [: G free(S.base);
5 n- |& [3 w* U' ]+ o z return 0;
3 \- A" Z; x6 _4 @% ]}
, M4 L& U( e7 K" U
6 S9 n3 o) _' n. `( r+ a8 dint ClearStack(Stack &S)/ E' K9 V% Y: q/ K
{. s3 Y/ v* e' Q" w$ @7 Q
S.top=S.base;
' ]: B* ]/ |' A( Y9 H4 ?* @7 {3 i return 0;4 A4 @# P0 ~ k6 i! s' W- ? {: `
}
* O! e3 Y! X* D D0 @; s
, b6 Z, _8 R1 W. i8 {' q$ eint GetTop(Stack S,SNode &e)
8 A+ _3 F3 R. D y7 f{$ T# r2 A1 ^& w. U* x7 {& I
if(S.top==S.base)6 G5 T4 M+ H4 k4 h5 [! x9 S* H/ Q3 a
{% L7 ^4 t3 Y, B9 }) Y( l
printf("栈以为空!");) p/ v2 w! G7 R! u9 C; r
return -1;
6 C; r, y( g G8 u }
9 T& ]3 C8 M5 z5 J: i e=*(S.top-1);' }( D$ I; x/ L1 a! s2 K
return 0;
3 I' }8 U; R; s. S& U8 U} `3 C4 @) w2 m( O- O ?
$ h- A4 [9 ]- p$ j5 F( B, @int Push(Stack &S,SNode e)4 K4 x; t& N6 S# H$ V8 \
{
! O! j/ x+ p5 z+ n" g if(S.top-S.base>=S.size)
4 j; W4 q. |9 M {+ n" G; J5 r' G
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));1 u. A# j; d4 W3 H4 f
if(S.base==NULL)
% h' C' D2 t2 \! x4 G {
2 Z& W7 ^5 f7 N printf("动态分配内存失败!");/ @9 W- A% ]% u# p! h
return -1;8 J8 Q4 h( }5 E6 |0 }
}8 q$ w% s# U$ e5 M
S.top=S.base+S.size;, q5 t: i) W: F3 ~/ Z
S.size+=APPEND_SIZE;" D! J0 f3 w' O# J1 z8 D$ c
}+ a# U8 T# x1 {* M5 M. u! h5 P0 R
*S.top=e;! H3 j6 ]# c) e2 F
S.top++;
( ~2 ?) U. y+ _" c5 t; Q) \8 i return 0;1 z- S5 L: _) x& X/ M
}
7 J# L0 w. F( _% C! y; x
* w2 ^7 P' k2 w& u, uint Pop(Stack &S,SNode &e)* Q( v6 A9 x( S' z! X
{1 H. J/ j F1 ~
if(S.top==S.base)
# _6 G2 n: h6 V6 j" _3 _ {/ {6 q$ }. r$ ^) c' I8 q/ d- N$ U( o
printf("栈为空!");8 U/ Y* H7 V H/ O, m$ F! g
return -1;
1 i b- {2 w' | }
5 I9 n. Q/ U. s |2 A& s( @ e=*(S.top-1);' q/ [- t, b8 Q; O
S.top--;
5 X5 f2 O( m) m' y return 0;% H) d/ F4 t6 |2 S3 G% E
}
) L/ S/ H0 I s) ]3 O8 l' d1 [9 V0 X9 S/ M8 u% e
char get_precede(char s,char c)4 i6 p* B* z9 ~ S
{
3 D9 P- l8 ?3 o0 S2 _1 i* E" B switch(s)' o- l% z2 z; M3 ?
{+ Y( c7 P$ ?6 y8 Z
case '+': % O6 h' U6 o9 l: U# c) g/ g2 P1 y
case '-':9 z; c9 F1 F7 @5 u# j5 a. o! b) I7 R
if(c=='+'||c=='-')
7 z0 u" B2 I/ T1 n6 n return '>';" ]) H, r# g1 b6 r
else if(c=='*'||c=='/'), Y- ]8 o: _; X2 F
return '<';* ~$ X, K+ e; i4 w( ?, K' C
else if(c=='(')% l) E, A/ X% C( x+ U! X
return '<';$ @9 x2 A# t; _8 T) r m
else if(c==')')
% C/ N/ t8 K# H return '>';. Z8 | ^: _/ v* L$ ]
else
( n, ~! ?, ^- S1 D8 F: u* E' f return '>';
% B z9 j7 y9 x' t, L( } @ case '*':& O; o, w3 W2 h) l3 O
case '/':
. b1 g& ?( ~ i' J4 y/ W, S3 \ if(c=='+'||c=='-')
/ E6 Q" C6 }+ i return '>';
7 ]" F# R5 p( W: q& j else if(c=='*'||c=='/')
! ], R' ^8 s# T" k- _+ P5 b return '>';
9 t1 l0 e" W1 g, s) _ else if(c=='('); R5 ^' K* U3 ^
return '<';
! V$ I; N! |- U( J else if(c==')')# W) @: g! N7 Q* v* ^$ R" a2 y! L
return '>';
# M; f7 p/ f1 E& h5 Y else! v1 [- z( v) V* e4 |5 o! R$ h
return '>';1 w8 W& U3 z' L l. t L) k
case '(':) C3 U7 U* J0 C b9 F G
if(c=='+'||c=='-')4 ], x% ~4 F+ f
return '<';
( h5 ~( E7 M% u2 G: j else if(c=='*'||c=='/')3 o# @; b3 \% s* p
return '<';; [; y! t+ c+ c
else if(c=='(')
9 _1 }, ^8 }- h( y/ }- T' p return '<';
5 D& A+ ~0 M' }( z# t& _% M else if(c==')')% a+ c8 V5 q0 a) f9 r( Q9 X
return '=';5 T! J/ ?. B5 O
else
/ u7 Y/ ]) u) i0 z$ ^ return 'E';
3 T4 \+ t& h* a case ')':
, f' D( s& l2 E9 z3 ` | if(c=='+'||c=='-')
* j4 D$ O1 j% t return '>';& H' B8 H9 P2 V6 s$ m2 |0 C
else if(c=='*'||c=='/'): W8 U& j& B; {* |) M) p
return '>';6 A- [/ i5 N$ H! v* E6 B3 m. e1 a U
else if(c=='(')# f+ P/ F8 Z. h
return 'E'; f' j' Y: P; |/ W; j
else if(c==')')
, T1 x& }* V: d, F return '>';8 }0 t$ e" g9 H
else
" Y+ \! }9 D0 L* q+ W return '>';6 D/ M( I* U# k7 o) [
case '#':, J9 p( G. w# X, U, A/ ]2 S; E
if(c=='+'||c=='-')
) X: S5 A" e: l5 U return '<';* \' z' v& D1 f8 a% ~
else if(c=='*'||c=='/')
- p5 P% F2 \, p. Q return '<';
5 k. \ U! b" Q( c' R# m# S1 X X5 F M else if(c=='(')
( J$ Q; b0 a+ [1 i return '<';& z N3 k3 n& ^4 \5 q% a
else if(c==')')
; r: [3 ~; T# q% {- k return 'E';9 j: S* s" }9 H. N' ^0 K9 J5 I% r
else1 h; S) g3 y! Y6 V- u
return '=';6 j* ?+ k( k! [: H5 Z
default:
; b4 i H) A, v break;( ?6 K: |4 f( h8 X
}- {/ Q3 g' d: R; w
return 0;
0 k7 U& l$ s5 }% ?: T! x+ e}" e. ], k* j l6 i2 u
3 g) J2 ?- n6 z# J* N0 ?' f9 l) I
int isOpr(char c)
* f8 K" {/ F; d$ |" K& `1 \2 p6 i{
$ s4 b3 T, K4 o5 l( Q if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='). x9 Q7 Y- L# w/ |4 u. q
return 0;
( d! \1 e# @5 ]0 w: O else
7 o1 V/ U( M5 K! U2 E return 1;" H( k6 b O8 M
}) ~# ]1 \7 p# e7 G% A. G
2 p* v2 `0 ?: m! V Kfloat operate(float x, char opr, float y)
. a6 _6 a/ J/ d* c2 W; Y$ m{
# h8 o# C; l2 {+ D% }( `- s, q+ @+ N float result;
% q* x6 S! H! \% m switch (opr)! x( d# e: M2 ]8 }6 G) D! ^1 I6 _
{; x7 i( N" N+ e; l5 }$ c) I2 Q
case '+': 2 ~: o) B, t+ \
result = x + y;
' z# O9 ^# P' y/ T/ A break;, S3 C1 w* {) b3 m5 F
case '-': ' C4 W$ I# I: p- i. V" J$ I! n
result = x - y;
" {% ], m) M; E% n: s- S2 D- v break;/ x' W3 f# k a; W' ]1 Q
case '*':
$ [, G# F5 Q% t result = x * y;
8 t E/ F: X5 l- J* p$ Y" L$ ?6 j break;
: z& B5 ] z; A2 f7 V$ n case '/': 6 ]8 i( K) I" @
if (y == 0)
: z% c t! W2 S8 W2 P {
. h$ y) E0 N# p$ \; n printf("Divided by zero!\n");! M3 @( c- m5 b1 J
return 0;
2 N( F5 m, R+ L }( X# d& o! r( H; |
else
# p. H) H3 J8 G6 h: o {
) A1 `+ a) U: O$ ^3 \/ n1 K result = x / y;/ I1 Z! [# K$ |' V; a
break;
5 t, h) } v; [8 w( U2 r- j }2 H/ X1 c$ B8 f8 s8 U+ f B; z
default:
& X8 k5 c( q9 d printf("Bad Input.\n"); % J, M1 M* t2 {- W+ W
return 0;' C9 q# C/ S/ S1 ^7 C/ b2 n
}) \% G) x6 S; m
return result;- d; Y- l9 u* U
}
* L" E3 ^& }9 y) b3 Z- I3 V; `; q- \$ ~
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
9 o# z1 g/ s9 q; }{
/ \- a$ y v w6 R" c Stack optr,opnd;5 Y P6 Y+ {- Y9 L* A
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
7 M; Z2 n o1 h$ g& L. K% ^ char c;
6 S% V1 F( _; V& m5 w6 V char buf[16];
( [* @" Y" e1 i- B int i=0;9 H+ R$ H+ x" r
3 n+ q% O" B R' A
InitStack(optr); /*用于寄存运算符*/
( h" M' v/ b4 V: s: t3 b3 i# D InitStack(opnd); /*用于寄存操作数和计算结果*/. Y' |+ l, z- L; b! t/ R! p
memset(buf,0,sizeof(buf));
9 f5 q& {% G) u5 M ( B- L: G& _8 S+ y9 {$ T
printf("Enter your expression:");8 m8 x$ C$ E; {; [, k
3 b8 v; W' n; c: O6 K& M2 e+ U opr_in.ch='#';. A& f" I. C M. i# x* v
Push(optr,opr_in); /*'#'入栈*/% a# w* H7 P7 D6 p0 f
GetTop(optr,opr_top);1 n1 W4 D, @: x' L
c=getchar();# y+ m: s! @% L
while(c!='='||opr_top.ch!='#')
5 M Y, C1 c- i {
% s8 Y) H2 X% e& a7 W if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
- ~' f, [4 q G' s+ N6 K7 m {
I& D2 l$ Y, \3 j7 R q/ Y# i: I+ @3 O: E buf=c;
: Q+ r& F7 Z* H3 A+ J/ T i++;
2 ~/ ~3 w; N( p: H, ~ c=getchar();
7 O! s5 U; q9 Z4 ~ }1 ^, C. ~5 H% l
else /*是运算符*/- `1 j' w. b3 B% x) K; {7 U
{- L2 |) J9 R! v* ~, L
buf='\0';
$ ?7 k) M0 l- N- }/ o if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
. M9 r$ c% a" P, Z! c+ g {) }# T+ O( S" q! D
opn_in.data=(float)atof(buf);, ^( {1 V3 N5 B" k3 n* ^" \
Push(opnd,opn_in);
# m/ m6 {9 |. u printf("opnd入栈:[%f]\n",opn_in.data);/ }- v J' o$ X2 h% C9 U. S& Y
i=0;' J0 B2 f c2 `' n
memset(buf,0,sizeof(buf));
+ U" J! P4 N8 I* b6 w }
( ]+ O/ X; n, n- k opr_in.ch=c;) M8 B' O `% j2 o7 Y& g
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
/ f2 _. g- Q6 e0 J1 A, B: d {+ k$ z1 D! q9 N* A3 F I2 h
case '<': /*优先级小于栈顶结点,则运算符入栈*/
; J$ o9 r4 X- `, D Push(optr,opr_in);7 l# L' L$ X2 Z& S
printf("optr入栈:[%c]\n",opr_in.ch);
( L/ S. A2 Z" E9 @& u6 j c=getchar();
$ ^$ M1 V6 R: `8 W- M. H break;; |, ?, C( [+ i# m: Y9 G
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/( `5 X1 Q& Y1 @9 Q
Pop(optr,e);
1 ^" n+ t' g# w% b! C printf("optr出栈:去掉括号\n");+ f9 H: C2 w4 C, a" z
c=getchar();
4 K( J j* {; |+ T$ t* ^ break;
. R5 b& E, C* d+ h+ w( ? case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/" t9 k! q0 c- e- B
Pop(optr,opr_t);; E3 H* ` H8 w: G6 {
printf("optr出栈:[%c]\n",opr_t.ch);
1 N: o5 X. ]& G0 _- y! L if(Pop(opnd,b)<0)' J% N+ F. }& d' t8 g
{
/ W. n5 c, w1 x! U printf("Bad Input!\n");
( l3 q. U# E% o& T/ P5 l7 N7 O fflush(stdin);: S6 I0 N( r! _
return -1;4 r- P9 G( [# `
}7 K# i/ A9 S( ^' D
printf("opnd出栈:[%f]\n",b.data);
3 t1 Y' q* s, x% s' D$ u if(Pop(opnd,a)<0)
6 b" B- u9 y! R7 ~# `; R {
$ _9 ^1 q$ P8 x printf("Bad Input!\n");
: [6 `! J2 j- X4 O! K fflush(stdin);
* K, ` W4 X& g) _( m# u' L/ [ return -1;
0 X! `2 D4 C+ M) l6 X: @ }
$ G1 c+ ?. O ^8 G5 F& W printf("opnd出栈:[%f]\n",a.data);
) r( ?& n/ m: }2 f8 P! z0 u opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
) T% R; @! c/ \ Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
% S+ X6 S/ S7 [' g( C6 u printf("结果入栈:[%f]\n",opn_tmp.data);& S$ c9 ?# w s' d: ?
break;
2 r& N! x- B! M6 b2 S }
: H6 W+ b6 U) `9 k6 r2 n }. }0 r/ V/ F% E: z9 J5 \+ ^. v1 V
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ 0 { \2 m3 a9 L. D
}
0 S! [! S# s2 v* x- G GetTop(opnd,opn_tmp);
3 j3 o( ^% R& y/ a+ L DestroyStack(optr);( |2 t2 N e) m, \$ k
DestroyStack(opnd);8 u1 L3 H0 C& X' Z
return opn_tmp.data;
2 ?' m# Q' t/ E2 J}: G. D+ t/ m+ r) D1 y5 v
+ {2 Q$ k0 C' m# [4 gchar *killzero(char *res,float result)
+ z* [, j3 s) d- M{
1 v, }% b5 s9 `8 \3 ^* |; s1 n int i;& f8 o* e+ q g0 [. i" H2 c
! j9 p9 W. @; s0 g) Z% b
sprintf(res,"%f",result);
+ @ d3 ~* T3 G6 J) r i=(int)strlen(res)-1;
S5 F/ k3 z# @3 P/ S: G3 W* n; x7 R while(i&&res=='0')
2 C- ?* h( t6 Q! d {" P1 k' x R+ g# @7 D" j
res='\0';9 F n1 \ m0 Q) {3 Y( ]
i--;, y- j/ {$ Q/ s! U7 q! W% M+ y# t
}
8 D% q+ n8 u0 P& e* N0 F7 Y) M+ h if(res=='.')/ |# I' [$ k1 ] M$ K+ P8 z
res='\0';
2 f$ A& ^8 k. v. O! r5 G return res;
2 g; C5 p+ W; a3 r: \! q$ f' x! p}
y! X8 k! B% I4 V L3 m& _+ M+ ^0 u0 j" `* F' U' Q
int main()/ Y& G( |6 W5 G6 ]% I; i: j
{
5 J' ^; t' t- |! j+ [1 V* t char ch;
# F) \( S( x* b ?- ?6 e char res[64];2 \' w; _, l( y* _+ f6 z
float result;
+ m# v/ j! `" I; \ while(1)
' S" S* [8 p* I; K) u: G {
. m) v; N9 H4 M! \" B: h8 o result=compute();% D* ?9 {4 X7 a# {6 p6 @( `
printf("\nThe result is:%s\n",killzero(res,result));
1 P6 p$ \/ H/ ^3 l( R; G. a printf("Do you want to continue(y/n)?:") ;
8 y. H' i+ E w ch=getch();/ J% t I# b4 z; \' J
putchar(ch);
M4 m" y, A/ |5 B: v if(ch=='n'||ch=='N')
2 P+ U, i; Q, \1 y7 i5 _" J0 l break;
" n7 p/ z$ c, f5 O else) X: P" d& n7 H _
system("cls");
% E! u* Z7 g$ E8 o1 i }% f$ G/ i, U2 z7 x
return 0;6 a+ C5 H4 A3 N3 x
}0 n N9 a1 K' C
: \3 \% d E; z3 _- K! U; I
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|