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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.3 y) }/ W$ H8 ^7 | z4 [
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
6 O+ R4 {. a/ D0 m& S6 S& t/**************表达式计算器************/
8 y! C' Y" l8 Y) k: w#include <stdio.h>: l* u; q& r4 W& {0 L# k4 O
#include <stdlib.h>
+ G% s2 _7 N4 V' ^( o; z& C5 \#include <string.h># g7 M: S0 {* A0 g! p
#include <conio.h>
- I8 l7 W5 [$ }* ~* @) F#include <malloc.h>) j% U6 p, e Y# D( }0 h
4 s( M$ N* z" L$ ?+ V# ?9 R+ Q! ~
#define STACK_SIZE 100
/ |3 _. R. k9 e f#define APPEND_SIZE 10
; I. C% B( f3 s( n, s9 ^
7 l" L0 y. y v7 }, k$ G7 fstruct SNode{( W6 S% ]5 i+ V& n1 p
float data; /*存放操作数或者计算结果*/
, P4 K) f. ~7 F, j- y% V% y char ch; /*存放运算符*/2 c, ^3 _' C; @: Z; F% s- P% A" b
};
% W+ d) X4 @4 R& K3 B/ J# w8 J8 @# S3 C2 K0 n) z5 b( Z
struct Stack{# e: j9 j6 p7 ]' W P
SNode *top;& r& C0 J2 V2 V0 m0 x
SNode *base;
6 [* J4 J7 G1 | int size;
5 R, e2 u2 x3 P) C};
% d) h2 _! E% \: M \+ s- U
# \5 q% k2 ^+ J- `; V/*栈操作函数*/0 Z0 y) h+ R2 ?) I6 H8 f
int InitStack(Stack &S); /*创建栈*/
' X0 s! _7 J3 W2 Dint DestroyStack(Stack &S); /*销毁栈*/- B- [( W' T4 h, n) J n& l
int ClearStack(Stack &S); /*清空栈*/
! a' ^1 D5 Z- a5 V- `7 _8 U6 z+ Wint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
0 M0 N2 A* K" C$ r" E* B) ~int Push(Stack &S,SNode e); /*将结点e压入栈*/+ K2 e. R. c) O; `3 _. }
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
$ l) x( n- b+ i4 g
& W/ ^8 f" B" P7 r/*表达式计算器相关函数*/, S6 G7 h$ U# l+ A8 c
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
& w) ?, e7 V1 E/ x5 P' s- m" Rint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
# W* E( n$ V: v* ^9 `0 zfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
r- X8 W5 ^2 j0 m# Gfloat compute(); /*表达式结算器主函数*/
, f+ b) ?" T" Z& Zchar *killzero(float result); /*去掉结果后面的0*/
6 p( j( S( E8 u9 a3 j7 n2 \2 |4 T
int InitStack(Stack &S)& G# g7 Q& m0 i! z3 h9 `/ }* P
{
& `5 B0 d7 U0 h2 A. F S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
/ C- ^: r5 L0 y) K7 z if(S.base==NULL); T* B* n i, b
{0 \9 ^9 Q w5 L% M: T
printf("动态分配内存失败!");' ~% D6 [; |9 }, z+ b/ a/ a4 ]
return -1;: m9 a9 ]1 o+ A8 I4 d
}
7 z3 G; {! P! I+ c5 E, { S.top=S.base;
3 O5 }: b% T8 `" O1 t' f& P" H7 m S.size=STACK_SIZE;2 d. h, ?8 C# ?# I1 g, p) _! K& H
return 0;% H8 A! x" {* s2 k2 Z7 I
}
* k, k( g, r5 _, }+ _2 @* s8 _! V* x# w$ ~* z2 W
int DestroyStack(Stack &S), K3 T9 H& L3 e& F+ s% K0 F$ N6 C
{. {$ x- @- W0 N0 s" t
free(S.base);
4 \# o. h4 Q" [* }- ?6 s; i1 o return 0;7 N3 U# u3 @( S9 b6 |
}5 k6 I( {5 J% t; ]! z6 F
) R2 V3 O/ e$ A7 A! q+ Bint ClearStack(Stack &S)
7 U q2 M. ^6 u4 S: }9 N{4 g0 ]! s& ?" s9 ?2 h6 c
S.top=S.base;
1 Z% l% I, C. V1 @; o return 0;6 M" W1 v) }) [& o7 Q$ ~
}
8 @8 V. E) v$ Y, [6 F- Y* Q! c! H+ X/ S! a9 L
int GetTop(Stack S,SNode &e)! R( O* P" t6 z9 F, o% P
{
! r/ @6 e) G% H, q if(S.top==S.base)2 d2 A( |2 |0 s. |: W
{1 N1 H2 |4 ?7 P$ q
printf("栈以为空!");. X+ B: T( r5 |/ h& ^! T
return -1;7 g; z; r( D- O! z5 R
}( E+ h5 e& }5 z2 ?3 ^
e=*(S.top-1);" j. ]/ @* s. z
return 0;
; I* ~% W( c* l/ _}
0 M8 `* h' ]9 t( S! w: w7 `1 q8 E. V0 T% u
int Push(Stack &S,SNode e)1 y2 V* P* x9 L, C; L3 E; r4 S! Y* \6 q
{
5 b! F0 b a* t* m if(S.top-S.base>=S.size). z S$ S/ s6 u- y7 V
{
/ V m1 f2 }4 m) y& {6 ^ S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
. R. p3 d; j4 b: {0 ~. ] if(S.base==NULL)& R7 B, a! n9 o8 J* d, Q
{3 A f1 l% E2 l* D2 o
printf("动态分配内存失败!");, z. f# A; m( I! Z; t3 ^8 k
return -1;# f' l5 B3 F) @
}% I/ h% r+ c$ c8 P1 P* T9 Z
S.top=S.base+S.size;( V% ~. C/ v, \- Z
S.size+=APPEND_SIZE;& d2 N4 h2 \* w n- `: l' ^) A, K
}
% R: l/ H' R, G& j; m( U Y, G; C' q *S.top=e;+ W2 K+ B# u4 R/ z7 Q( [
S.top++;
1 u$ e2 l# T) p$ _ ?4 l# N return 0;
2 F) U+ ^# c4 B$ |& Q}
& p: x8 V5 a1 `. U6 P1 V* o( s Y' e
int Pop(Stack &S,SNode &e)6 ?! F. V% `. Z9 S" P6 K
{" n `) Z5 q7 N1 V" t
if(S.top==S.base)6 n W6 G1 g6 e. x( p! B+ p4 ?
{
1 ?/ d8 Y' Y$ D- @$ S7 J printf("栈为空!");7 K, t9 H: ~& ~
return -1;
+ ~" m9 U7 L8 S% [# @3 \ } C; K8 ^6 i8 s4 ~
e=*(S.top-1);
' t `- P: S! g6 k+ o9 o+ Z/ ? S.top--;1 B8 @6 f( b4 K0 O! q: k* p
return 0;
% w1 Y- F- i; B& [9 e# `, D m}# \5 L/ t4 `( h8 p
3 y/ H( D9 l* Y3 S* x9 qchar get_precede(char s,char c)
V5 C: I6 i6 v- y8 Z& ~2 G. H{: O+ t' R# w& F0 v, L. j
switch(s)
% H; w. x/ E* b+ j- L {
- S1 j; _) t! q. i9 h% O( P case '+':
3 ?& V3 r6 K2 [( L \- z case '-':
6 z1 [* ?, k% s L if(c=='+'||c=='-')
. d( T+ t; A# `' F0 _% C return '>';+ O; d5 z; c h/ z
else if(c=='*'||c=='/')
6 \; }" `$ K I return '<';2 C% @ F; r+ [" d' L" v9 e5 T
else if(c=='(')) w4 l( F- W: M
return '<';
8 j* O% ]0 }* ^) F8 {6 H else if(c==')')9 D; L/ m# X! f) y# H
return '>';; D5 @" P' R% M0 r' g
else
I6 G6 C; E+ k4 ~" ` return '>';
6 B l) O6 _+ K! x; O; W$ U& _: ] case '*':5 b" e5 f2 F- g- u7 _ @0 Q
case '/':
5 U1 I( Q$ ] \, r if(c=='+'||c=='-')1 N/ x9 `. @. s
return '>';& [+ |6 r+ g! h( X
else if(c=='*'||c=='/')
1 Q# ^% p* b* e* f3 U! A' C return '>';: _2 Y: p4 k1 D. E0 r
else if(c=='(')
2 V/ K2 f9 M! C% U return '<';
* V: Z* }" L* U0 b7 Z7 c5 Q else if(c==')')0 H$ o9 i$ M5 `# h, f
return '>';
, y+ Q; h! i1 p2 ?! j else
3 K. T$ F* v" E: _* W0 h+ \1 C return '>';6 _: y. ?4 N: H6 R# P: }
case '(':
; f" ]) O9 O' a& }' ~: n if(c=='+'||c=='-')% f ~, g4 k% J; ?9 \
return '<';4 l& J% q* N1 @- @. u2 u, B
else if(c=='*'||c=='/')
% ^/ S9 q. n9 ~ return '<';
5 v3 a# A/ H3 O4 X0 u) ~ else if(c=='(')3 j4 O0 }+ R; O1 P* N
return '<';# x4 @+ l/ J' y8 Y' n9 {2 x5 g& Q _
else if(c==')')
\4 g" ? v7 N return '=';
! q5 U& ?5 k: q4 U else
3 \" `7 L+ W! R% c: {( g6 i return 'E';7 }, L' Z& z7 E [
case ')':
- [- ?% U9 V, O- ^" N, l if(c=='+'||c=='-')
3 y) H# {, [# `! d2 Y* b return '>';; L6 u! C% s) _& v
else if(c=='*'||c=='/')4 s1 i) k0 Q5 y7 S+ @& B/ K9 e& A
return '>';8 E8 @7 r* Z7 i- L
else if(c=='(')4 A/ f* \0 J6 {9 m9 z* L
return 'E'; E$ o. H7 L, @& d# W: s+ r
else if(c==')')
' T. x: p0 c8 ?9 V2 }! L4 | return '>';
6 |" `4 }% S' I3 D else
2 f. c' b3 C* t+ M return '>';
+ p9 }. w5 W$ z1 E) r% B; y v! T case '#':6 ^' D3 Y, _( P. B, [
if(c=='+'||c=='-')9 p+ t3 I3 X! z
return '<';3 K; S' X. v* S9 J6 r6 V4 x2 n
else if(c=='*'||c=='/')
7 r& F5 X$ Q1 r/ k$ f return '<';! d* K% Z; v; ~) |* ^, B
else if(c=='(')
- a6 C8 P6 T. j% w+ c. S5 J return '<';0 `- A. p% t/ @8 m$ m, p g* `! o# M
else if(c==')')' H/ k# M& f4 t' v* p& ^( ]& u7 r
return 'E';3 r" F( m0 ^* J. I8 W ~6 ?
else
/ s6 Q3 h5 l7 L) R' E4 i return '=';
/ \- Q* C( \; b( u8 R( G default:
: h' b- x7 b8 n% n. B7 J8 C% G break;
3 x% w- A- m1 J# k: E }* v; _3 N9 ~$ I V4 x' q
return 0; & U) e* y+ v2 m' j! L# x" E, ^
}
$ v: x& f5 |" e; W! p3 @" ]5 ]/ R6 i$ J
int isOpr(char c)& M |# T8 V1 G0 K+ N" X) `
{
- }6 w' e" I5 R if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')+ _. q* }# c" G' z, K
return 0;
" i6 B( v; A1 ~ else 0 e5 E! ]3 {7 O% c" E) J4 v5 ]
return 1;
8 a$ j- I9 H1 ~' G' K, A}6 Z8 }. C5 E4 `! C; p- A
8 x/ F; l' K }4 P, F1 h( c
float operate(float x, char opr, float y)
/ ?* V L- z) \* A{
, ~5 v3 y' k1 W float result;1 H7 q$ Z0 |5 g. P9 _ E+ H
switch (opr)
8 r9 h5 R+ M8 X( y" O {+ I3 a2 p7 v: \ n! a$ y+ X
case '+': , P8 y9 x, M1 E. r3 h3 C* a6 [
result = x + y;, F1 X. s3 u2 M% X
break;8 O8 I1 J5 h) e: H0 z( h/ B1 F
case '-': % W' [! F/ s. z8 v9 u- k4 R
result = x - y;
+ l) S. v' q( ]" `. _ break;
0 R7 S. D! C) Q. `( J j case '*':
9 C0 ~8 E4 [" N" p U result = x * y;& n/ l6 b/ A( C7 T' M0 q% @
break;
k3 i7 H4 A1 N0 `- K/ k K$ e+ X' h7 z case '/':
% Z( C y2 j) i7 ^% f if (y == 0)0 x, T8 O1 U' s, H9 p+ y
{& P, z) { T5 H
printf("Divided by zero!\n");& G6 d; f- }4 Y! [. Z0 `5 E
return 0;% ?% Y. h/ i+ _% S$ }
}
7 E6 }! f. S5 B S, w1 U else
. f' z* c8 `6 ~) W; D {
2 ?& [6 S4 E5 t6 F' Q result = x / y;+ L. G7 i `8 z( J7 a* j$ F. r
break;
+ R. w: y9 p% b }9 H% k) l* e# C4 t* P4 ~
default: , h7 o# r A9 N: ^( M
printf("Bad Input.\n");
$ U% a& a& [8 E return 0;# E7 W2 b5 R2 }- {
}7 b) z" T! j* e9 |
return result;$ P4 j7 j5 v1 i' W. w* D+ Z
}
3 ?3 k' j* h4 C/ G2 ^! l7 e2 B E
+ ]3 }& E; ~1 {" v4 C2 @/ m- Yfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
, @% s$ o0 l8 L- |7 E5 ]- K{) K2 t4 Q' [' ^. q+ W7 T8 {" v1 `
Stack optr,opnd;
! {" O$ F9 k& |& X( K' K' k5 x7 r struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t; {- J: ~5 V& H9 h2 F, p1 N y, G6 h
char c;
$ o: s2 c1 y9 Z. v) [1 w* Q$ B char buf[16];
: ? W; u; h# @& N a. l int i=0;
5 e3 o( a* C8 Y# W$ Z& I# B; I
4 b# Z5 p$ A* B5 J InitStack(optr); /*用于寄存运算符*/+ y! h9 {3 v1 m
InitStack(opnd); /*用于寄存操作数和计算结果*/
4 G5 ~! N7 _5 N" }, ^* D memset(buf,0,sizeof(buf));. E6 p5 g) c7 E- `% G
$ X, R' Q1 A/ O4 [- E, H0 Q/ [
printf("Enter your expression:");
1 [1 n! g+ o" H% ~; `& [! h/ F
6 @) |5 Z$ n1 W. d7 h: x7 r opr_in.ch='#';% E4 @' z# e8 y" u
Push(optr,opr_in); /*'#'入栈*/( Q e, n. V l0 S) s0 ~
GetTop(optr,opr_top);
. \- ?; ?! ?- j" A6 i c=getchar();
6 K7 W* x! E3 H" x while(c!='='||opr_top.ch!='#')
% g( ^4 T0 d' E4 J {
1 U# j2 B' P R if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
; p! {# c. r0 u' } S9 g {
( _7 O6 J/ b- w6 \' H) S4 G buf=c;! l: w6 g4 ]* X1 T- Y4 b
i++;
/ q2 p9 ?( Z. a' x Y c=getchar();
: ~: G; f/ g% |$ \ }
G) P! u' U6 X1 i% l else /*是运算符*/
9 V, M& H* e% A: R# J1 T* P! k8 V" w {$ @% L0 e+ Y& |8 \. {' L3 j4 T
buf='\0';# g( o; R( p1 |, b$ A2 D: V
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/ x4 b) p: g0 \0 h) M8 ~6 q1 v4 r: f
{
- H$ s- ~% G R( b# u opn_in.data=(float)atof(buf);
8 Q% q) O: X }3 x; n" [( V Push(opnd,opn_in);
" {- n1 h( ~/ ~% {3 L* h printf("opnd入栈:[%f]\n",opn_in.data);
' U) c% W R0 E0 t i=0;
k+ R& D2 C3 H9 |1 N memset(buf,0,sizeof(buf));1 t0 G6 g4 o d" s! {8 W
}
( g: a$ v7 e, C3 K" [2 j, ~7 y opr_in.ch=c;
9 A1 M9 x/ x% T% S8 w9 R% o' B switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
' |0 J& \; q' p! F5 M9 a* o {5 X+ s, X7 n4 O9 J6 f
case '<': /*优先级小于栈顶结点,则运算符入栈*/$ E" m) D/ h( W& @6 `6 E
Push(optr,opr_in);
3 d: y5 v* x0 Y, N8 X printf("optr入栈:[%c]\n",opr_in.ch);
) y) c4 P5 K' J7 Q" V8 q c=getchar();
! A; I" x% P( U break;
; i: ?: \( X4 J! [ case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
# ^6 g$ o6 | v) a' A Pop(optr,e);
, y' W- g5 q7 T0 A1 ~ printf("optr出栈:去掉括号\n");
/ f- S! }" p: l& n c=getchar(); ?4 C6 I' \7 F' `8 a% O3 a/ {
break;' t+ a" \% }2 F) g
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
0 c. E% l8 Q( V2 X) Q; I" } Pop(optr,opr_t);
6 [/ R1 D; E/ N0 M2 {4 F printf("optr出栈:[%c]\n",opr_t.ch);' ^9 v, |" p: Y2 s: p6 J) M
if(Pop(opnd,b)<0) t7 O+ ^" x' Z9 b: [% e% J/ y
{2 `5 P# v+ P2 r/ Q
printf("Bad Input!\n");" a h7 E6 i- I% a- y# G- V
fflush(stdin);
, j& d- z$ X y' M return -1;
* U% F) M$ [1 t* H9 v) \* x }
; Z; {2 [; v t! s0 S- R printf("opnd出栈:[%f]\n",b.data);- L4 d+ M& x7 C* p9 t' x" Z9 j
if(Pop(opnd,a)<0)
. X+ d, ~) A' l x9 l& ? {
! o7 p1 H9 g; L4 X' m printf("Bad Input!\n");, U9 q' _+ g: L, g+ p2 g/ C4 Q0 B
fflush(stdin);. d: x& {5 b8 P0 t( S( V0 K" }5 z. S
return -1;
/ \8 |' E# a$ F, | }
: O% S; k; C/ K printf("opnd出栈:[%f]\n",a.data);# w* |3 b, l: F$ k: ~4 L. ^
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/. H! L9 X" w8 T& R' D; `9 k
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
2 W6 V. G( g" R) ^9 E& H printf("结果入栈:[%f]\n",opn_tmp.data);+ i$ f0 ~3 J9 q- q0 j" J7 f
break;* t- n+ \: ?" H4 p0 L3 ^) x h3 C
}* z2 S" l4 v& w0 T* G% g
}# P" ]/ D- }, P3 t2 }1 `. G
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ # Y8 L2 v% `9 A: H5 V+ L$ w( L5 W o5 @
}: J$ |! p4 b( o/ |/ H: d
GetTop(opnd,opn_tmp);1 W" u: ] U, ?7 |' l; q$ d# ^
DestroyStack(optr);
6 r: C T: h1 e- K8 X DestroyStack(opnd);% G$ Y+ f3 h) O+ h
return opn_tmp.data;
5 x1 w( g$ S& {+ S- t% K}
2 C6 u6 C# ~* ^' o: v7 \
% B, [9 ^: Y6 `5 pchar *killzero(char *res,float result)
6 _% d. N( U6 ~& h1 ~{2 W s% L& w. ?. R, G
int i;$ _# f" O8 A0 B, C4 |9 z
# p" T) Y( J) i q7 P7 E3 j. j- ]
sprintf(res,"%f",result);
$ O. R- R: {4 j5 f8 `- w i=(int)strlen(res)-1;
* }4 K9 @. Q: b0 d5 D& T while(i&&res=='0')' q j# d/ R! k
{8 d* c u# `& U& a3 L+ s/ h
res='\0';
7 e/ U8 l4 |8 u/ f2 Y i--;
/ L# _+ @, n& R$ h$ N7 E4 ] m( W" u }
! |- f J* y! V f4 A if(res=='.')
8 N! s! `$ h3 b2 C3 b" L res='\0';
4 h( R! b0 E/ W8 M$ C0 c7 m return res;. o5 d' u, y$ U6 E& \* P7 u5 C( f
}% B5 z5 n1 m- S: P% y6 C
$ o: P* b$ F+ }5 K% D/ Cint main()+ y( c4 Z& m! y' C( R1 z" s+ l
{9 }, S& E( m1 s1 n% b" {
char ch;
5 u+ C5 c% I$ F( P+ m+ M& j' ^ char res[64];1 u8 p# }! I) P
float result;/ g O; M/ d4 V s; I/ e$ L5 K m
while(1)
. m* s) r) @, S3 \. M! P, \ {+ I$ S9 n* K; s0 w. m$ M
result=compute();
( Q4 d+ j G$ S0 Q printf("\nThe result is:%s\n",killzero(res,result));
6 A; _, f' O8 y2 k2 q printf("Do you want to continue(y/n)?:") ;/ e& P: A, Q Z, Z
ch=getch();
) J( L3 W+ q- U putchar(ch);* d4 g. X) [. u3 h: m& m( L4 o, J
if(ch=='n'||ch=='N')) H* }( Y' L- A* w; T; k( J
break;2 b3 [- W/ p& u# D a% N$ p1 I
else
7 k& }3 J6 Q+ C: z4 S, |# W system("cls");
& L& @1 x9 r% u5 i t1 e }! b( ]0 d3 O6 `1 h* K* e/ c# I/ n2 T
return 0;6 G& s; B& F% Q% M- T3 q
}' T2 U8 V7 [& ]9 c
( n- z/ F! e3 f e- [
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|