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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的., x4 t0 O' {/ |1 K
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=( T1 }3 G+ g- ?* H0 T; C
/**************表达式计算器************/
/ V; v9 P4 d9 J) l#include <stdio.h>
7 g( k8 t, u5 x6 d#include <stdlib.h>
$ k) V$ T; r$ \* S5 }6 Z* Y#include <string.h>- M- U- d; o- b' n
#include <conio.h>4 K( M# ^* j& Y$ Y% x8 \0 R( a* W
#include <malloc.h>: B( r' \# B$ E- ^6 Z: Q7 M
4 `5 |- t% E1 D9 {9 N) @3 C5 ~- s#define STACK_SIZE 100
& {* i$ M+ N8 Z# M3 B/ g+ w3 C#define APPEND_SIZE 10
1 |/ Y1 m u& W( O4 X
A- f" C' Q z* q2 n( Fstruct SNode{
& o; p# z s; _# @0 N float data; /*存放操作数或者计算结果*/
) \/ r8 ?8 [2 r4 g# ]. G char ch; /*存放运算符*/
2 k v4 m, L# c8 V8 Y9 }2 `};
) Y+ @7 P! d% V
, j5 ~6 S7 T2 L9 b. S/ N0 ] a+ Ystruct Stack{: Z$ ?$ W4 F( ?+ M3 c
SNode *top;
5 p! z# a$ ]. V3 T% x SNode *base;
z: U$ g9 z$ r3 T/ S int size;
4 T# i% e" T: ?9 ~! U7 M8 W8 b};
/ N" t: l+ ^: b/ ~5 k
4 M+ s+ m- t8 h- H0 u3 Q; A" F0 P/*栈操作函数*/
$ l$ Y& Q8 b$ k2 K( `1 g3 \% _8 X5 Uint InitStack(Stack &S); /*创建栈*/
" u: S* y' C5 D/ L" Y$ y% ~3 B" Fint DestroyStack(Stack &S); /*销毁栈*/3 M: L' R- [; N8 e
int ClearStack(Stack &S); /*清空栈*/
8 }9 A1 S4 `4 Tint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/% {# K$ ?) L2 v3 w/ Z/ r
int Push(Stack &S,SNode e); /*将结点e压入栈*/
6 {2 ~7 F# ]" K1 }1 s$ I% hint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ a& B5 z9 m, F. a$ }( P7 ]9 K
$ ]: g7 L% M' y- e6 `, |
/*表达式计算器相关函数*/
' U8 I3 Y t9 J$ R$ ?char get_precede(char s,char c); /*判断运算符s和c的优先级*/
# C y' [2 F( g5 h# [' Y5 E/ qint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/% T$ V! g- f+ o' B5 X$ Q
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
" o9 ^/ s0 H2 N( Ofloat compute(); /*表达式结算器主函数*/
3 K8 }* |% ^! W8 }) pchar *killzero(float result); /*去掉结果后面的0*/ 8 j* S3 g% R6 t6 ?9 a: {8 {9 k4 E3 ~
( }4 @# I8 Q; V" ?, I; ^
int InitStack(Stack &S)
# r2 x% I L! C" \! R{
+ G a# i) c4 M0 n S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));8 ]4 H' ~0 ]+ X# n7 u9 S! \% j+ a
if(S.base==NULL)! ?+ O" _$ C: Q0 ]$ i2 \6 s" T+ u
{; w% [# h9 Q! |* r- S
printf("动态分配内存失败!");
5 M- O% C' t1 a3 [+ Q2 u return -1;# h1 A5 Y2 z9 X% ]
} Y1 K$ P7 W$ t% E
S.top=S.base;
: o1 I6 I" k3 |* v$ Z% K5 s: t S.size=STACK_SIZE;
* w R$ J2 u! }/ y A2 ], R$ F3 P return 0;. y" e9 T! {' f' f
}
+ R# v4 s) G- ]5 y- \& L* d/ r$ a9 V3 k
int DestroyStack(Stack &S)
1 Q) L; }* v, E3 L0 f{
% n* @* s3 N. d+ _7 q free(S.base);8 P" H0 R" \; A9 e! X, H
return 0; d( E$ @- z* ]/ i$ B Z
}
( x) m& ^4 j* i7 S+ F& u3 e3 A$ t* H% E5 v6 f- ?9 y
int ClearStack(Stack &S)
1 S) c* L% A4 G{
+ z) e! O( h2 ]9 a6 E! J6 I- M S.top=S.base;( ^0 r* s3 [! s
return 0;
1 V; `4 v* e6 F( t}# g+ T) A: k7 o ^* j& f: j( |
; }! [! `/ r% B Qint GetTop(Stack S,SNode &e)3 N" }: Z8 ?% Q+ c/ V# v6 l
{7 ^/ [# I" B. m: J
if(S.top==S.base)
+ H' f$ K: Y& S! \ {
8 J. j; j( ^1 S/ Y3 p, D printf("栈以为空!");) c/ @' g5 x2 `* N* |8 ~
return -1;
6 B Q3 Z, \+ [& d, z& L } l6 P, e/ |% k
e=*(S.top-1);
5 |& M, h2 O; Q4 h: z9 a return 0;
- \9 `1 [8 [- V7 V6 \/ j3 b9 b}: C% _$ @- U7 @& s: E, J, Y7 C, X
+ N6 ~; ^1 _7 P9 b7 k
int Push(Stack &S,SNode e)
( z% E+ c0 M, w. z{
% w8 K! P, ~5 \; H. r if(S.top-S.base>=S.size)% P- X; P0 N# J2 o' t ?% H' s
{
: h) h2 [* H' m* s7 v/ @& c9 y S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
+ K$ c4 _; W8 a# a if(S.base==NULL)0 T: U* D1 @0 T% d5 y
{ D$ I' Z- H4 q
printf("动态分配内存失败!");7 H" K; B' I6 N3 y
return -1;
2 |* {$ ] z7 M1 A1 I3 E, J4 V }
9 r% T- H! I f" | S.top=S.base+S.size;5 |& M5 G8 {2 w5 u8 L
S.size+=APPEND_SIZE;2 k$ e8 n1 Z/ B4 y- s9 B) M
}
/ q2 i& e8 l6 I* B* M$ s *S.top=e;
3 {$ Z8 U$ m; b9 E3 B, s4 { S.top++;
( i$ b9 |: N2 \. p0 F& e return 0;0 m' E3 T9 |- W) s
} ]$ W0 B# T( \& S! s
) h1 l6 P2 V' Fint Pop(Stack &S,SNode &e)
. h" h- ~0 Y' v. x{
/ M; a# m; D" g7 Y% w+ [ if(S.top==S.base)! i; F) C) w5 }: E& f- q3 I- q
{# J( Y4 P! @2 k4 g9 ~; ~
printf("栈为空!");
: |& [ S: \! U4 C# {2 F2 P return -1;
, I' }; F) K5 U- c8 f2 w/ s }" |( `+ F( g$ F; P
e=*(S.top-1);5 |% e* x# ~9 D. J
S.top--;
3 S% O3 n b; ?5 Q: v* m4 N return 0;
4 w' k4 ^2 y! E5 n U/ h* o. {1 _}" P6 z9 t, j L- I9 D' \, C
1 H8 j$ @* T0 w1 _$ [char get_precede(char s,char c)
" h! Y% ?0 r- }# {{
0 {" s2 D+ s }; n1 _ switch(s)
1 _+ F3 y: h- x) ^% y @5 ` {( ? N' I0 P0 Q; i# V( g' E
case '+':
' @! l+ V8 g A/ }: X- A8 w case '-':! G' w! M- E* j
if(c=='+'||c=='-')( w; \5 a8 W' b; W* J6 }9 k. c! k
return '>';% c" ]- a7 @) X4 W4 E
else if(c=='*'||c=='/')$ w" A) G |5 H
return '<';
8 n4 X0 @( c+ T: ]+ w else if(c=='(')
1 {6 P; q. H1 G1 |( p6 h return '<';
6 D5 A/ N. y) c5 w else if(c==')')
& l5 k4 d( _* I* u return '>';
. k# U5 [' `$ F0 S; D% W+ ?3 L else 1 `: j9 O7 n- ]4 g3 p- [/ h- p
return '>';/ W r3 M- L2 F! z+ C- S
case '*':
8 Y u, N0 w. X case '/':) o8 ^) D* c: f5 }3 [! U+ [4 D. [) y
if(c=='+'||c=='-')
3 [+ w, F6 C7 _5 I- t& ^0 S return '>';, e2 d. y. }( j1 x1 J" X# l
else if(c=='*'||c=='/')$ N0 N, H9 e$ w/ ?9 m6 h
return '>';
5 t, E9 @; m5 ~0 R) _ else if(c=='(') c" L, Y) g- n# E! g8 ]9 A, d
return '<';/ q) M7 U1 i6 A4 K/ H
else if(c==')')
5 V) H0 C3 F; w* A return '>';
. \$ t9 Q$ T( ? else2 b$ C. T2 s% r6 K$ d
return '>';
; F; [4 L0 k; y( Z case '(':+ @* L) c6 r# ?: f# i! ]. ~8 z4 M
if(c=='+'||c=='-')
% B2 m1 T% o# G @- Q$ U return '<';
0 v6 U S+ ]0 U; D, d$ b# v9 H% i; N5 G else if(c=='*'||c=='/')
0 I' U. I) d7 F. ? return '<';' V0 Y) ~' |' B& m
else if(c=='(')7 O" G% l. A# [* N! \* P6 E
return '<';
7 q9 e# V8 j; T. |2 X9 u else if(c==')')
i; _% U% Z' u return '=';
+ Q8 O; {7 d( P9 V else
2 N! e7 [" X7 T& {2 \2 ` return 'E';. h* t# y, ^) I0 z$ Z0 C
case ')':" I- B9 U2 B8 v o
if(c=='+'||c=='-')
4 k1 v" ]1 E* H- G return '>';7 x) W: b% [% f0 ~; H
else if(c=='*'||c=='/')7 s& v9 Y: [ H" M* ]; E7 q
return '>';$ D( j5 m+ `7 I+ x
else if(c=='(')8 E% x3 K, t; [3 b7 T$ b" r3 G/ S
return 'E';
" c8 w# ]! F8 p7 n2 l7 `% n/ E else if(c==')')
, ^; R$ V+ h* G( v return '>';! s% H/ U z8 e) G2 }) t
else: D6 p& m* @, o) m5 @
return '>';4 l( B- z: k% T/ N7 P: \
case '#':
/ w+ K: J' ?$ N) p; E1 Y3 j if(c=='+'||c=='-')3 A K* p% M; m% v+ ]9 I
return '<';+ Y0 A- U3 `- Q$ F9 V2 D
else if(c=='*'||c=='/')# o2 W) Q I, E! d+ t! J
return '<';
- H4 B1 W) M( c; y% ~ else if(c=='('), R6 B+ s% n1 f' F- J; P
return '<';9 d* a, @& `4 g" z D: n
else if(c==')')
5 l! d" Z/ q) |5 ~$ I+ @ return 'E';" {* k% Q- e7 t/ t1 z
else- t& U) b d, @/ r6 _% y) u
return '=';2 A7 S% Z+ j) w+ l$ F; z6 e
default:
! c; o. s, ?6 ^2 M/ l' Y break;
2 n6 I8 g, l( @; X2 F }( L5 {9 c' W! ?$ g& u, Z7 H
return 0;
9 O- ]" l5 N$ H; e}
5 h% u! |( G) K: S+ F* h. ~3 R5 k9 [ W/ h! h$ D3 M. F
int isOpr(char c)( Y7 }3 E7 }8 x0 B% D+ k1 [3 t
{
" d, L7 ]5 N# K( P if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
+ o5 J6 n1 J; ] return 0;9 G0 r# v6 Z2 c4 O: Z
else & H% G: p3 P& \" u1 _
return 1;$ _2 X7 c9 s6 [7 C
}
$ o( |- w2 C, y6 p1 l' V( a6 Q& N) w2 F0 r. j, }( n$ f0 }4 ?" V
float operate(float x, char opr, float y)
5 C6 E0 m* U0 S9 `. q( i{6 ]. @7 |( C# l0 u7 C
float result;
8 \' ]+ Y6 d( |. A switch (opr)/ y8 y5 {# s% `1 E
{# f# d1 Q4 a; _8 `
case '+': % U7 J- G$ `- {' {2 I! @2 D
result = x + y;) r _) [7 V6 Y& e+ X
break;
. ]" H# d" {9 ~- c case '-': 4 N6 e' ?4 |6 y# W0 U" V4 n3 A; A
result = x - y;; ~0 C# T) ]$ r9 d% y7 Q( R
break;% z( t) y& k5 R% O* g, g
case '*':
7 _3 a6 ]9 R- \# o/ Q0 i result = x * y;
$ Y _* {9 k0 i9 N/ s! u break;/ Y/ N! o4 u$ F5 H5 e2 B
case '/':
, f; F. r _1 ? if (y == 0)0 `6 m8 z' k; I' i9 {
{1 |5 \1 j a# }: e/ X7 J
printf("Divided by zero!\n");4 O6 x* A# y) E& v
return 0;
. }7 f5 m1 ^& j7 _ }
* g, t0 ?" S! V2 o6 m$ _! m else. `, v) |( h+ S: E! X+ ]+ t
{3 B& I) }: p4 ~" H i" F4 j, y
result = x / y;
" i. Z4 C' p$ c break;
% }$ {1 L* o* y. i$ p4 ` }! `& R: q( E1 l' f
default: & c4 [) Q; `2 y- r" ~% j
printf("Bad Input.\n");
Q4 C: c* H6 @& \7 u return 0;- m2 n/ D; l, _1 L% n
}. b- u/ J( z9 T$ D
return result;
! P% w7 {' s% b5 \' D} 2 d* v2 U: l% `0 O" t
# |: k. I9 A# n3 `- E; Q% o$ `( wfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
7 n5 b; ?0 P- S8 l( L) Z" j, n{
7 J: Z' Y; v; {7 j- N Stack optr,opnd;( b& ^* {( a) Q1 W" Z. n9 v& B
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
% @- E& z3 ^3 T, |2 s char c;+ g# c4 @- w, p5 @* w5 R
char buf[16];
/ c' _- `' a# _: {5 _ int i=0;
" b, [- f/ m) l; f: v
; ~. `% u- p* F/ B InitStack(optr); /*用于寄存运算符*/8 o6 o; @7 {2 W" ]9 ?. o
InitStack(opnd); /*用于寄存操作数和计算结果*/
% {9 z* ]& U t# _5 S0 B& T memset(buf,0,sizeof(buf));
) m( Z9 Y8 g0 L$ M% b, K - G4 o( E# h9 v7 k; }0 |: g
printf("Enter your expression:");* @; L. t) I' B$ D
2 y, `8 \6 O' ]& r! l8 R
opr_in.ch='#';
" b4 K& I: J+ V Push(optr,opr_in); /*'#'入栈*/
1 j6 Z3 v) W4 d' [0 I: [7 n9 t GetTop(optr,opr_top);7 O! { U4 s( i2 V6 `4 }6 E% K, j
c=getchar();1 J/ d* Z/ P* P2 ^3 @8 y# Q- `. X
while(c!='='||opr_top.ch!='#')! {( Q; e0 _9 R2 a6 k3 Y4 t! Q! q
{
$ j8 Y& W$ {. g+ W. B if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
' u% q9 x+ y: m6 F9 N0 B/ L {
9 _( `3 Z3 U' F2 U8 u buf=c;
) G) y( @2 ^3 ^9 Y i++;
% n9 V( |& ^4 ~3 U4 }9 W. E: w" r c=getchar();
- d' j) a% w4 k6 E* t8 K. x }
( L+ ~; b1 `; Q+ Z1 x% k& ?5 X else /*是运算符*/
( Q+ T9 f6 m- ?6 K7 m {
4 o: Q+ }; f6 v, ]# Q3 R1 v: ~1 B buf='\0';* b: J/ W' c3 W/ a/ [8 }* `
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/4 Q D S) [' a% G
{
6 H [) h! R: ~/ O2 A- Y' [* I( j opn_in.data=(float)atof(buf);
' S# P; o4 s, M' q Push(opnd,opn_in);
& `% g+ V" F4 C9 ? printf("opnd入栈:[%f]\n",opn_in.data);: i( ?( ~4 x8 u2 K; Z) o8 Q4 Q$ }* Z
i=0;4 }3 Z$ W$ r. f5 R1 S2 g
memset(buf,0,sizeof(buf));
4 g. [+ c! F8 J0 x7 Z- r }
1 A3 T& @) E& |, |( T3 a opr_in.ch=c;
1 d: L2 h; E8 C i) x* l0 i; _ switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
; V1 O7 X- m9 b+ f4 ~+ i7 G1 C4 M {4 g& B% W$ B f& w9 P( {) Y# j
case '<': /*优先级小于栈顶结点,则运算符入栈*/
# j) s1 l7 j8 k9 T% i5 ] Push(optr,opr_in); C, H0 W B/ e& b
printf("optr入栈:[%c]\n",opr_in.ch);% w8 V/ H+ c1 ]) W q) M
c=getchar();* C% ? t9 r0 V# ~+ Z
break;4 Q2 B+ A; G. k+ P$ y5 I
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/7 \: t+ I' |$ z0 O% k8 u* ~
Pop(optr,e);
1 `7 |; h" R- i1 K printf("optr出栈:去掉括号\n");! D+ U. u* O4 M0 E7 x& M
c=getchar();
|% t4 z+ s4 Q) B6 N8 @* p5 Q* S break;
* t" W% Y7 |6 H( t- c5 l case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
; H# H1 |, i$ ~- B Pop(optr,opr_t);
" l- N9 g9 J. M7 V printf("optr出栈:[%c]\n",opr_t.ch);
) A0 j& O1 r, H if(Pop(opnd,b)<0)& P! v/ v8 `& p' ^2 \" j$ q; r$ @
{
9 c8 }" z, _) n( X& N7 c4 b7 l printf("Bad Input!\n");
! K' G3 D' q: @. a fflush(stdin);
% s' Y' Z* j" B4 e return -1;
5 s# b X4 |% A& x" _ }$ C: P0 [5 e) Z5 o# J* i: W
printf("opnd出栈:[%f]\n",b.data);
+ o* o$ |3 `/ g2 J( M* f if(Pop(opnd,a)<0)
8 n4 N% X) O* g" m {
7 r7 `( ^1 ~; F) C1 }4 B printf("Bad Input!\n");
$ _3 d" ? q7 x7 j; ] fflush(stdin);
; ?0 i0 _) [( d1 c9 r M return -1;
0 [' H5 d/ u: A1 s }
! e% z F) ~" B" l Z8 X' d printf("opnd出栈:[%f]\n",a.data);( K/ a* L! d, e0 }
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
1 @5 D2 Q1 E3 V' z Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/ T- W! Z* W' j& P p5 c
printf("结果入栈:[%f]\n",opn_tmp.data);
$ d( \7 |) J8 d2 l break;3 b' O, a' \% l9 a' G
}4 ?8 d# Y1 z( i% b+ C
}; |% ]1 n% p' I' q/ X2 B( M
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ ' W0 y e2 F; S F* j/ i8 {
}
1 v0 R0 h4 j* f7 f; h% b% N/ ] GetTop(opnd,opn_tmp);! T: z O _9 }! L
DestroyStack(optr);9 P0 z; y. `2 f. Z% ~
DestroyStack(opnd);+ a* Y5 m- G$ J1 o) x- z+ l* F
return opn_tmp.data;2 J' F3 U( x6 }3 o$ {4 P# A
}
' l" |7 I1 o4 |0 s; ^3 r' b' n5 m) E# Z# a& E5 {# F. d
char *killzero(char *res,float result); T' Y7 _/ p3 e' d3 ?# T9 j
{
/ J9 N) V" y8 ^ \7 k5 x0 d; ~* r int i;
. A* x- q( U/ x" A
% i$ t( q+ m: H7 g! Q# E5 Z2 ^ sprintf(res,"%f",result);
5 d# E q# X6 D7 q i=(int)strlen(res)-1;
: l& L2 G( Z9 v# w5 u while(i&&res=='0')
7 C, r0 l* t2 k9 o/ Y {9 D% V) z3 P4 k- K/ J R* x
res='\0';
s9 F# C" o; F; x i--;
' J2 h, S# ^; {# }6 r: Q }
6 H: C1 i1 X! o1 R if(res=='.')
2 i# g8 \5 K% p* ?. ` res='\0';
- s2 G4 L1 e, G return res;& ?+ i0 X2 c. N T& n- j, g) I8 p
}9 x, |8 g# @- O: t) E2 }6 y
6 B) ?' G! m& i* D" Zint main()
( i' p7 h2 j- \* o; {' @- e# l{
& G; h2 a& f& e. x/ ]8 p \1 } char ch;' w0 p6 j: W/ Z2 n9 D4 f
char res[64];) g+ T7 Z8 u* s1 O* a3 i
float result;
/ `- a2 m# O; ` while(1)7 p. E3 |" y& j0 x8 e; r9 N
{ H/ Q% ?( {, z$ j7 e
result=compute();
2 e# F0 P* w" d3 U( i printf("\nThe result is:%s\n",killzero(res,result));9 E1 w. S& y n. p& t! ~
printf("Do you want to continue(y/n)?:") ;
) d7 j$ |7 u4 F/ ] ch=getch();$ c+ _- A8 r# D; ^4 _9 q. }- b
putchar(ch);5 h1 e; I' @1 \
if(ch=='n'||ch=='N')
9 k6 o+ l4 z& o! v* ^$ O( N break;; a: U+ T( [8 p& H
else
s- n$ z, Z( `3 [" { system("cls");
) u/ |+ j) l/ e% U/ n. r }
0 d/ k ]( ~4 ]8 @, p; v B& E return 0;
. l1 @8 q2 a, T& F}4 o6 \1 r2 G& g8 b+ }# W# o
* ?/ T2 E3 B7 h/ Z X( _
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|