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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
_9 j9 v. ?4 Y& `7 z$ C# G程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
9 D/ M6 J J4 m4 O% L( i6 ?- X/**************表达式计算器************/
9 Y. L( o4 O- e& j#include <stdio.h>
. A7 Y- u1 ^* p* x# N& _: r9 _$ `#include <stdlib.h>
5 D; W6 o0 e* Q& C) ~# b#include <string.h>7 F- D, e8 O7 p2 h Q1 @
#include <conio.h>
B# n; p, J5 R2 M k! y#include <malloc.h>7 H; y& k# C6 W9 q u
0 h) [1 J$ l4 Q J e$ r#define STACK_SIZE 100 R* H; i( p9 u5 R8 y
#define APPEND_SIZE 10
, N M0 R( g+ c! k7 L9 Z+ e) P8 Y
/ _: h4 d1 K% |! ]& q" C6 estruct SNode{1 ?' \4 v2 d- d
float data; /*存放操作数或者计算结果*/8 g# U* n: _9 |' R) G0 M
char ch; /*存放运算符*/
u5 Z3 F+ h. B6 S( d* e};9 U! _3 ^# {( w5 M4 y% X
2 q* g+ k6 |+ p. Q
struct Stack{, G# H" r+ D4 ^' d* v
SNode *top;! b% k8 x& @ e. L
SNode *base;$ k4 e) }# h- Y; y2 x
int size;" ?! P! A% d7 u2 V) l
};
% t2 B1 b& c3 C- v' [5 f1 ]3 w6 n" ~( k
/*栈操作函数*/; O. ]1 Q8 j, d
int InitStack(Stack &S); /*创建栈*/& C o- t; D' M5 B( Q. ~# T
int DestroyStack(Stack &S); /*销毁栈*/+ D4 [ W/ @7 K
int ClearStack(Stack &S); /*清空栈*/1 f5 U! y; I/ {/ D/ o& z# X) [
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
& W6 t% j9 e7 }& f4 Vint Push(Stack &S,SNode e); /*将结点e压入栈*/
- F. Q% a4 Q- O3 |) Q& j0 z1 `+ f+ wint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/2 f c9 Z' x: V# }% F
" Y& F/ s# k7 e# Z& B9 n4 o/*表达式计算器相关函数*/7 B4 S( ?/ ^. E( S& L% b
char get_precede(char s,char c); /*判断运算符s和c的优先级*/% n9 h; v% l# M& t4 L+ M$ [
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/% w0 } N9 k; b* O) m
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
" f1 {7 g1 d, g# y) J# ^float compute(); /*表达式结算器主函数*/( S* \3 c! n# C/ |1 z( B
char *killzero(float result); /*去掉结果后面的0*/ , a" |) N% D* \4 E, K; c$ `/ [ l
# G' L9 |! O9 q7 D1 m9 D6 ^* ?9 `" N
int InitStack(Stack &S)
3 N% E y6 {" c" r% B) S{
+ q7 x: j. p) J. J; ~6 Y S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
6 A3 U# d6 p6 A! l if(S.base==NULL)( I# T' y: x- i, f" r( d% M, f
{
" [8 W/ Y6 \) F- \( f7 A printf("动态分配内存失败!");3 e" q! N, N/ u( q: j) ?) X- F
return -1;" }3 ~2 W) n" P; s D6 H
}/ |0 n% |5 f& d# |! @5 b
S.top=S.base;
2 ^' A! w; P% X S.size=STACK_SIZE;
5 `7 L. k% U) |" I0 l8 K4 K return 0;0 x x+ b+ E* G, j; q
}7 o4 C" D+ L4 r! V) P) ?! N
+ D& P2 [2 r6 u" @7 x( Y! _* W: F' v
int DestroyStack(Stack &S), J, U% W' ^' i
{. r/ K5 a8 `0 @$ Y
free(S.base);
X5 J% a) n7 S- m# o# r, Z return 0;8 G5 @, x$ x& C4 b( W: g) q
}
2 a* A. o' w8 ` P u& B& o# L6 B; w' v- B/ C, O5 U) v
int ClearStack(Stack &S)
( ?$ c8 t1 Q5 @" G! j9 `0 R{
7 x' l! L6 s5 L+ m( a+ { S.top=S.base;
! M( W4 c( w, z# t2 g return 0;- p8 G+ f7 v" o" w
}
) a2 P [) T& Y) F( z1 z7 h( G/ n2 e! f9 W7 T& f
int GetTop(Stack S,SNode &e)6 ~0 s' A& Y9 m) f. M
{
. Y2 X; P. C+ Y! k- \ if(S.top==S.base)) X R; x) S" \2 B7 z H% f
{
* g' I& A, S) T: a6 l* {8 x+ G printf("栈以为空!");
) S j7 W; \3 n# o return -1;
2 Y" {- F3 v/ J4 h! K$ y }' y* D3 g) ]/ Z) ^- h0 P% H R# i3 @
e=*(S.top-1);8 q' R; k8 C8 H+ x; W8 z% p0 V4 x
return 0;' w; ~9 |8 f9 t
}
S/ U& Y% K* R; [$ P
& ]( S" O0 y q# }9 P5 T3 aint Push(Stack &S,SNode e)/ B7 u, b1 P. P$ Z; ]
{
( t" o& W* V) G% Z! P( ~5 s if(S.top-S.base>=S.size)
/ E4 j8 {9 Y) Y& a( C5 j {
4 n/ G. Z" Y# ^1 }2 m8 t S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));2 F, q0 w4 u% h$ t
if(S.base==NULL)
! c7 E% I6 T }: v {
& D1 S' ?2 w8 x2 u: s printf("动态分配内存失败!");5 v1 ^" X. z6 I* |6 I3 u
return -1;: x8 s; W0 V; V
}
3 C- f$ B! ?3 [+ g7 t) j$ [/ E S.top=S.base+S.size;
% I& R- k( U- y" Y# s9 d/ O S.size+=APPEND_SIZE;4 g+ X+ L) {+ U; t+ |, i6 d7 C
}# S* l) Y& c; M8 M& K# u
*S.top=e;- E5 K& s4 i( D* r
S.top++;; N- u0 m# w7 N5 L1 l
return 0;: l( o0 E! a7 ] }
}
. |7 F, S" a9 d& v& D) R6 h) r+ `) X; k- W% H
int Pop(Stack &S,SNode &e)3 J. a* h9 q+ G2 [: e) g0 V
{1 ^ v' h. v) T. \+ c2 r; w5 P
if(S.top==S.base)
4 h% r$ |- R8 N/ \' d- B" J- @1 [ {
1 L) a X' h$ V, v3 _6 e# h# H printf("栈为空!");/ }# l. J, Y8 n" c9 P' z
return -1;
i9 \: g) H9 f- h: Y }* k/ k$ v: f7 P8 R Z/ g9 j
e=*(S.top-1);
8 B, V! k; S+ |4 ] x" k S.top--;+ ]7 R9 W& W4 z$ Q/ q: P6 T% B9 }
return 0;( O# E, l) V- i* ~
}
! M/ X1 N2 k- b0 M) i$ a. ~
3 X: h3 m; B/ C! q6 l2 e3 uchar get_precede(char s,char c)
8 ~4 W8 {% r* F0 J* R{
5 D9 } V1 P6 L; `( j* J7 K switch(s)
3 B% O( ~) F' ], i; ^! p' z$ N {9 t9 o: X# Y7 Q' w! A( j) W$ q: ~
case '+':
0 g6 Z" b/ U1 p7 L. h- } case '-':
" V( J( R' B { if(c=='+'||c=='-')/ z3 s1 U/ c" f- g
return '>';. }4 A. q+ h* @/ J0 r7 |" p
else if(c=='*'||c=='/')
+ o- X& ?; e7 X/ ]- f return '<';4 D% t) ?/ M6 a) ~+ i+ {5 B
else if(c=='('), `2 t1 }4 u% @4 g$ i3 Q7 q
return '<';) W- Y' b& Y$ M8 c6 F
else if(c==')')
( J1 K& S. D* X return '>';; n8 `& A/ V y) S9 `
else
8 G7 Q2 L9 H6 n7 y! C; t' U8 u return '>';2 i) V, Z* {# q2 {+ o/ v
case '*':
& s# c8 h* N+ a' ]: m+ A5 b case '/':8 X3 z) M3 [4 y) K$ r
if(c=='+'||c=='-')
; K& `% a h: I. M2 F, Z8 `, R return '>';
4 i4 T0 |8 C9 S( l/ B4 o- v else if(c=='*'||c=='/'): p% v) c5 j# o: c
return '>';- c6 p- U& c! v
else if(c=='(')+ q1 y0 }, v+ `! O+ ?, j
return '<';! w. {% P t7 I" m$ d( L
else if(c==')')
5 {+ C5 g: z* i# Y) ? return '>';
' {: b& i( h$ j: Z0 p: a else: P7 U2 Y! Y5 Q
return '>';
$ E# l9 v% ]* F1 ?1 K; r case '(':
; O8 h! L3 [+ X! O5 U+ d if(c=='+'||c=='-')$ o, U" F. h" y5 s) f' y
return '<';9 D8 m9 K% A* n9 j/ g8 q' @9 L
else if(c=='*'||c=='/')
8 T5 ?7 D" U, K& q return '<';$ V9 U. T, [4 `$ O8 l% n* ~) Z
else if(c=='(')" B- K6 {# } ~
return '<';6 z% g1 F4 o$ E! o1 u; s1 _
else if(c==')')
3 h# _3 ]) H: r4 q6 @. {1 R return '=';! {" l* a7 z3 f' |. h
else* j5 d; N9 @0 C5 E/ X. m- `
return 'E';5 s( V' |: n/ c
case ')':
+ k; U3 {' q4 _& s5 g# ?& ? if(c=='+'||c=='-')' o% t' s- t# r/ j
return '>';2 O3 C" c& s- f8 p/ ]* s
else if(c=='*'||c=='/')- A) D d* k1 W) Q8 G& M1 U; I
return '>';
% O( i! i6 Z/ e else if(c=='(')
9 m# t" e/ h' e4 T return 'E';
3 T% c% ]5 m( E else if(c==')')5 j0 e# C' l# [: f
return '>';0 l' q6 w- A7 }: \
else8 Y8 p8 |! m( L
return '>';
+ ~* ?, c" u3 M7 x- B: K case '#':& l) K4 C/ e6 L; K4 I9 U) O
if(c=='+'||c=='-')
& N5 a- F+ D H return '<';
! A/ o6 R! P2 ?# I' W& k& c a! @( M else if(c=='*'||c=='/')
% l: o o- {1 x7 ^; w, ?8 w return '<';- \& i1 F8 x# c3 b1 [
else if(c=='(')
1 c: x' k; @# m) N _/ h+ Y4 v return '<';
g" l7 u4 y6 k' c I5 Z else if(c==')')
# A3 {) F( @3 k' D4 C* p% P h return 'E';- G6 j/ t# [" `
else3 ~# x+ c, y, J+ H8 a
return '=';, \& w" j! V7 c( }: D
default:
; K, q* A- B* k7 h5 g9 b break;& l: |' B, \3 n' ?% B
}1 k3 o& D( o1 E
return 0; ( G# {3 ]( e, C' e9 L
}
' m# \/ }% h. E/ u9 T, H1 a2 e$ R+ x) @
$ m. Z. ?4 |. p7 M$ Lint isOpr(char c)
$ F4 E, M9 q+ P{( W9 [3 o- {- V8 n4 ?. J
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='), y4 x1 `' w2 r$ V. d- H7 m& }
return 0;/ j3 t: p) s2 m; g* Z$ }
else
) @( X; _; r5 @9 _( d, ^3 n return 1;- N: N' q( |* H0 x+ [
}8 G: \* T: I& W. _
5 a& b7 T" e1 d: D7 d+ U0 D; o
float operate(float x, char opr, float y)4 Y ^' s* q u# h6 H' V
{
* e# H" V- I. [) G. a# F. | float result;: M; a! ?: J: `8 m) e8 H9 A$ e8 F
switch (opr)1 q) @1 y$ _+ O% A1 V' n$ k& Z
{; e8 E. ?' \1 P0 q; O3 B4 F, `! p
case '+': & Z1 s* s- f- h: i0 |
result = x + y;9 x( [: i9 n9 _
break;
' @2 s8 u: A6 ~ T7 O6 E9 x1 f case '-':
) h. z" d- o1 u; i: A) }4 R Q result = x - y;; `* T; |) a$ `+ p& P
break;
) H0 J8 b4 ~7 f( C' i n case '*':
3 @" S3 o- v% m z result = x * y;
, r, w1 v$ x" V! ` break;8 I, V( T( T8 }) T2 a* g6 i
case '/': ) u3 P! Y U) Q: ^
if (y == 0)
' K* S4 d5 ~* s6 ~ {
& x: N+ |6 M+ I% b5 M2 s5 ~5 V printf("Divided by zero!\n");
1 v. }, Q; c2 M( ~4 t return 0;( V2 p& F% h6 C& b4 L+ h8 J# V1 x7 u
}4 E; K: S3 u6 j5 K( d; @& o6 h
else
5 l- f1 t/ s; ?5 Y1 { {7 a; u0 x9 Z5 `6 g y+ _. M2 l
result = x / y;
* @. f* J$ G0 P. O8 ` break;. i% d* L8 L7 F4 T' g" s! a
}
$ ~- m8 @7 M0 x: Z default:
/ c; r, U5 p: R. K! ^! I printf("Bad Input.\n");
) W" F; A0 Y/ S$ m3 M: ~2 C' E) d$ c9 t return 0;4 X' B; }$ T7 v4 J3 O. c
}* N# L7 h. e" q
return result;
|) t n/ n2 S7 E}
^& u* z& \7 |" u; u, T9 b
! ^0 f8 Z) N) V+ _! | Y1 Mfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/) ^2 c* O& Y( P" t) b* M! T6 I
{
S, s. D9 N4 k- ~+ I Stack optr,opnd;& D7 K3 w# g; ]* ^# e$ v4 Q v
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
" K! t4 Q) d+ q char c;' p& @0 |- U6 l1 @+ t) S
char buf[16];- Z% ~6 K* W1 e) @% P X+ }
int i=0;
9 n) ?% S' D8 `& d
# K. V9 D5 T! i% @& q InitStack(optr); /*用于寄存运算符*/
7 A8 s' c# R( I$ E D6 o& g7 ~ InitStack(opnd); /*用于寄存操作数和计算结果*/
7 `/ |0 I/ @7 r0 G8 f: { memset(buf,0,sizeof(buf));6 h" G2 V1 D' o+ M
% W# S. V a! I) P0 h
printf("Enter your expression:");
# e% D/ f/ P6 g- t. y 9 I6 c }8 P) H% _" a6 o( r
opr_in.ch='#';
2 T: n6 N- t* ?3 r4 T Push(optr,opr_in); /*'#'入栈*/; F* c' l9 k0 ^. t2 I8 M) d& E
GetTop(optr,opr_top);
- M" J8 `4 E) @, ` c=getchar();' M, a9 T Z* e* Y
while(c!='='||opr_top.ch!='#')# P1 q2 `# h, X: Z! W2 n
{
, Q1 N2 |: N" @* g% W+ E$ O if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
+ \" y+ T% e- ]7 I8 ^$ x+ | {7 C/ v6 B" N2 Y5 K
buf=c;) i) T. i! r9 B2 [' R
i++;
. Y6 q, \6 F; i9 _ c=getchar(); q3 J# f/ p; B- z6 w+ }/ I! V r
}3 H h% S1 X9 p
else /*是运算符*/
- s/ L# v$ t x" g8 e' K {
8 {9 `& u2 k9 a& p. d% Q buf='\0';
( l. @- U4 X9 i/ E" L if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/: m" O, `* I1 A5 M
{1 G( }0 E8 `4 C8 T1 A7 p
opn_in.data=(float)atof(buf);" ~/ x" l* ?$ X1 ]7 r
Push(opnd,opn_in);7 q% ~6 r. K% u
printf("opnd入栈:[%f]\n",opn_in.data);
2 Q, u4 u, y9 [ i=0;
) N* G# |) V0 ?; l memset(buf,0,sizeof(buf));
( Q: n* S4 [" |4 E i9 Y }# F: l! [# j7 P9 ~" U1 V
opr_in.ch=c;
3 [$ b/ B8 e" U) j switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/% e6 l; D5 P2 y! t: z& r
{
4 t& `" G+ X0 G9 r5 b case '<': /*优先级小于栈顶结点,则运算符入栈*/& G6 B7 h7 K2 h: S" C
Push(optr,opr_in);
. O8 _9 D/ z- r printf("optr入栈:[%c]\n",opr_in.ch);% w1 x: y, h8 i6 B8 x! d% s
c=getchar();* G4 ^8 A' `! Q& z3 y8 R" |
break; \1 ~4 ?4 u5 }' V
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
( v. ?2 f" ~( p& N$ { Pop(optr,e);
- [9 `% t5 p3 Y8 S" a/ X7 a3 r printf("optr出栈:去掉括号\n");3 D) h$ X: X* E( k6 e
c=getchar();+ k* }) k# ~/ W+ T+ E, A5 L/ |) l
break;
+ K1 r% y+ y; c4 G0 }; W; s' p case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/: E/ e Z: k& A/ ^( P( J
Pop(optr,opr_t);6 O2 {- f6 A: V
printf("optr出栈:[%c]\n",opr_t.ch);
9 E* W1 V+ ^; O+ E' _0 D. v/ A if(Pop(opnd,b)<0)+ r4 N4 d/ F2 {$ I
{
_, R2 M; f' l# w1 b! P% I" f printf("Bad Input!\n");- u9 D+ J$ _: {2 n' |2 f
fflush(stdin);
( t+ Q: Q9 u5 `1 {8 u0 Y7 T# C' J return -1;
4 c% @( ?& g3 `6 C0 I# z }
) F+ i @8 c) u9 C printf("opnd出栈:[%f]\n",b.data);+ Y# x+ \; ~/ F( L
if(Pop(opnd,a)<0)3 g1 f- n' p& c" f3 W
{0 Q5 \/ I- u1 r4 C! O
printf("Bad Input!\n");
9 }7 M" J7 M7 f fflush(stdin);5 Y) `* W' K7 i9 k' O- @
return -1;
! c1 `3 J6 x! i" U9 B! q }
: D4 S7 r+ z4 m1 c printf("opnd出栈:[%f]\n",a.data);
3 u7 L' J+ b4 Q2 y7 }1 p0 v1 X opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/6 J" H0 ~0 w' I. W3 l5 A, U0 ?# y
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
( i2 z8 P8 S" J: Q printf("结果入栈:[%f]\n",opn_tmp.data);0 e- b5 p0 j; E6 }' f
break;$ r1 h7 o. O$ @( j7 A# S
}7 \! V6 [- u& y5 T0 {
}9 n1 k' @5 G2 f6 C1 f; I
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ - b# @6 l% ]; T1 ^
}
; E' z3 q" @/ i: Z5 D/ ?& h. z GetTop(opnd,opn_tmp);, o9 _2 N% }3 ]; t3 `
DestroyStack(optr);# Q& F; i- U) y$ _ Q- u
DestroyStack(opnd);9 L6 S) b u( O
return opn_tmp.data;
" A7 N1 Z1 J4 @! f. e/ F5 _6 `}; J. R6 R/ P( S; }
! j4 K; ?% R' H2 t4 g
char *killzero(char *res,float result). @: g0 f7 W( X; V
{ N5 H/ Z, ?) @1 F, S5 k1 w
int i;" O4 E0 M2 Z7 k1 W
: k; S" q% m) I* `! V
sprintf(res,"%f",result);
2 _! E) g: c% A" r i=(int)strlen(res)-1;
! u+ k8 m0 g3 ~" O. C while(i&&res=='0')
- J& O5 w: B2 H2 y5 S {+ x0 Z( ?# n8 y. j4 p
res='\0';9 w! X& c4 ^: k
i--;
$ m# ?' M+ l1 f7 s: d' d }
" r9 _1 T5 J6 a2 U( m if(res=='.')* x% w6 c! t( R% Y; @
res='\0';9 B' a1 N# k* c! a8 Z7 i
return res;9 w' j' ^* N6 |+ M) @0 U
}9 l6 M3 p4 ?; t' @
5 q1 `# z8 x! a( j6 y- U( m, B6 u
int main()
8 E* S' Z7 K" u2 H9 ~8 t3 S$ v# E' i{
w3 K8 N) O& s9 b char ch;
) J' B2 @! I4 v char res[64];
" L9 M' d8 [0 j7 G float result;5 I8 R2 j- l7 M8 ~& w* j
while(1)
o1 B" i& G x+ N g0 T {
1 Z: s; g& h, @5 l- b! d+ T result=compute();1 K( s) o) N+ C! ?8 q
printf("\nThe result is:%s\n",killzero(res,result));
6 ]" Z8 P( a8 y- o( _ printf("Do you want to continue(y/n)?:") ;
: s) z+ V) N" J6 E. S- D ch=getch();2 \ B% `5 `; a6 b
putchar(ch);
( Y6 [' i# u$ M# Q/ r. c5 q; ` if(ch=='n'||ch=='N')/ _5 r T) G" ~4 C
break;
6 \, M: M1 V! E* f0 Y4 _ else
7 ?" _; j1 b, n( |- k) P' B! Q system("cls");
M6 \, [) h9 `: I. \$ m }% P8 d+ x- b2 b# J% C7 i
return 0;' l, S* v+ m& v) i3 d" e
}7 `( Q* x; y3 B1 Y- X s$ Z' T
7 o Z% r4 S; R[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|