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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.1 |* W- J4 N0 X1 W
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
" d2 c- s; w1 A9 @/ R/**************表达式计算器************/
: W' F! j' d3 F& _#include <stdio.h>
A% v! e: N1 \! ]2 b3 u+ f/ H#include <stdlib.h>
) S$ Y1 V& D9 G5 I7 U) Q+ j/ i2 K#include <string.h>
$ n: |; t6 Y/ Y% G$ N" ?9 S: ^#include <conio.h>
; o7 D: M h* ^#include <malloc.h>
8 W5 L, D1 k3 X" r6 l3 k& G/ T$ E
#define STACK_SIZE 100
0 Z! _- Q* ~* c9 g5 r' t4 d#define APPEND_SIZE 10% |4 o8 F; E2 N. c# }
0 j$ {+ A" Z3 N: p0 T$ ]2 X. K0 k$ E. Pstruct SNode{* E5 P+ u* ^! v% Q4 C4 [+ |
float data; /*存放操作数或者计算结果*/1 O1 {2 v) ^! J$ f1 C- t
char ch; /*存放运算符*// p' A: \3 R9 m$ P1 {
};
9 ^# L$ Y+ s% ~& z" Q, K; R% ~
5 w, u9 c! z, Tstruct Stack{
, |( z6 ^& b4 P SNode *top; ^" i8 J9 x! ~8 _, o8 J
SNode *base;8 G; p' l& J4 E* ]6 N; _
int size;
: Z( G9 P8 i0 r" @* L1 x6 q* e};" c( |' \0 \# L7 z
% P, B; o, e# @6 Q5 b! l( d
/*栈操作函数*/
6 a A* U& S* n9 W4 C% Z1 k: c7 w1 Rint InitStack(Stack &S); /*创建栈*/
" Q) v) k6 A cint DestroyStack(Stack &S); /*销毁栈*/
) R" S8 G. z% fint ClearStack(Stack &S); /*清空栈*/
0 v6 q. u, G3 @' J2 eint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
3 G# T% _7 N N( oint Push(Stack &S,SNode e); /*将结点e压入栈*/" h" C! d, a+ E8 T. U+ t4 g: u, q- l& p
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/; u+ _2 `6 N. C$ W6 U. l
! g# t) L, Y- }# N
/*表达式计算器相关函数*/
2 q# E8 {. D0 M5 p/ fchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
. A1 k. s5 [" E/ Iint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/! `/ b) I( I. V- v U. D# v
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/ Y% A `: |, ]5 b4 R9 } _
float compute(); /*表达式结算器主函数*/
) v, k) ] p2 N5 L+ J' v$ q) T$ \char *killzero(float result); /*去掉结果后面的0*/
4 N7 N- g$ T: |% R* ?; s3 R# W: }1 Z" |: E7 H1 U5 n
int InitStack(Stack &S); u" `, [# r& K! _. ^8 Y
{
" m) m3 t" G1 g/ o0 | S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
: T' @/ K/ t6 v6 W6 z L# C' Y if(S.base==NULL)
1 }( ^9 [9 P1 h. h% s {& C$ X' y' n4 M- B
printf("动态分配内存失败!");* Z! j3 Y! T c
return -1;
; Z: U1 p5 b! c, H4 r4 G }
9 w5 F j9 a$ r$ w5 l S.top=S.base;
; ~5 K% O, H! b6 ?3 @: [5 |: ? S.size=STACK_SIZE;6 _' Q3 f! T' S: J) P; \; J. L. R
return 0;1 m5 T. ^" t% `, V
}
: w P9 X3 o" E2 c/ S7 @7 L
& y! h q* M) g5 O5 M; \# C) gint DestroyStack(Stack &S)
- i) ~$ O6 s: p4 n8 e: @$ I7 |- H{
, Z- Z' v# E/ B, w: T2 c" Z free(S.base);. j7 W4 F- h' C- r! i/ u7 N. I
return 0;- k: q& o( e( K+ S
}& n, T4 }6 u' I8 f7 s/ g0 [" Y
+ Q7 ?& d6 E) n+ `7 \& j
int ClearStack(Stack &S)- a# {4 ^( _- N; q f2 Q2 h q
{3 z! Z" \# }" p% h- @
S.top=S.base;
, C3 ?, k: x [! N return 0;" X0 P7 @; Y; Q! w2 W( `. h& Y
}3 l7 w$ F/ w6 _$ `
; x- a0 f4 D0 \0 V! E$ j& i. y
int GetTop(Stack S,SNode &e)
2 @1 q% n0 \, I{
( }8 B& K# {# M& M; ]; z/ c if(S.top==S.base)
3 l4 n; q0 m7 v3 f. y/ P {' z1 K* [; l# O, @% ^$ @( L5 b
printf("栈以为空!");
6 p' ^2 a. V' A4 X. o7 C8 w. y0 t return -1;) v) H% q; U% R- t2 ^% m i
} F$ i/ o3 d$ K9 m% h3 F
e=*(S.top-1);
7 @% m5 ^9 M( G" U- w return 0;1 C! |- A F1 I; o: h2 w( ~
}
" M$ M' U _6 D; {% t0 _7 \ }/ ? \" K4 a% K
int Push(Stack &S,SNode e)9 V9 Z9 r6 O; H, d* R2 [2 d# y
{* y3 Q+ q% y, |" g
if(S.top-S.base>=S.size)! ~2 x9 ]" W; _! ?
{) _& S- [. q, h1 }
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
0 a7 M, r" Q$ S' E4 W$ I8 B; C4 U if(S.base==NULL)
; a1 W; N. L# v& q9 C: r) F8 i8 p {+ w8 O2 y2 i1 n8 q# _; H* a
printf("动态分配内存失败!");
. _$ I: U3 l' e( X" F) g3 w0 i return -1;3 ?, n. l6 C1 |4 U3 ?/ ~6 s
}
8 R) n1 p4 ~1 z1 P/ v0 k S.top=S.base+S.size;
5 F: W2 P" b, Y9 f6 y; M S.size+=APPEND_SIZE;
2 u# ?6 e& J9 ~, R2 v- Z# T }5 ]! O* t/ s8 S1 T
*S.top=e;' F7 b) _8 @) h+ }
S.top++;
7 s# d1 _+ r R8 d return 0;
+ z( [7 Z& }+ D}" J5 ?! g; e) F3 T7 I
$ U; X0 S8 T, Y& h
int Pop(Stack &S,SNode &e)$ S3 q$ {# o. z: G4 |! D$ t
{1 ~; V1 n) l( {8 f
if(S.top==S.base)5 q7 p6 j7 v4 P6 q3 G( o9 \
{9 @, L0 o6 Q. \: Z }3 G- a: o+ ]
printf("栈为空!");
! f9 h0 \7 G8 A7 x8 \3 Z return -1;
) k) h' M0 I% A; y }
. p6 d0 w$ s$ b( F/ K* S. D e=*(S.top-1);
3 m( O4 _( s# Z S.top--;
) D' l: }0 b& `% B' m return 0;1 U. m2 V" X* k* Y5 C- y
}
/ T2 G% p1 c+ {, S3 |, s
- u5 i# a# z3 K$ K# Xchar get_precede(char s,char c)
+ e) n3 }- N( ^* g- Z& A{3 q$ P, I- l9 {3 i' e
switch(s)
% ]1 q* ~, d8 r6 z. @7 g" o, T { z/ G- d: x& O3 B( T
case '+': 7 q" y) d* r/ b; t- o( \
case '-':
" [+ O8 E. N3 K. y& T. |8 D L5 q# y if(c=='+'||c=='-')
9 r- J3 W# o- {) R' C8 n return '>';
: l* _8 u; y8 g* H t. i else if(c=='*'||c=='/')4 s/ N0 D. z' F0 k5 T
return '<';4 K% R! X+ S* `3 q0 G% ]& C
else if(c=='(')* J+ Z8 y, F1 [6 t) L
return '<';: z; x a2 M7 r E: }
else if(c==')')
7 C. g7 s2 X2 d X* J' c return '>'; e- J8 V+ _. a& H6 o
else
$ ?) m* Y4 A& S2 {' f return '>';
7 n, s) L; c" M+ l \ case '*':
' N% \) b5 V4 Q9 n; F! @ case '/':
* m; t2 F7 m' y$ x' r7 i" E N if(c=='+'||c=='-')9 K4 o* R4 Y$ ~$ x0 S2 `4 D9 D
return '>';; B2 O. L3 a7 \0 t3 @
else if(c=='*'||c=='/')
& [4 \0 X& U r t- {0 n9 [5 K& G return '>';
+ E' |7 R1 j- m% K else if(c=='('), z- c5 ]% q! {8 ^4 N, W
return '<';
0 I! t! z+ Y" |9 | else if(c==')')
3 ]6 x! F' [7 o3 d! W4 w0 i return '>';
6 g, `" A1 J% A) m! t! S else
' X4 p: p- o) |3 O$ a return '>';( ?! K0 X0 `5 Z+ E" L1 i: [3 r0 C
case '(':
( P5 i( i2 n, s! c6 w( ` h if(c=='+'||c=='-')
+ ^0 T6 n, v2 r- r2 f return '<';
- F7 O( }' i" ] else if(c=='*'||c=='/')% F T9 h+ ?2 A$ @0 `
return '<';6 B, h: f; f- e. e
else if(c=='(')
9 m- r8 n1 p( I' P return '<';8 K7 [4 O! T+ l: w9 G3 x
else if(c==')')5 E9 f2 q9 i+ Y' n9 g
return '=';9 E' I+ g4 Q- @+ G/ p" c
else5 F: X, A* Z7 X5 j$ i: p
return 'E';
/ r/ E& l% [4 V, T9 o case ')':& P* t# `' k5 L
if(c=='+'||c=='-')
, ]( `# q8 e: V+ L C return '>';
8 ?" f6 S" f9 g5 X6 c else if(c=='*'||c=='/')
, U7 ~0 r/ f% }( n) F: S return '>';
$ u. U. s9 m$ c+ Y: B& ^, f else if(c=='(')
{9 y6 Z' m( J6 y+ r( ~ return 'E';
( ?% y& i, e& x1 C else if(c==')')
0 G! o9 j4 c; a7 m+ \/ [7 F! g8 s# d return '>';) }0 k4 J3 i% _3 P/ Y9 n
else3 {) I! M7 d+ B0 s$ |2 A
return '>';
% }+ w: Y2 k3 h5 b+ V$ ^# ?6 U3 j case '#':
8 g* Y& O7 ]3 a7 _ if(c=='+'||c=='-')
% k& K) Q2 ]: h+ g# k: f) ^7 j; N return '<';+ _) r$ x, c! k# `2 a3 d' e; Y
else if(c=='*'||c=='/') c- ?5 W: F# |" w4 X2 j8 e# y
return '<';- ?5 |" u9 g; w
else if(c=='(')+ ^% }! F" z4 g0 ~- \) c. v
return '<';
3 G1 X( I+ C( U% V' F: C m else if(c==')')
' y+ u$ g7 H# H F5 [ return 'E';
k3 Q# e# ?$ T! e% I+ A5 ? else
$ n) `$ w& d- Y) P0 r. _" B return '=';' X; Z2 x+ ^/ O6 T
default:' ]+ [/ Q+ c d, v
break;
" z& F9 Z) `3 o1 U }; A5 f H% A$ _! I2 @- U
return 0; # ^. b% ?1 n/ p8 c; x) S
}- R) g) ^% m: }4 {- B X; \
% S1 @, Y/ z/ N5 y3 m* w) z- J+ Xint isOpr(char c)
2 @3 Z$ ?# Z! @{
3 {4 t$ ^( v) S0 X if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
* R- j1 H/ a' w5 d, v return 0;
) C% U8 V- N( Y' {8 H8 U3 J' ^+ P else
4 x. ?6 x: w5 d* ? return 1;
, }- A2 R- O* t" n; q$ j" l. S0 d}' a2 f. V' R1 ?0 f0 m, `4 o p
% m! A* d* E5 f
float operate(float x, char opr, float y)
" L' Z0 L* W5 Z- D{
* {8 {* c. s3 W n float result;
: V6 b0 e* t2 g( R( O switch (opr)! _# K. G+ p" ~5 D7 W( p
{
0 P) @% J. X6 W8 f% X case '+':
* I/ s9 \+ Y4 C5 H; E$ V. g9 B result = x + y;$ Y5 D" |: @- _9 ]$ V
break;+ H; Q: k9 B7 y! B7 u, k( w3 l
case '-': 3 R& e# o1 p, j0 i6 t0 u x* b; s
result = x - y;2 o) X. B- t) n! W+ A) B
break;
; i+ f% O2 r0 o3 u% O) P0 r case '*': ) H- \8 [. e1 b c
result = x * y;6 c* _2 T0 b- V" \" @
break;
3 O9 s7 x' F5 N' D E: g case '/':
8 R; g1 F# n9 W% a8 r q. n+ O" B if (y == 0)
' p* y; [8 Z) f1 v, `+ Q {+ w8 x3 Q5 ?' D
printf("Divided by zero!\n");1 ~7 S# P) q; ?
return 0;! ~1 k/ J$ E6 C1 j( ]; V1 w
}/ A7 p. t, Z: j, _
else
1 | _3 V0 z0 A! p8 M3 A! p {
5 }/ i. `, t% t# B0 q7 V s result = x / y;8 f8 n2 }" S3 B! E( I
break;6 _% U8 I) t' d1 }: ]% O- ]4 ]
}
6 V5 g1 d1 X: C' C default:
* J; t E, V; n, @ h printf("Bad Input.\n"); 9 ?5 [ G& h# R; G
return 0;
. r, {/ n3 [0 f/ K# ` f* Z } }
. s/ ]- [& ^+ b, Q" W return result;
; {7 s* L: m) d% U' h/ w} 2 k4 ~- v N! V7 H1 U- ?
3 {7 S5 {4 c1 N1 e* o6 x& R: hfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/1 T. [! I* {& W
{, K9 b" w( ~" l2 o
Stack optr,opnd;1 N; n" J: \+ j+ v; U
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;1 b, y7 R/ g, w/ r9 ^' P
char c;; \8 ?( }- l! y, l% Q# [6 A
char buf[16];
2 I5 u' |; q" {, q2 J- T2 `5 Q J int i=0;3 f7 k) a7 M8 L. M) q! h
* H, r% w p6 M! H( [
InitStack(optr); /*用于寄存运算符*/. s2 R9 n1 x8 x) r$ [1 [( C3 d
InitStack(opnd); /*用于寄存操作数和计算结果*/3 ]8 S3 ?6 v; d; j0 C9 S
memset(buf,0,sizeof(buf));; w3 Y9 U3 i" a- b* a6 i, ]: e) Z: V
, ]- Y! N( Z( ^' {" m3 m
printf("Enter your expression:");
. D: }5 V b# O& T3 b 6 T& M7 V3 f5 R# Y
opr_in.ch='#'; T$ k/ E0 B" @0 S0 a/ `
Push(optr,opr_in); /*'#'入栈*/( k Q6 ?; X+ w2 t
GetTop(optr,opr_top);3 g. I: u6 R1 `' R3 D
c=getchar();
& l' t9 |6 C- z+ X8 Q$ e9 A while(c!='='||opr_top.ch!='#')
R0 T+ f1 b) Q4 B( |3 [# O6 `) j {
) I$ A8 o4 Q- L8 X0 t) W/ M4 D if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/3 y- U0 d. |9 G5 r x% m" Y
{0 t3 ?( {/ D1 f" A- m- w ~) t7 @6 `
buf=c;
) J6 ]7 V8 S9 z7 ]* i9 b! w) x/ l$ x. @ i++;. N Z+ j* A2 Y% _& Z+ j: F
c=getchar();! P* X/ D) q( a2 W' R
}
6 X1 j! o# V% p( x: P: B9 z3 c8 E else /*是运算符*/& j& n$ `" Q# L1 {" A
{
' p' A7 D# }9 j/ v buf='\0';; f$ w+ E$ u, `4 k5 s r' d
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
/ ^( t. c+ J( ^ P" E {* }! J7 f" ?1 z: v8 k1 M% O; j
opn_in.data=(float)atof(buf);
5 r o( v( W+ J- ]3 P2 S Push(opnd,opn_in);8 f* _, {. P8 u9 S2 G, g
printf("opnd入栈:[%f]\n",opn_in.data);
9 U H+ @9 ]6 N5 W q: |% K i=0;
- N4 Z( u% F) I memset(buf,0,sizeof(buf));6 D4 g# L& @* E* ^8 C
}
) I1 \* D8 G) Z0 H opr_in.ch=c;& X! u5 b+ G' k7 V' }3 n
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/7 W; O& R" ]6 J
{
- C W5 K& @+ h; ~9 c) t case '<': /*优先级小于栈顶结点,则运算符入栈*/9 w( C5 f; f5 U/ H+ m$ t
Push(optr,opr_in);8 f8 h i+ h7 ]" a% |
printf("optr入栈:[%c]\n",opr_in.ch);. Q( S" l. t% W `
c=getchar();
( c4 a; e# L Y. h& [ break;
% s% J- }$ i3 b _9 k case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/8 v8 B6 i& G- l6 ?
Pop(optr,e);4 V6 {# N% p7 F5 m, n/ n9 n9 W5 b
printf("optr出栈:去掉括号\n");
# ?3 ~" d* m$ [ c=getchar();- m" R' w3 d& ?- f- @& p' }
break;. \: u2 j! n9 u5 f3 z* N
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/( W0 u. Q, s9 A* s& j$ \- `
Pop(optr,opr_t);# C! l9 @" I: R6 h, {' E
printf("optr出栈:[%c]\n",opr_t.ch);! t/ q, |' h2 } x7 p, h' ?
if(Pop(opnd,b)<0)
@% p" B% s! T {9 j/ g; ^: m \( S( r( p
printf("Bad Input!\n"); y9 t& |" g/ S) Q
fflush(stdin);
3 z6 S" o# c6 D4 D: z return -1;
) N U7 a3 g* V" \ j& D }
' `7 x e9 I q L _$ a1 O1 m printf("opnd出栈:[%f]\n",b.data);
0 `4 Q; i" c0 @' Q5 o, I! V5 O if(Pop(opnd,a)<0)
. W5 |% W3 P& X/ H* ^5 m% s {
. u+ e3 f, { g( S3 V printf("Bad Input!\n");8 R9 n' i8 G/ x
fflush(stdin);' V9 D, G& `' J' f/ G* N
return -1;5 x( u6 m- S! u3 |$ a7 Z
}
; [: Q( l) n6 g9 o0 z printf("opnd出栈:[%f]\n",a.data);8 V$ f( }: `7 o) S) e
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/* i ?7 C" k$ s6 w8 _
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/! L" Q9 K1 D- [1 J
printf("结果入栈:[%f]\n",opn_tmp.data);
e4 ^% D% m( ?( l# c% M break;. `0 }- k# z6 L% _3 }
}
. f, w; h: T0 k& G8 k; [ }1 ?* Z& P T, |
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
D. H( S. `3 _8 z, Q }. T: K" C' Z7 M8 [6 C3 t
GetTop(opnd,opn_tmp);
) _! b* Z7 J. w9 z8 j8 b6 z2 ^ DestroyStack(optr);% L" Z& o/ g$ ^3 w2 k4 C& P
DestroyStack(opnd);' d8 q9 p$ l1 e& D0 H
return opn_tmp.data;
" t. F" o5 P/ L. ~: M+ u+ b- U}
" V2 i$ k$ e7 G
8 Y" i g' ^% Z* J- pchar *killzero(char *res,float result)
" x- K5 c8 b5 a; _{) ]- J- l: W: E
int i;
: L) [% e6 l: a: b* j; z$ p
1 d' [) c* y7 m4 G. h sprintf(res,"%f",result);
7 p/ [9 L' P" X9 M! O& I& c8 R i=(int)strlen(res)-1;3 o* c% D% B: l* E5 c
while(i&&res=='0')% P. }: `5 U2 w; e- W! Y9 L
{. I8 {8 `# d7 F: L0 l
res='\0';; _4 b2 d, U, L( X! ^$ c
i--;
% Y7 M+ D' A; h0 n$ }. X) a }3 K3 p' h- ]% @. Y/ ]- ~9 L
if(res=='.')
( [3 y: Q% {* M- @: M, G res='\0';
: X! ^ w) ~$ D6 P$ Q7 H+ }' f return res;" M0 ]! B4 E1 T" P, ]
}1 t$ m( O6 u% B. G" }
& R- S3 ~$ o* Y. A7 p( _int main()/ Z2 _& @9 s$ @
{
* \; N# [- P' j char ch;
# r5 Q) |* ~6 M char res[64];
- l/ D+ B1 C$ U- w float result;* u6 z. T( A! b; d
while(1)/ R$ m6 K5 @, D* c
{( G4 m" P2 z: t/ X3 X/ C
result=compute();- y/ i* |% _) n
printf("\nThe result is:%s\n",killzero(res,result));, D3 V5 K# i) f
printf("Do you want to continue(y/n)?:") ;0 B+ O# M" R2 ?) @
ch=getch();
1 |/ {, t5 ^' U M4 H putchar(ch);
( }8 _) j+ b6 R) x# \ if(ch=='n'||ch=='N')
8 p% V- n. o0 S+ H& Y break;
& e2 r0 U/ l3 N9 s2 V, x" Y else ~4 A, C: P- O: j3 @
system("cls");8 c+ a5 |4 h: X s' C% U6 g
}/ N( i" r. h' @+ c- D+ J* t
return 0;
& }' O5 B* ^; t; v}
0 m. L7 ^8 {/ l/ R H: S) S% A6 g! x( N; }5 b- T6 y0 l4 X
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|