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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.' H3 }5 Z0 Z( }
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=9 w9 l D) D$ f
/**************表达式计算器************/
) l' F* x8 k8 j# [3 j$ T6 I* G#include <stdio.h>
" a4 A7 u+ Z% J3 Y- ~#include <stdlib.h>- J- X2 Z" s; Z
#include <string.h>3 t1 C' ~' q9 a9 S2 a, }
#include <conio.h>
9 y0 }8 r: O o! c4 b* D- }#include <malloc.h>
7 ]; m) x9 D% ~- g# o: r5 M* t! o: z; I* y$ j
#define STACK_SIZE 100
5 c9 u6 J$ O) }7 l# Y6 q# U7 i#define APPEND_SIZE 10
: z3 b8 m, A$ A v9 b4 ?7 ]0 |3 d
1 U) T& L" y: h5 u* Pstruct SNode{
/ J" T/ v' R# A$ T' r. ^8 A! | float data; /*存放操作数或者计算结果*/
* D2 I6 |7 Q! [, X# k( h char ch; /*存放运算符*/+ j3 F; A! t' k+ e
};$ S. \ H: x( @# Y$ L
4 Z' R0 A* A( v: W7 @6 |
struct Stack{
: M- c+ r" Q! j0 t& O SNode *top;
+ D7 U/ U( ?5 @+ ^+ F SNode *base;- Z/ P$ v' t% q* u
int size;0 C3 p* Q0 S* \6 K9 T' U: B2 K
};
8 j; Z! o8 ]/ e6 c7 ^% i' n6 _7 ~7 g, {" v" T
/*栈操作函数*/2 N$ l/ L: s" V x7 m; E4 h
int InitStack(Stack &S); /*创建栈*/
% w: \- Y+ _0 r4 |, x3 k" \3 yint DestroyStack(Stack &S); /*销毁栈*/
" t3 e" @' f' q S3 \int ClearStack(Stack &S); /*清空栈*/
9 U' d8 r4 y( bint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/! V) Z9 x7 y9 C) f' W! ]
int Push(Stack &S,SNode e); /*将结点e压入栈*/
! l6 j0 R y/ p( W* r4 q1 uint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/8 T! E& v5 l }
. B. h& P- P1 [2 o
/*表达式计算器相关函数*/8 `. U7 j: u$ g
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
" m" j4 |, I. ~int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
- r1 H! e+ |$ m) a1 Ffloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/9 h6 [: r' {& `+ g" i0 ]
float compute(); /*表达式结算器主函数*/
8 |$ l+ n4 I4 U1 ?) K+ kchar *killzero(float result); /*去掉结果后面的0*/ ) J+ u V( j$ U a$ d- m& `1 W0 ?9 a. \
- n% X. C/ p) U! B( {int InitStack(Stack &S)
. P j! M1 H) Z, u+ L, x* r{
. ^% B9 u: p) L% r S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));: j% m/ r' @! \" D+ p" y
if(S.base==NULL)
* {% e( a" t3 c( p4 `. }) \8 E {
8 @* q! I1 ]+ k$ n9 U$ i" r printf("动态分配内存失败!");
( w1 H' d9 F. V/ v1 W, [ return -1; e. r. ~! G. k e$ P% K
}
3 p& v. \& S( ^+ w- M9 x c S.top=S.base;3 w9 Q# i+ F k7 _0 y! s/ T8 x
S.size=STACK_SIZE;. {: T H* \- [# d
return 0;
* c4 ?- A# {4 Y |; P- E}% A9 U' F$ {% j( E1 e
; I/ i! i- n, I0 S7 g4 Kint DestroyStack(Stack &S)
& b: W1 _2 W8 A0 T9 Q1 y1 F7 X3 p{+ x( T( y9 s9 C& L
free(S.base);
; Z8 `+ X+ X7 j, `& p& C2 x$ j return 0;
: B; W5 z g! B- d5 O5 w! W}, p+ r7 W3 d* `5 e
3 B: a3 r, U6 H! O& r0 O9 x. Mint ClearStack(Stack &S)8 y2 \+ ]3 b( p
{- P G; B7 c* ^/ G. ~ ], Q
S.top=S.base;
], ]- Z! k+ Q6 i/ p9 J* Q% ]5 Q return 0;' t2 }/ s1 q0 s8 R, s$ ?
}
: k3 ~# l: @( w. Y3 K3 Q% U
- M- y+ X9 t9 q! Y5 J" ]/ Tint GetTop(Stack S,SNode &e)
4 r' E% a1 E4 Q# L) Z/ v% ]6 _{
, [ Q+ `0 k: K, }1 ^* r" Q if(S.top==S.base)
4 F6 L; Z1 M, C6 B5 |. M1 q" m {
* z0 ~$ i! E3 } printf("栈以为空!");
" C$ T6 l3 L% }$ R# j4 [/ ]8 z return -1;: ~% A @% f. X7 P" u
}
, c9 q5 P) v1 P5 t. x$ F e=*(S.top-1);, n0 c J( E6 f
return 0;
2 w( n/ t' v* O4 i8 k1 ~2 J}9 X& K. c% C( c t& t8 W
& V1 O, f4 b# Q2 ]2 Z' r
int Push(Stack &S,SNode e)
: y& u. k2 I! E) Y0 {' r{
5 h% C( s: t6 s. n if(S.top-S.base>=S.size)9 Y/ |6 g7 `/ e1 I4 R( s
{2 B9 ^& m, y# d" Q, Z
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));& W0 e' x- H _$ P/ j- m% i! s
if(S.base==NULL)# l; R, _( G+ x& y
{+ f- J$ s9 m% g) X- K8 s: Y. Y
printf("动态分配内存失败!");5 f. e# m7 O- Z3 m! c7 Z
return -1;
3 ~/ P6 y! z& w. b, W$ K! O! v }
7 b- b, C/ X3 H4 z S.top=S.base+S.size;3 h6 J+ z$ K2 A; H& R
S.size+=APPEND_SIZE;# D- T9 J7 z$ M5 V8 A9 B5 g' Y
}
; o O5 K9 U F6 ~; h! T( I4 j *S.top=e;+ d. p) S- N; |3 R7 x1 M
S.top++;8 u8 x2 ^1 a7 F: p, f. h; v
return 0; ^8 W) L, n/ k! y1 r
}
. o/ o" H4 F; u
7 F1 \& y0 X9 n+ y$ N: c2 ?$ eint Pop(Stack &S,SNode &e)
8 Y0 B# Y' P1 I! T9 x{
/ B0 y: I4 f7 d# g* L' D if(S.top==S.base)' M# W* |# ^# A( s/ w
{5 v3 d `! [. R; x1 u
printf("栈为空!");% E: U2 y8 k6 p& f5 K0 k
return -1;- `1 u. l, s. v, {! _, p3 A
}
: Y6 P9 \. v) D8 F/ F- v- w e=*(S.top-1);( ?/ z' Z' D' P3 F+ m! N9 Q
S.top--;: A+ t" t+ ^+ L* D+ z' E' D1 U$ h
return 0;
% Z# N- D7 k* F}2 ?, w" c3 ^: D2 Z$ U* V
3 `. v2 D" Z# a4 R
char get_precede(char s,char c)7 j# l+ }, f4 x0 e$ n
{
1 J) E+ E7 @4 i: i" N% I9 z7 x$ R switch(s)- ~4 ^; u h4 @ s
{; Z3 e0 V9 F5 V. o2 B
case '+':
3 J, M$ n, I" k( m) } case '-':1 \" z+ C8 Z4 g, Q# b
if(c=='+'||c=='-')9 ]( {2 M: l, q5 Z1 `
return '>';. F0 o6 R% M' x7 d
else if(c=='*'||c=='/')& l4 X9 l @3 G4 |- r) _
return '<';
! s; B$ g$ o* A# C2 P' u; {# w else if(c=='(')
`/ k6 Z. ^ {5 `* Q: P return '<';
" ` j% V4 z) o else if(c==')')
; p& ?' w2 s; ?; E return '>';
$ v) W1 G' x. i7 m else # ~- R7 J3 t2 W. P; S; k
return '>';: P# R8 o1 _8 q" o) t3 {: y+ X
case '*':8 b; p; ?" X2 t
case '/':- W, o+ c" N: t& E, j
if(c=='+'||c=='-')6 L, w7 U5 {- ]
return '>';/ J- v7 B+ M( q( C# B
else if(c=='*'||c=='/')$ h+ Z0 V6 d) @: q" d. T8 L, j
return '>';- I0 p! M) E2 {$ A# O( s
else if(c=='(')
( P3 ]: J3 |: S( b: z/ Z- Y return '<';. `; c0 t( S/ E: p$ _+ A( B/ A
else if(c==')') z% D" G- ^+ G- Z; B z
return '>';
+ S% O$ l( R$ w2 ] else% n5 [+ s+ H8 M, G; I: V6 e
return '>';/ m, o% H( h7 d" B- ^( u
case '(':
8 G) h3 D$ O' ^8 _/ h7 J: p if(c=='+'||c=='-')* ~# X% i$ A; P
return '<';
: B6 `( G: ~) J else if(c=='*'||c=='/')
& [0 P$ g2 g4 {1 m# D p4 O return '<';7 }) \" _$ U7 Q
else if(c=='(')4 J4 W& I! j |. B, K' c1 F1 r
return '<';
& ?! e0 ^0 L# S) M4 O% a% ` else if(c==')')
7 R4 [0 i. V P3 c return '=';
! F7 b7 x. L. |* r# F else P4 W" t: z3 d; E$ U
return 'E';
$ `4 s& y, q) v9 K3 b case ')':
9 `, V0 r: w5 ]9 j Q* g& T if(c=='+'||c=='-')
7 }; n) A; x$ U! z/ e" i return '>';% i' C% R2 t) S( M3 ~% J4 p& Y
else if(c=='*'||c=='/'): g O$ x- Z' I6 ?* j* u& P* s
return '>';
; F# V: m6 Q+ w- a2 u else if(c=='(')
7 ?! k* K6 e' ~ k( F return 'E';
$ V: i" M E) g2 w( g2 ?6 l) }* ^ else if(c==')')
/ ^0 A" x* ]$ R# ^- y. u return '>';
; w0 Z; B5 @; U, O6 T9 s- ]: v else
3 \$ n' a+ w/ X2 W. Z return '>';0 ?9 d. q# o( E& n
case '#':3 r7 ]/ b0 k+ e; u% Y9 f& m: Y! ^
if(c=='+'||c=='-')
9 w! `& Y6 A& E: U2 b' f+ T return '<';
, C4 Z3 E% T: Z& ? else if(c=='*'||c=='/')
9 _2 {6 _) R$ ?% _6 M% P return '<';) v% |3 k% D5 i1 i" I3 N# E+ D
else if(c=='(')
9 ?# i- A! A& Q9 K( l, M return '<';
+ r% _7 t9 V: j8 F else if(c==')')
; g9 _+ l# h' ]) @9 U8 | return 'E';7 c. C6 ]) R1 `# V+ t# Y/ i J+ o
else0 Y' v8 E% r" z* j/ {) H7 B) d
return '=';! ^/ L# H5 p) z4 T' j. x
default:7 q1 I0 F8 F6 W0 v
break;
9 x6 V" c* ?8 q, z4 ? } F2 x2 b- r: T/ q6 q) h8 Z
return 0;
) @. B' S1 D% T' x% B* u}6 P4 q6 v& u+ Q' ?! [7 M: l
* z, D5 f4 o& k
int isOpr(char c)( k1 a* ]& L; o- `2 G
{$ z% g& _$ ` b% U4 v+ Z' m6 Q
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='): x F1 @! G4 E F
return 0;
# ^6 m5 G8 ^ V$ f7 ~4 f! z else
! h" g8 u- c8 \- V j& } return 1;" \5 ?. ]8 @9 |9 Q8 w6 H8 J
}
^; P$ g: u6 g9 b: f$ b
' P7 d0 S# p6 Rfloat operate(float x, char opr, float y). r8 Z6 ^, L6 D1 F6 _2 e
{
% E- a1 E, z# I3 R float result;- l: f2 @* V( ^/ Z
switch (opr)* a5 r' J+ V5 s% h" o/ A
{
9 y, a6 y9 D- Q7 y9 s l case '+':
4 e+ J6 T/ f$ V! k1 d result = x + y;: X% j( ?1 ~) l$ G% i
break;
' |# `1 k; {! D! y3 L+ n1 D case '-':
: C3 M8 R+ l6 K) V9 b ~6 ~! x1 k- E5 H result = x - y;# \ g |9 O7 {% C
break;
+ D- A& v3 R; O case '*': 4 B8 l4 A2 E h5 L1 `1 \* J" q
result = x * y;' K& l7 Y2 [4 ~4 ]0 U% [. F' D
break;4 ^& L$ E0 b1 M' ?
case '/':
8 M6 X3 B( q& \7 i2 b if (y == 0); P# f2 E/ w! b& z5 J
{
: ~% m& F7 a( ^, I, p$ | printf("Divided by zero!\n");4 e X& ? Z8 M* b% D0 ^3 }
return 0;( v. i. r ^8 N5 l" N6 H; b( O
}: {5 J6 p7 I; @- Y, S) U
else, V' K5 C6 M. w. R. c ]- z
{. \- n4 B9 `* | g5 g4 }
result = x / y;
3 a9 j e: i' t f4 }1 G break;
7 d, M* a) ?6 ]" m) k$ [7 E: _& q }( M& \5 i7 Y5 w& t4 }" T, V1 p
default: 8 M$ m0 j2 j0 t0 J( y
printf("Bad Input.\n"); 3 z! o. i7 d' I+ F1 `! I: j6 n
return 0;
Z: f5 L1 L/ Q3 e/ r }& U7 ^" E+ f; r1 C, f
return result;
; X9 A$ Z" Z2 X5 K9 u8 s}
& U/ m; G- ]+ W8 A- v, L+ W# k# U9 i( d
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
. ^# E% v0 M! J# p3 v/ m( m+ E! A{
: k! [( |# E1 [ Stack optr,opnd;
4 d0 m, V) J% V struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
& i' E, s5 s3 k9 u; X' T6 p* ^% T) ` char c;
% k9 V4 M3 n0 o0 |+ M char buf[16];
( ^$ d. G" I& A! Q int i=0;4 S) L9 {. E' J. s6 a- V* `; m
! Z, l' R$ o3 q3 \6 Z9 U/ V# | InitStack(optr); /*用于寄存运算符*/
+ F9 s- ^4 `' Q& e3 v( g InitStack(opnd); /*用于寄存操作数和计算结果*/. s4 \! A" v, C% D
memset(buf,0,sizeof(buf));8 K8 j& g4 ]0 N6 r# Q
! L+ L, s1 v) g7 e. E% L0 o( W printf("Enter your expression:");" t* g/ V5 c8 D6 s4 o
- _+ w$ o3 @* O! \2 g4 J. B opr_in.ch='#';" b" E+ |: z# a1 q' O: e
Push(optr,opr_in); /*'#'入栈*/! G L9 V6 }+ |2 S" b
GetTop(optr,opr_top);
3 l. h6 n. x* I7 I0 \9 ~$ _ c=getchar();) t0 l5 o; p, z& ^) n$ m' L ?6 S8 s2 X
while(c!='='||opr_top.ch!='#')
6 _% ?: X) @- O& t9 _, s5 O {
$ L3 V' ]/ ?1 I if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
) u' [" L4 }2 ^ V4 l/ E1 ^4 M {
4 x3 l1 h. k* E6 X7 }% ` buf=c;6 N/ h& w; X# B
i++;
1 i' W& ], B2 U; Z0 N1 w c=getchar();
* ?# j( ? s5 E4 m% s }
! M! b5 G6 u4 A4 Y1 B4 q else /*是运算符*// ]9 ^5 v1 Y- C/ Q& T8 H H; b+ ]
{ }1 _# w, s( ~* y: w
buf='\0';3 Z! d; [8 D( L
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/' d! U# L+ u+ K+ {6 z7 l' c, d
{7 a+ ?: i5 z( i& \$ J; G: {
opn_in.data=(float)atof(buf);
9 Y, t2 J8 E( }+ P# Z' W Push(opnd,opn_in);
, q3 c& E/ u% \+ G printf("opnd入栈:[%f]\n",opn_in.data);( u+ m1 ]: S* h/ [- {
i=0;
" A' T3 b# M! y memset(buf,0,sizeof(buf));' C* D( |" n+ g
}4 I- i3 E, @0 ]
opr_in.ch=c;
# U; [# U4 @3 k; g- f- | switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/0 S# A, B; V5 f" ~% Q
{
0 g. z- X: R: @6 R case '<': /*优先级小于栈顶结点,则运算符入栈*/
, T4 x D# V4 }) v( g1 `0 f, t Push(optr,opr_in);
' b" W3 B1 o( T6 Z- h( i, J, \ printf("optr入栈:[%c]\n",opr_in.ch);
! p2 ?0 r; m3 }& M& d. Y4 X c=getchar();8 ]0 `) P* _; X4 v$ O1 b. K" N
break;
( \, t _5 Y2 i- s- y9 ?- } case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
- z+ e. Z, C4 V9 V( G; T Pop(optr,e);
. H9 b5 t' V" T. x printf("optr出栈:去掉括号\n");
) E- K- [4 j# G5 K% k2 @ c=getchar();& ^; u$ c) u( g( Q, y
break;
( [; F+ g- n& N2 N; x# \ case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
. |7 `6 k) E/ f! m" r! j1 C Pop(optr,opr_t);3 P% e6 Z& U( w, [
printf("optr出栈:[%c]\n",opr_t.ch);
D# z% ^! x7 P6 D4 ^ if(Pop(opnd,b)<0)
/ Q# B# E! R: s! r- R {# E8 f- ]6 ^1 t! r* A/ I6 Y) o
printf("Bad Input!\n");9 y6 M7 Z1 A1 x
fflush(stdin);: @, `/ X" ]5 u o! ~6 J
return -1;9 ]/ n) x0 B9 [7 T8 K
}$ d# U. h* Y, J
printf("opnd出栈:[%f]\n",b.data);
3 k5 J. P' O& \ p) \/ r; l if(Pop(opnd,a)<0)
) x( R3 h |# N! R {
g, v: C9 i$ k3 k1 t printf("Bad Input!\n"); _) r/ a/ J* l
fflush(stdin);7 r7 p3 r" I! j3 c
return -1;
" G7 `+ E0 K5 M. e# l }
5 t7 O, B1 A4 I5 x! W' n* u; w printf("opnd出栈:[%f]\n",a.data);, D) O3 Q8 n( j3 Z* V1 P
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
+ i2 G( ?! M$ o V0 n/ N Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
: F# m( V; F0 C* f8 t G printf("结果入栈:[%f]\n",opn_tmp.data); P9 y! U3 V$ C, O' z+ x+ X1 C
break;, f7 ]: q- i$ i% ~- [
}
5 j. l$ V+ W$ L$ v% G }
) L9 ~$ V$ i+ B# z) z R3 k8 [ GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ ' |( Y7 R2 W. h) r" X1 C
}; F9 R8 @/ S! |1 c( _
GetTop(opnd,opn_tmp);
8 i6 p, A8 E0 S9 d# Y DestroyStack(optr);" q. k9 O# B/ y& h9 d& y7 @4 ^
DestroyStack(opnd);. L) w1 k( U+ u$ k
return opn_tmp.data;8 C- x/ m# K8 f& A# W5 s
}' A! D# c, d* \6 `, I' F
! o6 f% x* D9 B! j
char *killzero(char *res,float result)2 y- E0 g$ a5 U2 F2 s, ]2 `
{/ ^6 L5 _/ T- R( f4 d- y
int i;
! h0 z; h/ |0 _
' T' x4 d4 z/ S) G4 e sprintf(res,"%f",result);
\- Q2 b4 x1 w' I6 B* v i=(int)strlen(res)-1;
+ ?8 h" s' X2 e: l% o while(i&&res=='0')
{* `- C" j& K {
V" p8 `/ u/ Y6 l res='\0';
! F$ l; N z% t; y L9 H$ c i--;" x3 D9 G1 ^4 \9 Y: G: K
}
4 c. ?* F4 e$ O) U6 D% H if(res=='.')% X6 G& A! L" e! x" G/ m
res='\0';. N8 }* O* h4 I1 H3 E5 l
return res;4 d# V3 q# W( ?( k7 Z! [" X: l: [
}$ U+ t. f# @2 |$ Q: M8 Z
5 [" P' l b" n/ q- j7 d: s* Y
int main()
/ _+ w6 l8 {: c, M8 R& Q{
; f* ~: i; e9 E h; g char ch;
0 L$ ]* n5 n9 x! E/ t/ S# Q char res[64];# |+ d4 b3 I* I. c, e3 @8 e/ v @
float result;
: R8 m0 P# T8 b4 w6 S1 g while(1)" h& [6 M$ `. \( ^6 G! J
{
9 ]% c* s/ _6 x/ B" i result=compute();
; I/ h+ v/ Z) K. v printf("\nThe result is:%s\n",killzero(res,result));- e5 h* |) p8 E) R) V2 P/ Z
printf("Do you want to continue(y/n)?:") ;9 a4 s$ b2 Y% P9 z& _% h% ~7 A- @
ch=getch();
8 M3 w3 D3 C8 A! ?' M0 I putchar(ch);4 v( _7 s$ a( F8 A! O' w
if(ch=='n'||ch=='N')
3 P7 r/ f6 e$ ^ break;8 ^7 \: q5 Z' ^' M1 W5 \& q0 `3 O
else
. R# i+ m, [8 L" B v) Q* @ system("cls");
4 h6 g z7 V: r$ x }
! R) w: X- N) @4 C, v return 0;
# k0 m" b! A& ^7 i" P5 v. p}5 g' L9 @. L' a- K, c% m2 H& R
2 q: } S, s& q0 Z W4 h
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|