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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.% a' [1 N2 V. w# o+ y8 \
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=4 z: B6 {4 c, h1 j0 A W# v6 `5 g
/**************表达式计算器************/
0 C3 ^+ h3 V1 M: L9 ?8 _" u#include <stdio.h>
1 q' q% L0 a6 u#include <stdlib.h>* t# M; |: h" B4 T: i% w5 r* U
#include <string.h>0 e$ z; Z& Z( Y! k) ]7 ^
#include <conio.h>
( W. i9 }5 b& |, X9 B* L#include <malloc.h>7 D5 X/ P e0 n
$ W& u" J# F4 j* G
#define STACK_SIZE 100; A) z2 @9 `% U( _# P" \) u$ t; a
#define APPEND_SIZE 10
( M7 _* X. [ C! d" ]$ p7 ?
; C) P3 D& f9 v, E# F7 _ g8 l- ystruct SNode{
3 q, v: I# W) z. O- A- K3 v- p& Z float data; /*存放操作数或者计算结果*/
% t4 j& `; e9 u char ch; /*存放运算符*/$ L* M/ F) |& \# R
};
3 Z+ W6 c3 x# c1 m0 c3 W% R2 m
' f- Z! e; F2 R. a. ^struct Stack{
# m0 T2 q5 A5 M# R SNode *top;
: m3 ?2 M8 ~; l: G! C SNode *base;
& P" Y* C. ~4 y! Y* Z) r3 s$ Y int size;5 `7 [0 N" c; F+ ]& U; m
};
/ e+ x- i& i2 z& {9 ` p
+ }4 [9 z2 ?9 V+ I3 v: A/*栈操作函数*/
: G0 t3 k. ]1 t$ Sint InitStack(Stack &S); /*创建栈*/
0 L% ?7 R$ [: Q/ |9 pint DestroyStack(Stack &S); /*销毁栈*// e3 P. D+ W" f" ^3 I2 ^3 A+ D0 Z
int ClearStack(Stack &S); /*清空栈*/3 f l8 L0 q+ R
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/6 Y- K2 ~/ H2 [0 K+ d/ C
int Push(Stack &S,SNode e); /*将结点e压入栈*/
6 l' n; u0 i! xint Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/) V1 `1 D' q" L# H
5 n5 G" u( `; c g0 E& m
/*表达式计算器相关函数*/
5 Y% V8 I- K9 \9 g8 q3 hchar get_precede(char s,char c); /*判断运算符s和c的优先级*/& |5 W* f: R @$ M4 m2 o
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/+ Y$ G7 x* O3 \ O# M# q! x
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/7 l/ l2 n' S4 @& O
float compute(); /*表达式结算器主函数*/& n% e$ t. l2 W# v \
char *killzero(float result); /*去掉结果后面的0*/ 1 z1 L* D# b/ V$ y2 |* x0 Z6 a
! C% R9 L) }: m4 |& O. Oint InitStack(Stack &S)) U+ w1 w8 i5 d: h
{/ ^! J3 M6 {# y8 Z. K
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));& h) r0 |9 K7 e2 H' A K+ l' I4 b& K
if(S.base==NULL)9 m0 Z- b+ L" A
{9 C. Q+ n; v6 k! A' J- b
printf("动态分配内存失败!");, m& ^1 N+ c6 G" f9 o, L
return -1;& l2 i. T, c- e
}
- F2 V2 Q6 g8 E S.top=S.base;! U7 |0 H F4 b$ T5 {( v
S.size=STACK_SIZE;2 b, E, u: F/ q8 y; W5 m( c$ k
return 0;
1 }+ m+ X! ]& s}
0 J/ M5 P. b0 J; Y6 c$ `: U
$ k3 p% W- G6 v2 w9 F! _) L3 rint DestroyStack(Stack &S)2 P) P: z0 F0 d4 N
{
, P' d5 H. S5 P free(S.base);( ]4 \2 e; Y6 b) w' P( p
return 0;2 A' ]5 w* p @
}
4 O9 b1 X$ A/ h4 |" z
/ ], K9 o& m# Z3 K5 C$ [1 ]int ClearStack(Stack &S)
8 z) `" W4 B/ M) \. G3 Y{4 d r" c$ c8 g! T* \
S.top=S.base;! L" ~7 n, j2 H8 Q0 q7 k, m
return 0;
/ e z) O! @9 @! `& }3 p! H, J. G( e}
; R( \) O: U' O5 a9 r. p/ n1 q* U: H; a' Q: h' M- y' j
int GetTop(Stack S,SNode &e)
* R7 W* |6 [7 [/ e{% L( S# \5 B: I( V! h
if(S.top==S.base)
2 S4 ^) X1 W9 ]7 j9 A0 Q( b {, c! X$ f0 {& m) {( p
printf("栈以为空!");
2 ~( D% C; A$ D' S7 q' T9 d/ D return -1;' J4 P4 d3 ?$ o q* W
}: K! p' ?1 n: ?& R# a: Y
e=*(S.top-1);
! G) p% `/ j) v9 Z, ^$ F% |8 f return 0;3 |1 X a) |# C5 W! G/ I
}
) }/ o: J" A( f* ]0 E# v3 h- b0 F, y5 h y* B1 |2 u5 a
int Push(Stack &S,SNode e)
+ i. n. D: P! c{
" A) @9 E# p9 r; y% s+ x7 c if(S.top-S.base>=S.size)
$ o( k7 r, o: T V( n9 t I {. m8 f$ Y4 [4 z, U! s. d$ q
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
$ j% l8 S+ a) j- h, i* l x0 r if(S.base==NULL)
6 T! Y9 L( I# h5 a5 w. c4 b$ G, o {3 t, q4 E) ~: l: X
printf("动态分配内存失败!");0 ]0 m! Q( C" d
return -1;
$ k- g! U. ?7 L }
6 D% ^6 u" t: x0 B S.top=S.base+S.size;
4 J% w8 t$ \: U2 H* r+ v; d0 A S.size+=APPEND_SIZE;
1 n' S& F. N3 U! m. v) e4 L }
1 z4 i1 d# p* @' I1 t8 ] *S.top=e;2 N" r. {$ ^$ T+ @1 }9 t; E
S.top++;1 t9 W- C0 U( x8 ]7 S! B9 d
return 0;" D) ~5 q2 t8 r/ q
}
3 l' \1 q; M- a) @) B$ c! ]1 S7 [& X/ f
int Pop(Stack &S,SNode &e)! ]- o$ G1 z+ ]1 K! U. C0 b
{
4 V/ L% k9 e/ Q if(S.top==S.base)
% N3 ?/ P" g% {" I2 X {. l1 Q# B! P8 |/ K, f. s
printf("栈为空!");
9 l! s6 W# u6 g2 L; ^ return -1;" x# V( V/ ^- u1 k9 U
}
" S$ N0 m5 w8 ~. E e=*(S.top-1);
# \0 w1 p1 l2 h' m( n S.top--;
! I5 F4 D V- { T2 q6 E/ x) z return 0;; S' D c2 R6 N2 {, t+ V2 i" v& c
}
0 C1 k$ c* d4 [& }: f
, F ?; h5 n1 nchar get_precede(char s,char c)# A' }( y# z7 w1 a
{& d4 \" C& K. [! q; \3 P& g
switch(s)% S/ L% ]5 B9 R* N' Z8 u h
{ j6 v6 W8 q% Q- u! R! b6 }! P
case '+': * j; o& S: G* O
case '-':* |1 F* N) W# A8 s" N
if(c=='+'||c=='-'); p7 X6 y! z- `/ [8 E: m& Z. i
return '>';
5 C' q* |2 e$ \+ h else if(c=='*'||c=='/')% P* |2 z1 N+ A! N: o+ l
return '<';8 V/ _* [9 k# N$ O+ M6 P) c( G
else if(c=='(')4 G* t" l0 |$ I9 B; I4 T
return '<';, o% Q3 E* I; V: V0 _/ C! [+ ?
else if(c==')'); _# Z* t2 E4 u& Z2 d. r
return '>';
1 Y$ `& Q; c: i* Z9 e else
9 i* n4 ?! W: H0 t S3 s a; a! B return '>';
0 w" D. s! a5 E( ~ case '*':6 Q+ U& y! t# C, Y% u2 h
case '/':$ w+ C7 q* O5 Z+ E
if(c=='+'||c=='-')! C! I8 j, [" W2 \: h# |* Y
return '>';6 W- ]/ n2 k' I0 n: i* k. v- ?. Z
else if(c=='*'||c=='/')6 o+ m' j X" {' U8 n9 f
return '>';0 z: z i [( d0 T% H( S p
else if(c=='(')
2 y, ^: U, v; }3 C' N: Z* d return '<';6 }, K1 G' f. |9 w. ]# [
else if(c==')')
' h, A3 t) b' W3 e$ ` return '>';
! X/ i* m. a' P7 D7 O1 Y3 _6 w9 k/ i else
. ~0 G- \. d9 u* s n% u return '>';+ ^, G, g/ H& t7 p) r' q- \
case '(':9 N1 s0 |2 G$ r8 f: X8 o. y1 g. ?
if(c=='+'||c=='-')0 {/ o1 Y+ ^$ W) a
return '<';
% Y+ v2 X2 t1 ^) d( Q Q. r else if(c=='*'||c=='/')
( X \3 Z) K3 p return '<';( I' ~6 s; e z% X; d
else if(c=='('), L0 @8 N: n/ A7 _( U
return '<';
1 W, \7 s. w$ y- b, p else if(c==')')' `& H0 ~1 {' A
return '=';
9 _6 [' @% A) ~ v7 a. O1 P else% y4 _. f2 K3 V2 S* x* N" W2 J
return 'E';% Y0 S% d/ D9 U/ X1 G
case ')':
) N! q( E" Q2 T+ H } if(c=='+'||c=='-')
' K8 m5 M2 E: i: Q- e- {4 Q return '>';) A j- ^) v Q5 u- [0 ?
else if(c=='*'||c=='/')
: Z9 B6 R3 D# d: h, [2 j return '>';3 J" m" n$ T9 s( ]
else if(c=='(')
5 v0 O0 [8 j0 ^9 ]$ r1 X0 I% f return 'E';. z! A- E) O5 u$ M @
else if(c==')')
$ w4 w2 H- j$ T; d8 e1 ^2 i. N return '>';, M: |! \6 d3 E6 d$ w) w
else
9 `6 F* o5 Y. ]4 P! G" _4 q return '>';
& U3 T, h$ R: V' h0 n8 E- M case '#':
6 Z" E. U3 ^9 H9 R8 |4 L if(c=='+'||c=='-')! o1 }$ R/ p' K, ?- Q
return '<';
1 N# u; ]2 i: R. A/ o/ I& L else if(c=='*'||c=='/')
7 u# U J1 C6 `8 V' T return '<';1 r, i% S" M! @7 s# K" _' ]5 \4 c+ u
else if(c=='(')% C1 m! U& u6 X8 u9 _
return '<';
0 j. M' \7 V! P, H3 D* h; L; _ else if(c==')')$ A# l! [% o b5 _8 L
return 'E';: b' w, G1 U0 `, _& Z: f3 {; z
else
! q9 \0 u4 M7 t' i& f6 q return '=';( O( X* Z% S$ o
default:1 X ]% b% S! y6 l: E/ M
break;
7 j# R3 i6 a- Q3 E% n4 o0 a2 t }1 y, M+ M. u/ @- R- _
return 0; " L8 S: e7 ]1 D# K/ E( B- r# _
}
. W* G% c2 Y! i/ ]+ t) w! v3 w- L# K: }! D9 n3 f2 x
int isOpr(char c)( F, v) Y4 c2 a J" W8 Y
{ M! P D$ u$ S7 s0 ]
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')/ h. A) m- g$ c
return 0;6 S/ T% o( y! c& g2 \0 v3 ?6 j( `: K
else ; [7 y$ n* c9 U# T% R4 }
return 1;
- T' n" W) L1 e}
% |+ t& z" D" a- K }9 b# B0 {* H: w/ F
float operate(float x, char opr, float y)
: {% [, c6 C) P! ?( x{3 u0 V& k& D6 B6 t$ W+ |! A. s& P, `
float result;
# W( y6 t8 H/ X# U3 v& Y switch (opr), W3 m9 `7 j( y, f& W2 m
{$ n- A3 e6 _ U4 y
case '+': 2 y- X V2 i9 ]- z1 n3 }- Z) p
result = x + y; G; H+ ]8 D% f8 G: N
break;
( a1 ^! Z( ]* f/ @' u case '-':
: }1 h" H9 [. o6 w5 `8 a6 H( Y9 z result = x - y;
: m# @7 P6 p9 K7 d8 m break;9 L2 z& G& h C$ B) j/ D
case '*': ! D5 n d& ?: m9 J S% J
result = x * y;
0 _6 i; I* s! X. H% P break;2 ?$ S* G; K* F4 i2 T4 k
case '/':
3 P# @0 F- y8 l, O8 C, l if (y == 0)/ q) M: P% x6 T6 _
{! D1 U H0 ~: B, P3 s j: @
printf("Divided by zero!\n");( P2 N3 ?8 B! K4 r( Q, ~: @8 h
return 0;* | S/ t! I! i: Q# D) `. N
}: S- p& ^+ G& ^0 L% R
else- ]- z3 L( o/ B
{
9 j9 L9 a' D2 H+ y result = x / y;
- R: Y: U# ?$ \ \, e$ K0 B3 G5 l" P5 ^ break;
& l; x8 S* d+ Q7 A+ b3 i }, R% D3 x; ]5 h3 ~% I8 t
default: * C3 ~9 \; O' `0 N* S9 ?
printf("Bad Input.\n");
/ t0 s9 b2 Z5 A( Y1 K, d/ [4 \ return 0;8 i! |6 X! T& K" M5 e7 m" {( |
}% @+ k3 |) @6 B( N, R6 |1 S& c* n5 o
return result;" R8 B w9 R; G+ C/ q- J2 R
} 9 D+ {2 N0 L& R- M! M6 M
3 U$ k" h$ b" t7 R3 l
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
; @$ n' `) r1 |- _0 v7 V{- |1 M- ]6 h; G
Stack optr,opnd;
% {! u5 ~; V7 w) X9 t: r5 d( M7 h struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;2 K( {; m& g; Y$ ^
char c;
8 z/ J+ X) Y7 K' F char buf[16];6 F6 {9 z3 F( _* Z7 k' M
int i=0;
2 P. n. P5 G- } : Q- B1 X2 H3 u" E& H' w; X
InitStack(optr); /*用于寄存运算符*/, c/ `. R1 U, ^+ a
InitStack(opnd); /*用于寄存操作数和计算结果*/
' U# H- b) h2 ~) P6 z7 J; e! }# q memset(buf,0,sizeof(buf));
% z7 g. X2 G* Z0 ^
% x; i- Q2 M# Y4 h% I printf("Enter your expression:");2 ^# c% X# D" {! q* X3 ]9 [
2 V0 i8 O4 b5 Z' X
opr_in.ch='#';
+ \# t x/ c! A7 H Push(optr,opr_in); /*'#'入栈*/" Y+ J+ Z f! e- W5 o
GetTop(optr,opr_top);( m/ h( h; y( W# I' e& O
c=getchar();7 _4 L. M9 [/ k: [" l
while(c!='='||opr_top.ch!='#')
8 y5 W2 ~6 ?$ O3 P/ w {
$ U* D# z: [- O if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
- v* ]1 j- T& a: ^- y+ \ {4 t# D* V3 u) b
buf=c;
% y2 Y. [0 m/ P i++;& S/ H6 c5 }, I* w3 W
c=getchar();
& ^# X' H* _7 L+ s$ W }
. ?) B6 u2 |) l0 g0 S8 T$ X2 u+ p& a else /*是运算符*/. ~& }) [, [. N- k3 @# j+ Q0 {
{1 `- |( f0 Y* I/ v5 Q' K4 q
buf='\0';+ s& K% h1 V7 {7 q
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/) {7 b: p- e7 L& n+ u
{
+ t' J P5 s, |" S( W) Y" R opn_in.data=(float)atof(buf);# v1 k2 f4 h1 k6 x: Q5 J' u
Push(opnd,opn_in);
. W+ K& _. \% T6 }8 U printf("opnd入栈:[%f]\n",opn_in.data);
( Z! o& @& l8 c i i=0;
+ B1 ^6 ^4 C! b memset(buf,0,sizeof(buf));
: C- ]% l% D' x+ L& U$ f' k5 w1 Q }2 H$ C3 x/ b; ~$ w/ g
opr_in.ch=c;0 x3 S7 c1 s( X/ w0 o( U" c- W
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/$ f8 F: P+ c- p5 j
{
: ^% m7 `8 O# S A: E. x$ Y6 B case '<': /*优先级小于栈顶结点,则运算符入栈*/+ |- f6 t0 D' _
Push(optr,opr_in);
? C" Y9 V3 u! C" Q/ m; k# r printf("optr入栈:[%c]\n",opr_in.ch);
; ^2 q/ b4 v* R3 f/ `% ^ c=getchar();( o1 B! }5 g) f' ]3 f
break;6 [' J. {0 M: H$ V1 I R; \
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/8 V) v6 m* B' h3 A% `. E+ ~2 G
Pop(optr,e);
& a8 l, B( @* g' h" y) N" c- Q6 @ printf("optr出栈:去掉括号\n");
$ d- w7 q o# x7 k c=getchar();' W H7 {% [% y, R* x
break;' N7 T: k) k4 Q$ b9 Z. e0 W
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
: Z6 w1 u" `& X) r6 n Pop(optr,opr_t);
$ f7 p' Y7 W# X! v4 ~ printf("optr出栈:[%c]\n",opr_t.ch);
1 K# j/ h Q! x7 N6 H if(Pop(opnd,b)<0)- j* x, Y5 L, M4 ?, `# I
{/ [7 c& V" [5 S+ I
printf("Bad Input!\n");) V: B. r7 p1 w$ }
fflush(stdin);# M! Q7 w. E5 e U
return -1;/ d B( y2 @' Q7 F( F3 W5 X; r
}- S. j0 ~6 z& r
printf("opnd出栈:[%f]\n",b.data);
4 ]% N- }3 @+ F, m) f if(Pop(opnd,a)<0)" Q; C* _% Y) R- o- E, D
{
8 [" l& C H. i/ B2 f5 Q6 C8 C$ P printf("Bad Input!\n");
" e/ c" R* a$ Y; B. C2 K8 P# T; T fflush(stdin);
2 s$ `1 H0 K G% Y0 W return -1;8 l# C. d1 d; V
} o" A& @! f8 u: N% n3 v
printf("opnd出栈:[%f]\n",a.data);+ C, m2 h0 l- F
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
- V( R, M0 F' X% r6 P. w( f Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/. C l2 |- S: f/ S2 E/ Z8 c
printf("结果入栈:[%f]\n",opn_tmp.data);. I9 B1 |1 t) \ G, K3 J
break;
5 L% ?% p! c e6 m2 g5 r }/ h" N+ U" ~5 _: k$ w; @/ L
}
- [4 v9 u+ d# `$ j0 u* j: k' _ GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
. |9 G1 n5 @# j% s; M+ V! e }
1 Z9 m. ?- [, ~4 u) k8 L GetTop(opnd,opn_tmp);! G/ q8 x& X+ j' d# G, G7 ~
DestroyStack(optr);4 m8 D$ `! y6 ^. I5 ]+ x4 |1 m3 L) I
DestroyStack(opnd); G3 E6 c" ]0 U! {7 }0 G
return opn_tmp.data;
* Y; |) j# e4 }' t& g}
2 l, L5 _# } g& P0 C+ j( C7 | Y' r# O1 M, ^) O8 K
char *killzero(char *res,float result)
" c1 t2 Z* H; g- _5 ^+ ` o{( \3 X) o! t# g4 Q
int i;
6 M% e" p9 e7 S7 F& _; a: v% }) C: H% H$ W1 X% Y+ J+ P+ j
sprintf(res,"%f",result);- ^6 ]9 R' S0 _# G1 Z# c9 N
i=(int)strlen(res)-1;4 C; _% V% U& `
while(i&&res=='0')9 R+ N( U+ g. c7 ] g# N
{
/ g* G% x; r) }# R- y0 O$ f res='\0';8 Z4 b9 W& \- ^; M6 W0 e
i--;
" d/ W! V$ x! \, J; T, P: s }
5 o# j$ L, |1 ` if(res=='.')- }- |( U/ m% {4 G; v2 b5 ^
res='\0';3 n& h3 x5 |: g6 B. s6 A$ H/ F
return res;2 ^' X) I/ b6 A* U0 k+ S+ \0 e
}
5 e8 |- n& _7 ?( ?0 d$ P% U
- E8 e! M- p Q' P1 j V7 l, H( E2 Pint main()
: ]: O2 K+ Q+ L( {# c2 R{- ^1 F) i; ]& A. i
char ch;# F7 N' P- `3 [' I" w
char res[64];7 h9 H; |% E: M. e8 W; N. `
float result;
% r( u4 O! U& e while(1)
. Y/ e" C3 E2 M4 V- R. W- n {
$ u" p, f; Y2 ?, N, f: l7 W result=compute();) i+ v3 h- L: L* t x: `2 U. Z
printf("\nThe result is:%s\n",killzero(res,result));
! X$ m% W |1 g6 c8 O$ [- O: s printf("Do you want to continue(y/n)?:") ;/ q- Y7 Y- u* z- Q T
ch=getch();
9 H/ k# ?# g3 A9 [$ s: M! K: t putchar(ch);
* X* }- z! ~- Y5 v6 v if(ch=='n'||ch=='N')0 L: m0 Y" c% q7 ]1 H/ z
break;
, Q/ r6 w; p$ ] else/ t* P! K' r' `
system("cls");
* Q; [8 `* ^" [3 c }
0 b C, ^6 r2 n$ Q return 0;- f% F9 `7 {" r2 T/ r
}% Z3 x/ _& G, s- O+ }8 k
! G! x/ z- }6 C( z& Y* M[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|