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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.' `4 E6 K% _5 D& } u9 `& y
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=3 c6 o8 l% E4 p! k% ~5 g+ f
/**************表达式计算器************/$ f- E. B0 N. L) S3 G
#include <stdio.h>
; p/ l$ k0 s& S#include <stdlib.h>
4 e5 I* Y4 {+ B. q, O7 v#include <string.h>: U/ N# |2 S p: N* k
#include <conio.h>
; ]7 Q$ ]' g, l a#include <malloc.h>1 a7 `1 T3 [ \
6 l! F$ E3 F$ \3 X4 g#define STACK_SIZE 1002 @' w) S# F5 \, ^: q b/ V4 i. h' {
#define APPEND_SIZE 10
; Y- s. A* N$ [0 Q r. B$ Y
* I2 u9 b0 P; ?$ _& |! Istruct SNode{
1 `" e G2 X# t float data; /*存放操作数或者计算结果*/
( {1 m0 N9 A0 b2 X; h9 _ char ch; /*存放运算符*/& N. u9 S" h3 U
};
8 c9 w) L) ?4 A, Y6 l* `
* T/ b- S" T7 \1 ^( n% H# \struct Stack{( |( v( k- t, T! Z
SNode *top;9 ?, N( e# F2 R% T
SNode *base;
3 K5 _- p0 [$ [, c int size; U! g8 F0 c% M9 V' L
};
# P% Z% b3 T o$ r+ ~ c" O. J/ I1 v+ e$ I
/*栈操作函数*/
/ q: L9 k, N5 m T( x9 Zint InitStack(Stack &S); /*创建栈*/9 N) M- r# j9 K+ u$ H Y0 o
int DestroyStack(Stack &S); /*销毁栈*/
2 Q9 V$ J" \4 \4 \4 Zint ClearStack(Stack &S); /*清空栈*/; U2 p; j% X/ [: g/ h' C
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/: v0 _# m9 q4 M* H
int Push(Stack &S,SNode e); /*将结点e压入栈*/9 R+ A5 N, m# v
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/6 ~0 }5 e! E) W; s% X7 k
- g9 D0 y2 n7 Q& a& i4 T/*表达式计算器相关函数*/: Y( V8 T) `" s, Q* f8 b$ J* J
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
$ n: Z4 O! K5 u" o+ u$ \int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
4 I& A+ A/ f% I8 ofloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
9 q" K' A5 h! M' @. M* p Gfloat compute(); /*表达式结算器主函数*/
7 v8 t N L9 u" ]char *killzero(float result); /*去掉结果后面的0*/
4 Q/ v7 r& c: g' u8 _6 E+ X4 Q$ D/ p) z. ^8 O$ H& `3 B) I3 ~
int InitStack(Stack &S)0 o4 `9 j- R/ j6 K2 J6 J. w
{
; Z& t" k% R) D* h2 x5 v/ o S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));- V4 @$ r" Z. b5 {9 A/ A! L3 I
if(S.base==NULL): T4 |% T8 f2 J" g. y; j. v
{
( V- ~+ s1 Y3 s; k# \- s printf("动态分配内存失败!");6 j6 a9 c$ v) s1 E- o6 s' x2 ~
return -1;
7 B" B! Q, Y; S0 x }' c! J6 K! {4 l: j, K5 h
S.top=S.base;. ]9 u9 U% e( I- h4 f) }) ^9 g
S.size=STACK_SIZE;* M" ^5 M7 [9 s) C2 S0 y
return 0;
& b+ c' `* O& K6 Q4 b( G; K}8 ]; [0 f; N0 i7 ?2 h
' w# d2 g! Z. p, o# r3 i
int DestroyStack(Stack &S)6 c) {4 d% f+ ^0 |) C) F6 Q
{8 y% S7 a2 O1 H0 V, N- c( I
free(S.base);
' l2 r- p& m( I8 r# Y- i* c) o return 0;
& v+ b0 K+ Q! p, G* o3 j}
" E: d; T$ ~( l! T5 P/ p/ p+ H l. X' ~! Q% |$ E) G
int ClearStack(Stack &S)
! h$ U( f. j5 D! D5 l: _" f# B9 o4 L{5 G* i. M' F( I
S.top=S.base;
: E( i& H9 x4 W, C! f9 k" C return 0;
* X, n4 ~% \9 k( ?$ [$ }4 L- ]8 M' w}0 d ~7 D0 O/ e' g# h- X- c8 U. b
/ S x& E0 m* _int GetTop(Stack S,SNode &e)
6 k% L6 k1 h) L{: w0 k& M: U& L" f# d
if(S.top==S.base)
; e m8 u, h, f) d/ e {5 X z7 r9 Q3 |$ {* \6 i/ Z2 x
printf("栈以为空!");8 c' V/ y6 m: d6 z6 y& X4 A
return -1;
O" ` b9 `% h }9 u, x- j" g, u# H8 d% }, ^
e=*(S.top-1);, p# _$ S, B7 [! ^" m, C
return 0;4 w+ _; h) q a/ F+ d
}3 u7 F! @7 d! V, i; q
- g! A) f5 b" M- z& F1 y0 Y% f
int Push(Stack &S,SNode e)
7 D1 `. G) F9 h/ [{
% l S, s8 D- t if(S.top-S.base>=S.size)
' h3 w" g% M5 ^ {
6 s, T7 \, B9 p* I" V. N" `6 T S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
) f+ ^( P# E8 o; U" p, D if(S.base==NULL)' G( d* p" h8 \, K
{9 m! w% L& K4 n. a1 @
printf("动态分配内存失败!");: h; M' l7 R, K! y; h1 O! d/ e
return -1; {. }+ P' T9 V
}
" i A4 N4 ~9 k* `( s S.top=S.base+S.size;) ^- S7 q( [5 Q x
S.size+=APPEND_SIZE;6 h: s% Y# S4 M2 `5 u- q; }6 `; K
}8 v3 A1 C. I, j& N
*S.top=e;$ |+ d0 x$ l: \& ^# Q
S.top++;
4 O3 i1 T, I& l$ G3 G; | return 0;8 O0 h( @6 i# Q0 }2 n7 j
}
4 l5 e% M0 d7 ~( r
3 t ^* O" S! Y6 q0 U) F) gint Pop(Stack &S,SNode &e)0 v/ M4 M/ Y' d+ `6 q. W
{
- g( J; R$ h! s* J R) e2 R* Y3 y if(S.top==S.base)
- T! S [* q @: W, a4 x! z {
9 e7 K7 c9 q9 L* [: h9 x printf("栈为空!");7 C' R: D! ?& Z7 w" |) p" J
return -1;
- r! y! A8 u: M% M- |9 o6 z6 v3 ~ }, U( @5 T: ?& f6 a3 k4 C
e=*(S.top-1);9 Z% I& c2 E# G5 U, }6 K7 r
S.top--;
7 w, f0 K4 ?% ?- J/ n8 T3 p: q return 0;
& y1 H: A P, q: p}; ]* D8 D6 u _4 y9 N
5 |& W; L" M. j5 p- b$ h
char get_precede(char s,char c)
7 i1 i# g- c8 Q$ b3 O{2 X; x: N/ {; t8 u \
switch(s)
' q1 F/ K. E+ ]& k% j {" [1 X. [% h7 t3 G, S
case '+':
/ h1 r; t+ @1 F case '-':
; a9 U8 s: R ]" q* D6 ? if(c=='+'||c=='-')7 g: m1 k% ]9 x8 c* J: d6 P
return '>';
4 P8 A4 X0 k1 b) S* j else if(c=='*'||c=='/')0 w5 m1 H6 i, I& t4 `5 f8 V' h$ u
return '<';
& J; F2 S/ S! Y; B' p8 n, B# { else if(c=='(')1 j" ]$ o+ W! I" F
return '<';
; m4 S8 m" m" x1 w else if(c==')')
/ n+ D- D$ i$ {# W" \) I! n return '>';
- N: z; l8 T7 w, d; |( x# \ else
' D" K' a& S' y6 E) q return '>';1 E% ~$ P4 V. q. R* y! v
case '*':
& U' y' ^3 D. c2 G2 g% {# d case '/':
2 }0 ~& Y! C5 [. }4 H if(c=='+'||c=='-')1 f/ i3 U- o6 {# G, ]
return '>';6 k. G* r+ ]- D! u$ `0 V
else if(c=='*'||c=='/')6 u' w. R% g* I4 j1 \
return '>';
2 i6 M0 H% b& ` else if(c=='(')0 w8 N z+ Y; B/ }( l: f( O
return '<';
, |& ?8 k0 ~ d% z else if(c==')'), B- q3 o0 [# u8 I
return '>';+ `+ x! {( l3 v6 C7 k
else
3 p; G4 j! C* F6 |, f8 A8 B return '>';
5 V) | n1 J# W P3 A3 t' y case '(':- G+ K, u2 z6 b* ^4 H. O
if(c=='+'||c=='-')# ]& R5 e6 S: D, B# F
return '<';
2 W8 I5 E0 ^" R/ v/ Z6 K else if(c=='*'||c=='/')$ K& L; O8 F5 i! b$ }
return '<';9 S0 V/ l$ j* v. b* M2 j |4 H
else if(c=='(')0 `# V. @2 Q8 _* M
return '<';
$ A3 {, m& U R" j else if(c==')')
! E4 ]. G y3 l5 i. U. Q7 J4 s/ j return '=';/ I2 ?4 U: ^8 ~6 [
else6 e. j8 [6 d; I" E1 Z) l* C' Y
return 'E';
6 N# P; [- b1 K( C$ Z5 A) l case ')':
, f+ B. l/ m$ @" T3 N if(c=='+'||c=='-')
# N$ A5 P5 d9 [& l. k l0 \ return '>';. }! H' O- F0 P4 R
else if(c=='*'||c=='/')
W$ E! @7 z, a* N( }; O( a8 y$ W return '>';- w1 q( {3 @, M( O4 J- K# e
else if(c=='(')
4 z* B) G# ^; W9 Q' O8 X return 'E';
+ }. H7 Y8 Y! S+ s+ w& Q else if(c==')')* C5 c5 A. a! ?+ N$ p: d6 O
return '>';
% ?2 R! d7 _. Y1 M8 K else) k: c2 a. v' n. v7 w
return '>';% U3 ]4 C5 j( I- C. N! L3 |4 M
case '#':
$ K, ^1 s+ L9 }8 ^& g if(c=='+'||c=='-')
* ~* U4 [$ {# v9 S/ |6 \/ B) k return '<';
: g* S9 v, ?5 t, j else if(c=='*'||c=='/')1 Y t% B; p/ L, \" i
return '<';
) m' p4 l- ?; U: ?5 I/ ? else if(c=='(')) a' U: |( z& Z6 E
return '<';; e$ j& i/ H6 N) g! ]1 h
else if(c==')')
, K2 e) k5 F. }$ {, t6 e9 F return 'E';
# a+ ]) a6 Y: C+ o. Y7 K else6 {$ Z0 F1 g7 f s" Q+ A5 V, E' S
return '=';
; A) L4 k% I, X& A default:: z$ Y4 ]$ ]( q4 u# {: b3 u/ V
break;
- ?0 f# e+ _, @1 _/ C }
$ G8 c4 B- i: T return 0;
" }/ g: ~3 `' y6 ~; ~( v& H}8 O! Z' m' w" M
& ]; X9 G/ N4 l$ W7 q2 [, fint isOpr(char c)0 F, b5 d. f Z! J: N, e
{
* c+ H- G, U! P if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
' O2 R: [# q* i4 p8 v return 0;4 F( }) a! Y4 D6 S
else
; x% o+ r8 i( ?0 \& r( D7 G A return 1;" j: \/ E# v% {, b' V
}
6 @4 D& j* ^+ a
; k1 d+ u; K+ ~/ B* E1 ffloat operate(float x, char opr, float y)
4 B1 D! N( ]* V, |- d{
5 y& y' p! \$ K! |0 J% s" a g+ Y6 j float result;" E5 q/ b' M9 Q0 S$ z/ k$ P* G8 h
switch (opr)
& P) N; w$ U4 _% t; O* q {& ~0 R5 Z3 C6 S8 x6 v- _
case '+': & `; s5 _- z+ j$ i, `
result = x + y;' m& [7 |; T, e
break;
3 Y; _ _- }# c! l) D case '-':
, r' J9 `& E1 Q result = x - y;9 l4 Q, F/ O7 D
break;
# M" E _6 E) n+ [ H9 e( y( R* K case '*':
% e+ d+ ~% q# g0 w result = x * y;
. m9 K5 v7 J; A0 s break;
: E y u s5 |4 \# o case '/':
+ K4 z8 K# v2 [7 }6 v if (y == 0)* N9 J2 s; q7 v3 _# t, I! ]# Z
{2 h T; h; D' {6 w! `/ X9 J# s/ w4 U
printf("Divided by zero!\n");. I; U$ P q7 j$ I; m3 e8 }
return 0;; t+ W x+ f8 b, r4 ?7 i
}
, N; k" I2 V; t5 b else$ y2 x5 f1 Y: q7 S- ~6 n
{, v4 o' f2 l1 A e: B6 v% R- \: \! {
result = x / y;
3 N8 O$ u0 V1 X! a% ]/ n8 t$ h8 S break;
# `% ~# `4 \. V, r% |+ A }
7 O+ N3 M$ `1 t0 y- r! j default:
+ f% O5 Z' }, W4 @$ X4 L8 n+ j, n printf("Bad Input.\n"); . } d, M# [: F. t5 }3 m
return 0;8 I6 F5 r: Q9 I) f( w
}
/ S, c6 H c' s; T return result;
$ U6 I7 \' ~& i3 L- Q0 |8 ]7 ~} : b% D: s/ N% v4 t }' M
' `2 x4 ~) @9 Z& S2 B! t- Xfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
- N! n% E) y$ ~$ e5 L{) g4 S1 J# I3 M+ Y; s* B& }
Stack optr,opnd;% x5 l D. u! g) ?$ j6 j; {
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
/ s/ g7 [( @* p5 ~2 \! z1 Y char c;; h( p7 I% W8 z3 g6 I* G: Q
char buf[16];
N: V' K( c& T7 R/ ~2 \2 P0 t int i=0;' n) o0 u+ T; u9 o8 }$ Z
2 U' g* ~" k. D' V3 ]% B/ z
InitStack(optr); /*用于寄存运算符*/6 }+ u& ]* A) a c- k( ~! W, C# N9 U
InitStack(opnd); /*用于寄存操作数和计算结果*/! E' k" V; O9 d1 u6 }8 [
memset(buf,0,sizeof(buf));7 Q. ^# M3 U9 y1 ?5 a7 `/ j
# ?4 S' c2 o" T printf("Enter your expression:");
$ p3 A, P. J) f) ]5 f) Q 4 }7 x5 K6 v+ |: Z7 B3 I
opr_in.ch='#';( ]! Z9 d/ i8 ]+ L7 F$ X. E
Push(optr,opr_in); /*'#'入栈*/
( W; N9 ^% s- O) @9 ] GetTop(optr,opr_top); V9 q( c6 r+ Q7 B. U. }
c=getchar();
( L+ L0 t4 Y( u/ {* B1 C. ^ while(c!='='||opr_top.ch!='#')
1 J: @0 h9 c% F& Z {$ `1 {+ _8 O9 D
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/2 F1 F+ v% u$ c2 c& N0 C: _' K0 ~5 g
{( L1 K* @0 e* z) T% c, N( ]# ]
buf=c;
' {/ n% F! H1 |3 C i++;
1 |8 @1 B: @+ r5 ]- \ c=getchar();
9 @! S, t+ S- b+ N" c }0 r, j. v+ ?9 {, h
else /*是运算符*/
) E& ~ r& e/ G {
+ y6 _4 Y" V( _ buf='\0';
8 u: W3 t7 ?7 e/ G/ ] if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/- S' d) X1 s- }& e3 ^
{
$ Q+ D/ E6 O( P- R0 o5 } opn_in.data=(float)atof(buf);
. b1 k( h2 y0 W; i+ g$ E% z- l Push(opnd,opn_in);
4 h$ y* A7 [+ \2 {3 O; s3 q printf("opnd入栈:[%f]\n",opn_in.data);8 F: e2 \8 ]4 D: n: a
i=0;1 r0 ^' Z# m8 N
memset(buf,0,sizeof(buf));
4 ~$ t ]; c- G) q o; U/ @ }
; F, _ {9 a2 V2 w; a: Y, f opr_in.ch=c;
1 ]9 G% Y) X5 r; I: t$ s. Y switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
4 W' Y1 E4 C6 s) X4 K {
; z9 Y; E$ h. y7 I3 | d5 P, K case '<': /*优先级小于栈顶结点,则运算符入栈*/
! H: e/ w, ]" r4 I6 k7 `3 ` Push(optr,opr_in);# u5 c! @* L# U5 \/ _' p
printf("optr入栈:[%c]\n",opr_in.ch);
: h% M0 h% G7 ]% `: e. W2 O, F* ` c=getchar();" x& C. m2 \( Z0 a9 t
break;
8 y& |: D+ L/ ~ z4 T case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/. J! Z* ?, s' ^9 F6 [1 g
Pop(optr,e);0 g4 s# q( F9 `4 ]; ?( z1 E
printf("optr出栈:去掉括号\n");! M2 X8 R" o4 @4 ~
c=getchar();$ ]" h- F' I* q7 A3 W2 d
break;4 Z) F4 i- r% k, d) u% C* [
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/2 \* I2 l+ `; ~
Pop(optr,opr_t);
! {( V4 }/ l2 t6 a$ X, q/ P printf("optr出栈:[%c]\n",opr_t.ch);0 j4 @6 E+ t$ S" b$ N) R
if(Pop(opnd,b)<0)
9 S! J. ?" x" T( ~ {
& V4 Z& n1 ~+ {. v: D1 K printf("Bad Input!\n");
( A% m2 E q9 O% S ? fflush(stdin);7 z7 H' }2 Z+ Z+ A& E
return -1;
% ~% B! @& X. U# }; g4 B }3 n/ m# X3 E) I J* ]# K
printf("opnd出栈:[%f]\n",b.data);0 ?; @9 `9 l7 g: m# y# ?
if(Pop(opnd,a)<0)% d" ]; t, j2 J, c2 d
{
) [) ^+ M# o7 }* p+ |0 f3 b printf("Bad Input!\n");
7 q3 ^+ @/ D9 Y$ `. ^1 `0 _1 c fflush(stdin);. a" b0 N$ h; ]
return -1;. ?* U: ?( f- J! r# @3 d
}
" N; X2 c0 o1 ~1 _, w9 d& J printf("opnd出栈:[%f]\n",a.data);
- ~0 S' d9 z1 Z) x5 x! j% S opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
0 |* `+ ~ [ w, x1 a) Z Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
/ u, t3 q6 m8 U1 q! P+ m+ t( t! U printf("结果入栈:[%f]\n",opn_tmp.data);
! f1 c, [3 @" s$ q) U P break;
: m @8 I7 \, H# M- q1 t, j [ }! Y5 N/ Z& j5 y$ C8 s& O- d. m
}
0 q0 d3 w: D/ ^7 R2 |9 j, \ GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ G; d& r' S! y0 _
}, C1 f) o) @1 F* f4 B
GetTop(opnd,opn_tmp);! s. C1 [8 f9 A+ l0 t0 g
DestroyStack(optr);+ i7 t( N, c# o Y
DestroyStack(opnd);. u) a6 r' z- ] W: _. Y. {$ w# J
return opn_tmp.data;
- W9 f7 B. R; s8 F4 A& U}
. p" e7 ?" G; q! x! P( C+ Q& l f1 V2 S
char *killzero(char *res,float result)/ o$ q+ y( Z# |! q. i6 Q8 M
{
$ Q7 D' g/ ~- }% v$ _: `. D int i;( a. m( b6 x1 H/ v, P+ E( K6 [- g8 R
# E2 ^2 p2 }8 H$ Z8 \: N& }
sprintf(res,"%f",result);
) C- @; s) D. W/ _3 }3 d i=(int)strlen(res)-1;! J% r" g2 [/ ^- {+ j A0 K
while(i&&res=='0')$ |- _, f% {+ |" w9 W# h* V
{
& b/ g, N5 H3 \0 x8 d res='\0';
( E8 S$ b" {9 G% D7 E. S { i--;& r* P7 V0 m: Z3 l! F7 @4 A
}* B) J4 x9 f5 Z" S" ~
if(res=='.')6 s8 q( p& ~+ l# _& r
res='\0';
& @/ d4 O8 J- ]/ \9 r% G6 D return res;
! m* u' b5 x0 }* Z6 ]}
! O& y% z/ Y: L. O7 E [+ F9 `/ ]
- z, b8 ?$ k( [ Y3 Dint main()
" y1 P% q6 E& s% b; Z% x: b8 U9 a{
3 ]2 O0 m) U2 H2 Q! F' j! l8 _ char ch;* X7 f2 X& r r+ A( ^& A
char res[64];' h. }0 \. y/ c( ~7 X* ~! |. B
float result;3 E q7 T; X1 T! }, S8 @+ `# v
while(1)
6 r* h f y9 N1 m( c9 i {* s1 l# Y+ v$ j3 l# k+ ?
result=compute();
7 ]" |* r) m& \9 b1 i" } printf("\nThe result is:%s\n",killzero(res,result));1 ]9 s$ X7 B( q- w
printf("Do you want to continue(y/n)?:") ;
, w6 }( G p0 m1 }: r8 G U: | ch=getch();
5 O; a/ R/ l# z: @, ]9 ^! _9 I. C putchar(ch);1 e' o9 A' W& H
if(ch=='n'||ch=='N')
9 k9 x7 s: j# |) n9 E$ p4 G break;5 z C3 v3 A' P* _* H' [
else
6 o4 r6 j" c8 d+ `, m system("cls");
# H" c% o# B w" f. \5 x/ c }3 t% \. t9 p7 {& u" O1 j$ s4 ]
return 0;
0 L* H, I# o* k6 k. u! ^8 f2 p}
' q9 l2 t3 S# O: F
: A4 V( k2 o1 P% c! s[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|