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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
" F0 P% y0 |7 h% G( w程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
- O' |( }) q z4 Z0 J! @7 u2 f6 u/**************表达式计算器************/
. g8 H7 W8 r1 p5 @! L8 @: q#include <stdio.h>$ g0 l8 }5 |) G1 m ]( R8 p
#include <stdlib.h>
; W/ G1 E! j7 y! t3 o7 i2 j#include <string.h>
, y2 v0 P2 ^% J/ H a$ s7 r#include <conio.h>- Y, ?7 W* a1 K- A+ ^, F
#include <malloc.h>0 _/ O7 U" h4 k, h( M; V
' S M7 k4 u2 A, A#define STACK_SIZE 100( s6 o2 N- O9 Q. f r- t, q
#define APPEND_SIZE 10
5 K1 o- Q+ C* W( U2 Y$ t6 `" x/ y- j$ U
struct SNode{
, F" g( W+ [/ Y- {* U float data; /*存放操作数或者计算结果*/% f. m7 }( _ B4 B" E
char ch; /*存放运算符*/
( S6 c, t1 Y; x7 u% {};( k% o; v+ Y5 v- [
* t Q, [- u! ?6 s% |' Ystruct Stack{4 j. d6 g) w4 ]0 s
SNode *top;
1 N% {% J& o- x1 j4 m SNode *base;
6 g) ?: {. w4 S int size;: H/ Q- `1 A9 F8 ?) C7 R% m, `
};$ i" a. j, \2 K# [3 U5 Q
7 P$ G. p+ V3 Q3 k. x) {, r9 U/*栈操作函数*/7 L* F9 A. F) r+ G: u9 Y
int InitStack(Stack &S); /*创建栈*/
: V* z3 g! I1 d" v. H+ dint DestroyStack(Stack &S); /*销毁栈*/
* F9 a5 c6 X8 v% A& }1 Gint ClearStack(Stack &S); /*清空栈*/
& Q# h5 A8 i Mint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
3 q9 L; i6 D. Xint Push(Stack &S,SNode e); /*将结点e压入栈*/" C- d# k% Z* C
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/* G" z0 c7 o0 V, f1 e" @8 G
% ?5 _) `8 G! `8 G/ H/*表达式计算器相关函数*/
; O7 n: x# H0 ?7 O: xchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
7 s/ w, V9 s1 Xint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/$ w1 T6 J0 T8 s: J7 o
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
k: j/ }9 X: j. bfloat compute(); /*表达式结算器主函数*/
" J7 y0 P. v5 |4 U- qchar *killzero(float result); /*去掉结果后面的0*/ 8 d2 b! k. m1 c, T( E7 l$ m
3 g2 P% i" d0 r& o5 I0 p
int InitStack(Stack &S)2 C9 D, A4 a, H8 @6 H }1 l
{
3 F$ i. B, H, i% a1 V- T' L. J S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
- }4 w& e; f) B) |2 E$ L! n if(S.base==NULL)
& s9 C0 _7 @$ M9 y4 z {7 b; g% P' i4 R/ N2 o2 Q) l. ^. L
printf("动态分配内存失败!");0 Z; z# `- v; f4 l1 u. L
return -1;
3 n7 ?6 i6 O( Q5 `3 q& [+ C }
/ m& O2 p; i1 G( M; e S.top=S.base;
$ j6 V s& ?( y: N; g% b, { S.size=STACK_SIZE;
/ O/ x/ |, O, Q1 ~8 C% V. E return 0;8 X8 i& a5 }* V, l t
}
4 p2 F! L$ x0 G; p0 L( ~+ O' Y( P! f w Y1 B5 m( l5 d
int DestroyStack(Stack &S)5 X+ S' D) x% a7 {& L2 f! C
{
, c2 e: {* G+ _; U& |$ h' Z4 ?6 H+ B free(S.base);
, o% I! V. Y/ U return 0;4 u& u- X5 r) ^' T9 r
}
: T! ~" F: g; {2 X. O0 h" x/ E/ e: v
int ClearStack(Stack &S)' c+ N1 G1 Q, q, T) C# E0 N5 z
{* a0 f! Y: ~( ?" ]' O# i
S.top=S.base;4 h' ^9 u I3 _1 E. R1 L
return 0;- y( w" H& R/ E: Q" x3 s
}* f# r5 Y7 X0 ?! d8 E( H
) g- h! a1 X: h3 Y# H& S5 }int GetTop(Stack S,SNode &e); v. l: r- B! q6 y
{/ P; k; R& r* S! V! T# H
if(S.top==S.base)
6 U' f6 S+ T. V/ U { Y) ?+ O, p( X R
printf("栈以为空!");
% c4 B! B `3 y5 N" x- J& t return -1;/ f" p; B: z$ U0 x1 I% u- n
}6 q* X. w3 T( j$ N0 l
e=*(S.top-1);, Y$ U" z1 B8 ?) G5 N6 b
return 0;
/ I" o1 @, H9 E0 U1 U}
* Q" w! W C4 T s8 \5 z9 l1 |3 A# @2 s( o# W. ?( T
int Push(Stack &S,SNode e); w7 @( O1 @! t8 p( u
{
3 J0 V+ _. p2 {2 @ if(S.top-S.base>=S.size)1 ]% L6 c; e. A; y; x s! o
{. g: L2 ~) j _" R
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));( U: w6 b5 {; x* O9 W6 X
if(S.base==NULL)9 ^( K" l: A' p- B0 p
{
* I ?( C g/ [% m# p& Q printf("动态分配内存失败!");
) f- [# Z: }7 t5 Y5 {! J return -1;
7 [+ x4 y" ~- h }
) C2 D! M* y! M; I& y S.top=S.base+S.size;5 ]5 y# q; m. V1 y# P# i
S.size+=APPEND_SIZE;& L( d- e' D' F9 F% {8 y4 I& P
}$ s3 n: m% D1 m7 I! `$ m0 c8 ^) r
*S.top=e;
& [9 ?( F! V+ d. Q% B' [3 Q0 H S.top++;$ W+ n/ r) o$ N7 N0 Z
return 0;
' R! n3 s) g4 M. ^7 a2 E}
& E" Y# X0 S( m9 G- w- h8 K U- d
4 s6 F3 T6 G6 pint Pop(Stack &S,SNode &e)4 ~- X8 K; L: m8 n, ^9 _2 ^5 p
{
# I1 z0 @+ L1 W9 B if(S.top==S.base)
$ _/ s( m3 l( E$ [2 E1 W {
# e. S6 Z; v, G! ? printf("栈为空!");) q+ @, I: n( E. r* v: ^
return -1;
5 P4 o0 {; T$ J& F! n }5 t! D l' o5 T& {; c
e=*(S.top-1);
7 `6 \/ c1 }% z& T: Z0 i$ |4 o S.top--;
6 `! d% b; [/ a return 0;
, W: }. S2 c6 |8 e+ ?}& N5 }. |: S* w
. |) a3 e- y! N- wchar get_precede(char s,char c)5 R$ f2 r7 R4 p
{
B4 P- j+ H% n+ @$ x switch(s)& Q# V6 b0 N+ o2 }! @: Z$ s" x
{* ~) Y' C$ I; S2 s' p" T
case '+':
# k* e+ ]9 i; e) G- Y case '-':
) u, \* V: g( r- J3 w6 r if(c=='+'||c=='-')
( h8 y! ]7 s# R" r return '>';
K" ?4 Z3 c, S V else if(c=='*'||c=='/')& Y% O& o7 \, S
return '<';. R/ q# J6 w* Z6 i3 K
else if(c=='(')
& o6 J7 u9 M1 O8 o; x* c8 ^: Q return '<';) r0 m/ n2 s5 X2 t) {, p( n* K
else if(c==')')# Q4 H, E( r" _ F
return '>';* T5 M# i( Y1 d( h& E0 @
else
; w$ d6 j0 t; d5 [ return '>';
# d3 ~. a' w5 A N: K, z$ k2 K1 a case '*':$ K9 @7 M# t: M! a# h6 `% J! m
case '/':9 ]" ?' O* v# f3 D. w/ L: i
if(c=='+'||c=='-')
% d/ _7 g! C. g' G e# d return '>';
1 y: r% ]' E/ Z8 A else if(c=='*'||c=='/')
' ]9 q' m2 s1 ] return '>';$ g; h4 l* L4 f. z2 T8 Q+ B, w
else if(c=='(')6 F7 T+ o* B ~* x
return '<';
; `& f* d. E; a7 F3 x9 }- a' R else if(c==')')
# a9 ^+ G' ~3 |' A2 E9 h return '>';1 i$ L& W: g1 c, A6 j
else: b9 M, n% V/ |
return '>';
2 a9 ]( p* N3 c+ M! g& Z case '(':
A4 N- [3 E& U1 ~) {/ I6 Y if(c=='+'||c=='-'). K# z/ C4 h- i3 J8 l" S% v
return '<';
% q- N! I3 G1 o- _ X. i5 v! Z else if(c=='*'||c=='/')
6 \+ F8 C3 O5 e return '<';% F- q( R/ A0 ~% R) l9 r
else if(c=='(')3 [( S1 [0 `, X" `9 t b: o
return '<';! _* F7 s7 P% a% F1 l- N
else if(c==')')5 U- o, D0 I8 u4 x: W0 X+ F
return '=';
# @$ \6 h: _4 @+ X' l8 q else* t% w6 @0 ~" r6 @
return 'E';- M1 M+ U F: I
case ')':0 [8 f. i9 P$ h5 ]- `. H
if(c=='+'||c=='-')( H& N9 X- a* Y
return '>';# f! B& O* y# o& v: M' r! N
else if(c=='*'||c=='/')
1 A7 r0 \7 i. M1 K% ?$ \ r return '>';$ r: s/ p1 p: l4 ]3 V9 X
else if(c=='(')
4 K! }( n* s; U4 ^# k4 a" g return 'E';" v5 [" s- s3 @4 k+ |
else if(c==')'); K) B. u" o1 q* H! d2 [2 J
return '>';
/ @1 {; i- s1 m, u* _* J+ k6 ? else4 E: ^+ S9 X& |2 c1 x( K' X+ B
return '>';$ t& P& g' {0 {3 G& e
case '#':: W& ^- G* E# t( x
if(c=='+'||c=='-')
' A% e3 D: k6 ?; ] return '<';2 O8 T& A4 b- c% ]4 b$ j4 {
else if(c=='*'||c=='/')
, D6 I# T) l% g return '<';4 u4 e8 h% w+ Y) G) j
else if(c=='(')
; L% C7 I7 u5 B7 L& p0 I return '<';0 t0 O; Z) f4 B4 D2 L
else if(c==')')
2 l+ J/ Q0 d5 |9 K0 _ return 'E';
' Q9 _6 y' x0 n/ s- K else) O, W3 W8 R5 @; i$ C9 D9 T
return '='; ^ N& q+ |+ U
default:0 \3 t5 m1 U# H
break;
% k0 q7 C- ^- k }
* y* i8 Z& k! S& w return 0;
" O* x: y6 ^7 C. Q. Y}
6 p- s) p# b$ U+ h& z& d9 C2 n! E3 q( `
int isOpr(char c)* I9 m+ ]( ]. d3 q! Z
{
" O K) Q' m* g7 B! V+ W if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')7 e m5 ~" V. _9 o' m
return 0;! i, j. x. I1 v7 X
else
" Z2 A4 y/ D! t3 G3 z, G4 T& G return 1;1 n. m4 N6 d. y8 Y7 j* s s* u
}0 A: g* s% w& _- K# @$ j
7 F" ^/ W- B8 [5 ^. e; afloat operate(float x, char opr, float y)+ k* @$ k: M! \1 B! z
{/ @5 b* T# c2 _- l9 d
float result;
' a; u7 o$ e1 T% z6 d switch (opr)3 n. f: b/ o6 R; K
{5 U, ?1 {0 A9 ~( X( W
case '+': 5 G" }$ g8 K; c/ C' w9 p
result = x + y;
6 i1 M6 L* t0 O7 B+ |% V4 H break;
4 M; C; \6 d" E, _2 k9 T6 l% r case '-': $ C. u E" n2 E9 T- z
result = x - y;
' Z: v1 i: B8 m7 d break; Q3 w2 L! ~% F: T
case '*': 2 ]$ ]; }* @) K- g; V: I N9 \- @
result = x * y;; B) F! s$ t7 P* W- e: {1 i2 ~
break;
' A5 ]( J" @& a- r# d8 x K: w/ I case '/': # a4 R( ], @* J7 k4 j2 u9 a
if (y == 0)( Z7 }% B0 e4 _/ ?6 l- K9 ?5 e
{
' Z5 u7 s y: M0 J* M printf("Divided by zero!\n");
3 n- R- b6 _/ |+ L6 v: P return 0;5 N4 p( k, ~ u* G' n' M5 o4 u
}3 x) X; h1 T+ ^$ R! z5 Y X
else
2 U) `* g" A/ U' m0 [- I1 X5 U {
* [4 Q2 Q+ U) J" V result = x / y;
* X# ] S+ Q5 q2 c; |5 B: w F break;/ W5 x" t# L2 G
}7 ~8 l: Z6 x$ l, V
default: ) ~" I* S8 e( m0 b" @; W# x
printf("Bad Input.\n");
4 y: a: U \* t- Z6 l return 0;% x7 G* _" Q. p6 K$ v/ y
}6 x" M1 c* Y: u+ \( ^
return result;
1 u E5 I9 P* v6 N( t} & l4 V" S5 J! ^' c; a
' N- f: g: g1 C! e" [. L S# m: {0 [
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
) w" `/ W/ [- v6 y+ g{# N& U( \) r. |: u
Stack optr,opnd;: q" H4 C2 N4 U
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;& \. b$ V1 W' u/ c0 J# N3 ~
char c;8 U- u3 w8 h+ }9 l" F
char buf[16];; n1 M( i" r% q8 @; I; C0 I. R9 h3 ^
int i=0;0 L& Y+ O2 N$ b6 u: h# P
2 N2 G) k K# n( g
InitStack(optr); /*用于寄存运算符*/
4 w. H( K2 G n9 Y. c/ w/ M; `0 ~ InitStack(opnd); /*用于寄存操作数和计算结果*/
. U) t, I: P- X) u1 L+ \; }/ y memset(buf,0,sizeof(buf));
& Q* s8 E/ B) A8 Z
+ B- {! A% ~. Z printf("Enter your expression:");
. T$ _: H/ G( \$ G - B# }; f8 ^: ~ t) [ g) z- K
opr_in.ch='#';
# f+ m6 p: \/ G2 B& W# Q. T Push(optr,opr_in); /*'#'入栈*/
& |/ C1 ^7 C: i& c( h GetTop(optr,opr_top);
8 D# x* j8 o: L& m4 J, N3 r c=getchar();
B8 H, R) Q1 u- Z while(c!='='||opr_top.ch!='#')1 ]+ u! P+ o5 z
{
; O6 A. E" }% y+ o L/ [3 H3 F8 k if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
6 \- {8 `5 j! B6 N" J$ _& L {+ ]3 b& J( D i7 o
buf=c;1 U( Z# z- U" S3 T9 i
i++;9 c, s# b& |8 \7 q
c=getchar();; i0 B9 X1 X+ B5 M' l
}
! V: Y" c$ e V% O else /*是运算符*/0 V6 R! @/ M: i
{. Q k. F& f, `7 s
buf='\0';+ e# M7 m& t8 @% N1 N+ @
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/5 l* s: A6 S6 |/ Y3 i
{3 J. ]) ]8 T9 ]* O
opn_in.data=(float)atof(buf);
$ ^5 L2 ?; W/ n Push(opnd,opn_in);) u! @1 f9 ? D9 d) V
printf("opnd入栈:[%f]\n",opn_in.data);/ a3 w4 S/ [" X" }+ w% R
i=0;, Y/ P; M* x/ z; |& Q6 B$ `
memset(buf,0,sizeof(buf));
3 K) c/ s* ^8 f. l' ] }
. w& H% p3 o$ d opr_in.ch=c;, g! {) E# Z8 Q; ?" N( m' V7 s
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
2 h- \ N9 \3 S2 E! z2 A {! I- x4 O' j' Y6 C2 i5 a! X: u
case '<': /*优先级小于栈顶结点,则运算符入栈*/
# }+ u( Q/ |% x4 f4 O Push(optr,opr_in);* ?1 ?8 s5 l: I; O# y: u
printf("optr入栈:[%c]\n",opr_in.ch);
- o. E6 f% i7 ?9 q) X c=getchar();
% u" H8 k, q& Q h2 Y break;; Z* Y; r. E4 p7 ?4 }) H9 m5 U
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/: `$ i6 u. \: Y: G1 }/ H
Pop(optr,e);# Z) p5 v4 W4 x3 z+ h/ b" G
printf("optr出栈:去掉括号\n");# a+ Z- H$ v1 c7 d) Q9 B8 g9 x
c=getchar();
/ i* |% }- q1 p* {6 i3 ? break;) o v/ \4 k+ l" j4 ]; Z
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
+ l% r: k$ H9 T% U9 _ Pop(optr,opr_t);4 S W( I2 e1 p
printf("optr出栈:[%c]\n",opr_t.ch);# S% K! V; s5 a: l/ A
if(Pop(opnd,b)<0)
: Y) X5 H3 H3 W; V0 q M! O: j {
2 h, M& b) n( f# j8 Z2 j& Y printf("Bad Input!\n");
! h6 N) r, J, Y# K3 j8 G3 `! C+ u6 k fflush(stdin);
9 p$ D3 ^* E* ]# B. q1 L return -1;
, o7 M/ j& Q! P& v$ m- W }
8 u- E& X4 q2 W# R* x printf("opnd出栈:[%f]\n",b.data);
6 b) C! P2 n5 _0 X7 Y1 N }; V if(Pop(opnd,a)<0)' I# G$ B9 b$ f! h' M: i6 D8 ?! }1 p2 H
{
" e7 Y* }( h* e1 f printf("Bad Input!\n");
' u1 V/ I1 K- g ?$ V# Z1 \% W fflush(stdin);+ a2 o e6 q) O: j4 T% @, g9 v
return -1;
- L" q( g. u& a8 T, ^4 N }
6 Q4 F- _( l. z! E) ~+ f3 k" x- y3 e printf("opnd出栈:[%f]\n",a.data);" E* ]! [1 T* {7 q) {7 U
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*// b) u9 ?( G" N2 K7 x! t0 M5 p8 Y
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/% L6 y2 u7 U" Y7 ~. D. C
printf("结果入栈:[%f]\n",opn_tmp.data);* g! Y1 k$ {4 F& U( w/ _; e
break;
" o$ y6 c E: ]3 s3 Z" F6 k4 ? }
1 ~5 c3 d- ~! C' Z: @ }
; Q" t6 g2 M" X- `) n GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ ' U9 Q1 f% t5 C
}. m m4 b3 i+ \* F" g' a. I
GetTop(opnd,opn_tmp);
& `+ x4 O3 M8 d5 s: q: I DestroyStack(optr);6 J9 ^% C# @0 ^( J+ r) }
DestroyStack(opnd);2 F2 q3 v3 P# X" N) f
return opn_tmp.data;
$ d6 W! x" n2 ]& Z9 a3 \}
% ]6 O# [9 Y( h' m; {, q H% h( H! s
char *killzero(char *res,float result)8 |8 U5 {* S. W) j9 u% _, h' s& t
{ O4 i. J5 ^5 W; A
int i;
3 r0 q, r0 I7 M D8 O) o; u5 y& o* x+ i* Y0 s, E* k6 B
sprintf(res,"%f",result); m3 u! s3 [. A3 f( U7 y8 u) u9 w
i=(int)strlen(res)-1;$ L. ?( q, F& j. O( @8 B$ k
while(i&&res=='0')0 ~+ @7 e6 K! ]- k- V
{
5 j% F) T4 c0 p( {! Q res='\0';
) m! o/ {3 p Y( Q& Y i--;6 i3 S! s5 z% s9 K* x
}
/ ?5 O$ S; m- F U if(res=='.')
. b) W# ?# D \9 j- P* O- { res='\0';
1 y! L8 i+ q) O, }; C! o% j( `5 s return res;
4 A* q9 i: b& }) r}
& \9 q0 c' X8 P7 H Y" ^4 Z* ~0 w: g4 w% c4 g. f7 D; n
int main()
/ S) n. y/ R0 x+ E{
! e/ m, S/ R' v3 {2 n U char ch;4 k) Y/ K' V$ D3 u9 {0 g
char res[64];, l& w6 ^* e0 I# S) o
float result;% o3 r6 ^( y4 P
while(1)' J ?: w) x( S8 U& m, I
{
4 u) Y) T* @$ W! j3 J" ^ result=compute();
) Y. O6 U* s9 J8 L' _; J! M printf("\nThe result is:%s\n",killzero(res,result));
. X& S4 b, @* L: _* N' \1 @ printf("Do you want to continue(y/n)?:") ;
" m5 } M; F% h, b: G% c5 U+ j" G ch=getch();+ ^, j* e- N0 T8 ~: x( f) S' i+ c6 h6 \
putchar(ch);
' r: F6 @+ [* s( b/ c if(ch=='n'||ch=='N')
' u" D c: k E$ i# Y break;
: \) x' n) C4 K: U else
4 g6 `5 ]) M; H% _% Y; Y8 @! @5 A system("cls");6 W" S" e9 E6 l( a2 ?! }7 Y
}
$ a+ f. q7 V7 ^, n# Z, ~8 S7 D3 u2 x5 n: i return 0;% t+ J* i: Y* Y. S( _# W$ F
}- \8 g" J6 x- }. g+ I+ k# O
/ k; K3 {2 x7 i2 k[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|