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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
. H1 o. L+ F8 c; `: T- u程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
/ O3 c4 e5 y# y, M! R) x+ `& f) K1 E( f/**************表达式计算器************/; ^6 Y8 l, D3 j1 x
#include <stdio.h>+ O: S% s M- ?" H( W+ k
#include <stdlib.h>
B- W3 ]. L, t4 z) z6 D4 m#include <string.h>
& g! p. x( b$ g1 A3 X#include <conio.h>
$ l- Z3 F& o/ C. V& _4 R#include <malloc.h>
- w- A f# I. E- ?0 l9 n5 P) O
1 F2 M" g9 G1 N, ~: A* h; C#define STACK_SIZE 100
1 m, s9 H( `. @/ @#define APPEND_SIZE 10
( i2 p" W* U, w Z6 d* \6 x+ _' b. @
; s* y I# N0 d1 pstruct SNode{
) L* ~* |. l: w0 ~" u float data; /*存放操作数或者计算结果*/
7 B3 P. J1 ]5 C; t char ch; /*存放运算符*/
; O, `2 R: a. q% `$ s: v};
" [8 o! z/ B8 [3 Q5 T+ Q W5 Z# y p8 Y: i( F
struct Stack{% I9 Q$ {+ H5 d3 {, n( {! o5 _
SNode *top;
& w; s/ O3 ^; N1 h2 g- a- ?) i0 a SNode *base;+ e+ L. N$ \6 z( h; e' w8 p1 ? v. M
int size;
" }* F0 H$ F" u4 G5 U2 r0 X e};
2 u0 d& h/ f9 a, x
5 x6 @4 ~( A8 e1 p7 m/*栈操作函数*/
9 B* l& a* ]3 k! _int InitStack(Stack &S); /*创建栈*/( g' @& h/ b0 f1 c7 M
int DestroyStack(Stack &S); /*销毁栈*/0 i1 i3 i% q, S# O. v! @1 b& f( t
int ClearStack(Stack &S); /*清空栈*/
+ t- b0 y# t, R% e1 U$ ]1 H# cint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
$ f0 S8 k# e3 m4 P* U* h1 Kint Push(Stack &S,SNode e); /*将结点e压入栈*/4 `2 A" K7 `' U+ F* y P9 P
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
/ q w$ l/ D: u' M, u5 x( i, c5 X& Z) N) o
/*表达式计算器相关函数*/
0 w( t3 B% R4 Uchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
) s: O; c+ K: H" G% Iint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/2 d# B! y6 A! Y1 B! A- d
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
8 ^; E- u+ |7 i. v* M8 c& Ffloat compute(); /*表达式结算器主函数*/+ P0 z# R1 H4 D. ]7 @' _1 p
char *killzero(float result); /*去掉结果后面的0*/ 3 \" }. w3 \0 E9 A! T5 m1 O# X& l( n
& T A1 y k' `' eint InitStack(Stack &S): W: R. v8 U* A/ _( B
{
, U6 t/ B Z; P' d! L S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
6 z7 [" c$ ?$ ^# E if(S.base==NULL)! p* \+ i/ T- W: I% R+ c9 J
{
( ?# J4 O$ j: W! G c- Q printf("动态分配内存失败!");
! m5 @) {1 i$ U! q4 c3 i& M; G5 c return -1;3 L* E/ v& i, k5 H' w
}# c0 f; @ K4 z- k, \5 G- ]
S.top=S.base;
6 p. `; B6 ]; s1 D S.size=STACK_SIZE;0 b- n' {- J1 n" j2 {
return 0;
$ q/ N% \3 H3 K6 S' K$ R1 H}
6 e( o! y) Z) w6 v* u, X; k+ l
' a) p3 ?8 j' }0 cint DestroyStack(Stack &S)
/ S; L/ R% y5 g' K! N1 r% {0 q{
) j8 W. {* Z E. r# i: i free(S.base);
- r$ k7 o% X; J0 c; V; O return 0;( T0 L1 l% S9 G2 O# J" w- w. U
}
# _/ n5 a$ Z" ?7 ^# E: e6 o3 C$ u& z4 G, g/ ~+ V5 }
int ClearStack(Stack &S); T" W O! u& A/ k- h* h! @
{- k9 K0 g: e" A' ^- ?, G, v
S.top=S.base;$ v5 Z: V1 m" Y) E7 c7 R
return 0;
5 O) p; B+ E* V}% ~5 M9 [: i; r, x6 w
- H) W }" b7 L7 L4 m% t' Y( zint GetTop(Stack S,SNode &e)
" f9 v6 _9 A+ r6 D{
5 r: v& f# y' U& E% s) L' _ if(S.top==S.base)' t" m# x' g6 E7 _0 w
{
. K ^3 {) r; Z& F$ i. l; v printf("栈以为空!");
3 u( b% Y& ^# w* I+ O- m% w return -1; z! a6 c4 ?4 w0 Z1 e) t/ G7 u' k
}
8 K/ d2 a, G7 Z e=*(S.top-1);
! y, |. x3 W( a2 G0 Z( ~' j! K return 0;
2 A. G2 ^# r* }& }3 _+ ]1 ^}- ~% F! `) w* v/ o' [" r i
4 b) P5 B0 z" Z3 @! [* lint Push(Stack &S,SNode e)0 h# [) v: @! u& E. {& c; K, |, M
{ q* g2 v: v u0 q! ?
if(S.top-S.base>=S.size)
* m' ?7 L. b2 Z! C- v" ]/ E {
# [. }% B& t+ i+ I S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
; Y5 r3 s/ e: U" e$ d# H/ l if(S.base==NULL)
$ ]* p6 j) W! T6 ~" Q9 [0 M/ j {# }# l# j8 _/ W( W: m9 y# a+ ]: c
printf("动态分配内存失败!");/ V/ C( P6 Y5 N6 ~
return -1;
~% z% }- d2 O ?% s. V! n. ?3 k }
3 i( A5 ]0 W; K! ] S.top=S.base+S.size;/ P! A& d1 e' Y8 c& N4 [
S.size+=APPEND_SIZE;
2 \$ T+ t, w' r$ y2 I: p }5 K9 k3 N0 ?3 E1 b. T2 w9 _
*S.top=e;& O7 `: I9 a; _/ M
S.top++;
, Q4 F6 W. n$ B return 0;+ G) ^" d% z, f8 {
}
' S- Y- @3 y1 {* W# J6 Z6 U% C( n6 J( [- Q4 f; j4 {0 x
int Pop(Stack &S,SNode &e): R: i9 z+ l8 d% c
{3 h# T% Y: R1 B/ ^) x4 K( U
if(S.top==S.base); J. ^ _6 D1 k0 B! y' l
{: [( A5 o7 C' T, |/ R& f- ]+ j
printf("栈为空!");
- c9 P( O9 z8 I9 G+ y* q return -1;0 v+ L! M- r A5 d3 M; H# C5 j
}
9 _' x$ @5 q) S j: W e=*(S.top-1);
( d& _! T% o& e3 u& B0 E1 N S.top--;" Q2 W s$ E2 @) j1 s5 g
return 0;
2 r9 t3 ?0 Z t# `3 P3 G}
& ~2 y% ^6 ~& H" U' `- O# |+ D# [ ?
char get_precede(char s,char c)
1 e* B: \ r5 c2 s{
; q- }. G$ E+ Q9 e' a switch(s)
8 Q/ G0 Y# C; C$ b: ^- ?2 L @: H; q {, H f' T/ T' a7 {" u4 k+ c* l# B2 S
case '+': ' Z; H- v& w% W e1 e
case '-':
) Q$ I/ g& e* m. T7 D if(c=='+'||c=='-')8 ]3 l- \5 C" Y5 }
return '>';
5 R, a0 i- [5 c2 f; K else if(c=='*'||c=='/')
6 u2 n4 k8 R7 o/ L return '<';
3 }: i* z. a+ j# I% w$ E else if(c=='('), p) e5 V- L. w, X
return '<';
. T" S* o& i0 n' `6 }6 ?0 l0 k else if(c==')')+ Q. H5 b) f0 c" B8 o! r
return '>';
2 N% X6 D5 B7 | else
' H3 q! b/ S' X# Q( ^, j' j4 P- M6 U return '>';- h: W0 Z+ e/ M
case '*':
0 Z7 H n3 m3 W: }" D case '/':
" J7 O- L, g9 T$ o8 `$ i if(c=='+'||c=='-')4 w' r! a! W ^+ {5 o% A* g
return '>';9 J. S. _ s9 [0 E; t
else if(c=='*'||c=='/'), y* S) S2 ^9 Y
return '>';
6 ]8 z8 r* T! |+ q! g else if(c=='(')3 }) J3 e: ?/ f( ]( ~5 H
return '<';
+ n. Y( y' I0 o6 p else if(c==')')
" g* Q2 `" k( B( Q return '>';: ]/ S8 E4 _# c. j6 k# J( s2 G* m2 S
else0 v) F) x% M4 V, Y1 y/ g# D5 x, R
return '>';% I+ `' Q$ ]4 _0 P# m4 H+ t9 L
case '(':
6 X; D8 _% V: O6 D if(c=='+'||c=='-')
2 h4 g: Z4 _7 \/ K( } T! v return '<';+ W$ t# p1 c$ G4 c$ L. t) a5 L' |
else if(c=='*'||c=='/')
& O- x5 D3 e$ f0 c Z( N J" y. C return '<';: F) L) C4 y9 ]* r4 I; |1 x
else if(c=='('): ?! V0 w& W6 J }9 I! m+ S
return '<';! C* q5 \$ ~8 f9 d( W5 @/ C8 \
else if(c==')')
9 j3 ~! [1 w% W- _6 t) t6 w& u0 v; q return '=';8 \* H. x: w- q9 l& I+ f2 i- O
else* g- ?: Q2 G8 K3 X, F% Y
return 'E';. `1 u3 X" R# ~1 h/ U. E
case ')':! D4 s) W7 R+ \/ s9 n% A. [9 }: d
if(c=='+'||c=='-')
' J0 X) i* f6 ^% R7 x3 f; Y6 K return '>';5 b2 n9 L( Z, i: a2 d
else if(c=='*'||c=='/')0 t9 m( e) i( E
return '>';; N' t, s6 a) N: ~# ^. i
else if(c=='(')# o* ?% ~7 S O9 g3 Z
return 'E';2 _: F; u* I9 o6 |' m
else if(c==')')
- }, H" Y w9 w( x3 r" q: G% [$ o6 I return '>';
8 B V( i; ^# g; e" j else. L1 P" e+ B4 F2 T
return '>';: ^9 c8 i. x2 T) B7 J0 Y
case '#':
# |; ?" I6 j7 X \0 P! f if(c=='+'||c=='-')
! D7 k9 f+ A. I return '<';
" F: w: ^! `) h else if(c=='*'||c=='/')
, }0 @9 @' R$ ^4 q7 i+ X return '<';7 w: n! g2 Z, P
else if(c=='('); }5 _& ]. M3 Q% {
return '<';
+ H( Z) T: B V* ~' T+ x7 D else if(c==')')
D0 n4 C) @/ c# I return 'E';
8 P0 R, ^9 ]$ N, e! [ else7 T3 \$ f6 n' m4 Z! p
return '=';
! s- f- e/ ~" l default:
/ v! g3 E6 P, l# Z break;
% M2 k* W( P7 ^8 F }& ^/ ^& f7 r2 e" ~2 z
return 0; % ]$ O" g$ X% w" f( B, E# ~9 d0 L
}! ]/ G" @: e$ B$ [2 c* O
# ]7 g& k* M% q/ z( fint isOpr(char c)
5 @5 Z8 j, q( y, M1 {& {{
( f" }: D7 v2 d1 U7 k if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')" Y* Y2 J# S" Z+ {) m: G
return 0;5 V3 C& d0 X+ N& f
else
# y8 u: h0 w8 } return 1;
1 l5 l w# r2 X. Z4 B# C}
* F1 _* E* O/ T& w! ~
$ ~1 s+ N3 |: w+ q0 E- L4 Kfloat operate(float x, char opr, float y)9 m5 l, Z4 p# l/ }+ ]# F( H
{
9 z5 K7 W b8 O+ z L float result;
; F3 c C, |2 `9 F6 }# J% N switch (opr)4 n- x5 V B5 B, J! x
{$ S z: v/ i% \. m/ L P
case '+':
. h& @9 x* e" J- j& n5 d4 J result = x + y;
9 Z6 e% [2 K2 u) ~$ P break;& V8 P+ R2 z/ Z1 D6 ]: N4 j9 N
case '-': ' l6 w! C' z: ~1 x
result = x - y;5 q& W; a/ j4 p2 N3 O
break;
9 }5 Q" A [/ _& ]2 T2 r case '*': * V: ^8 C+ u4 x/ U; p
result = x * y;( d. S# U2 O- e9 r* W$ [
break;
3 s& A) ]$ X' J# B6 `4 h( s case '/': ! r: u8 x4 o5 T1 _# ^# [2 v
if (y == 0)' z V/ r! M- i: w- J5 U
{ P! L4 C9 X C2 ~: D( K
printf("Divided by zero!\n");- \; M# p8 W' K! A* H) u
return 0;
* y3 x2 N5 r# c* L6 A }7 y% L/ K+ \/ s: T0 u0 H. D% U
else
6 e1 j8 P# ^3 G! C! K' z' } {+ v0 l+ j* v; V2 t
result = x / y;
3 v+ @- z3 F; \ break;
+ L: V: I7 k, A p6 S }
( H- c% |% I4 ~7 F1 `6 X default: + F: `. @( k( h8 m+ A+ S
printf("Bad Input.\n"); ! M6 d# D! J5 k6 ]
return 0;
8 [+ p8 A: i. d- E' M. J } }3 \3 r) g0 P; K
return result;
6 R) e Y2 ^6 y5 s& |} 6 u7 `% b. @6 s' k2 g5 t! E0 f# @" _
2 U3 M. e* f$ x2 s( U3 x
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/+ m; f! k6 a. T8 Y0 ]
{
0 |" Y+ b% B" k6 c6 C Stack optr,opnd;% \; ~) t% u! v" ^/ n1 C2 p
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
5 Z7 T# E% O' V% `" M6 W! t( i char c;
- k, J4 x5 G' z% s/ {, r char buf[16];
4 z, {8 i: q! ~+ _' f$ y: L/ f int i=0;9 _2 \! B1 [/ D' A# w) ?0 [
) b9 u# T" O4 [9 a; z6 @, U7 m
InitStack(optr); /*用于寄存运算符*/
( D2 ?: u/ _. `1 c+ x. r" A2 n2 L' ? F InitStack(opnd); /*用于寄存操作数和计算结果*/
f+ v6 v8 f K. {) C1 _ memset(buf,0,sizeof(buf));
2 p2 ], g1 {& O7 H. [
5 w( |8 s5 u$ ~2 U$ R2 X6 H6 p; B& u+ n printf("Enter your expression:");# w: l; ~ t2 W5 Q
/ ^+ _" X" j+ w g/ u opr_in.ch='#';
+ m" y, F3 F8 h0 x# \ Push(optr,opr_in); /*'#'入栈*/
9 I6 s: F. `! Q1 I/ ?& I6 G GetTop(optr,opr_top);) F! q4 \& W- C0 k# j
c=getchar();
! t6 k/ B' n3 f( g+ w while(c!='='||opr_top.ch!='#')$ U3 y# ^- G* L Z
{
( G% T) S9 v, k) n Z if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/. {, u* l# i7 V6 z
{0 m \! H/ d( j; @. ^! b7 }0 K
buf=c;/ q o6 s3 z& e# I
i++;8 F* w/ i% w$ I. d
c=getchar();
$ K( }0 L, h5 _& R& x9 G5 ~" c }
& q( Y$ ^9 B' B, T/ w else /*是运算符*/$ o. S& }1 u- F2 R8 z
{1 y$ ?4 l- I q4 F/ I4 y0 n. T
buf='\0';
/ W; [4 g/ d! _5 n9 e if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/' Q( H5 j& D) r2 G* T+ N% ^
{
1 C% G- u: g4 S- t$ n opn_in.data=(float)atof(buf);: O; h$ e% N' ^' c( j0 E$ \
Push(opnd,opn_in);
, j, u3 P) c& c* ]4 l2 q printf("opnd入栈:[%f]\n",opn_in.data);
' C6 \9 ]+ S- q* L$ A4 H& Q3 g i=0;
/ O# _- u7 g" p: G2 U% N memset(buf,0,sizeof(buf));
' c# I6 ?4 M" ] }
% t' |- q, O0 S& z/ R opr_in.ch=c;( c7 |3 a. {4 P) L5 A% I
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
. ~# [ s: B- ]- v: h0 B5 S {
9 B3 r5 g" i! q1 g- `9 b3 z case '<': /*优先级小于栈顶结点,则运算符入栈*/! \& l7 t0 b0 r9 G! I# \6 c
Push(optr,opr_in);
6 l0 a' B, T$ u% X& w0 W+ d printf("optr入栈:[%c]\n",opr_in.ch);
/ w/ Y% f m" u5 B4 q: A. h c=getchar();
8 c3 p1 V# P4 `( s0 B/ A2 K break;
( K& K9 i' ]; b# f4 |+ V* T case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
0 v4 A' Y* y: U; s+ P Pop(optr,e);7 T Y4 G# [) a; P8 k) L7 p
printf("optr出栈:去掉括号\n");9 n5 c9 [% S6 c0 A O9 j# i; \
c=getchar();
- i& B8 d) N2 p h P* s% ]* L3 s break;
" O9 W2 p, {% |0 s" t R! @) \ case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
3 n6 a# X( q5 g. r* Z/ O, W* D Pop(optr,opr_t);
) V, F4 g9 z5 C; i0 A# ~# s printf("optr出栈:[%c]\n",opr_t.ch);& p. e: d% _' d
if(Pop(opnd,b)<0)
& o) Z7 V& O2 [: h8 [6 Y {1 P5 {# V( c! @
printf("Bad Input!\n");# z" q$ v6 K8 r3 @0 l
fflush(stdin);
' p6 u( X- b. [8 g" p7 S return -1;
' v. F+ ?. Y( }+ y- r5 O6 x7 r }
1 B0 _) Y; R, J O printf("opnd出栈:[%f]\n",b.data);; n/ j1 o1 k+ Q& E7 l C' u
if(Pop(opnd,a)<0)8 H; a* I! ?7 z1 l8 Q1 ^
{1 f; |# M" \( P2 q G1 ]) c% C& p4 f
printf("Bad Input!\n");3 c) i9 v* z: f8 W$ C; |$ P: A
fflush(stdin);
1 f/ c2 v/ Y2 q. S3 \3 o- v+ v return -1;: s9 r5 ~( W) c( l( x
}+ o# r$ B5 \. K3 {8 m$ f
printf("opnd出栈:[%f]\n",a.data);
; Y. g. U g" V opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
8 k+ [3 o$ U. i/ p7 j. Z Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/7 X2 ?" s% T) f7 E; x$ o
printf("结果入栈:[%f]\n",opn_tmp.data);
' C# X/ g2 m B break;: Z8 H, f/ O5 r' H
}
2 N1 N, P+ z( g% i' V }0 S0 E: d; H9 V6 x9 s C
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ # {; q2 Z* x% n. o
}
0 S3 h7 t) r: B' G$ k GetTop(opnd,opn_tmp);9 n( A0 N4 }3 R' K! Z% y/ R
DestroyStack(optr);
Z) ~" |# \9 y DestroyStack(opnd);
8 O! j% u% w2 d$ l- ~ return opn_tmp.data;
1 n1 u v7 H! m/ E0 ]5 E- y}
+ E1 O- Y: Q$ Q
, l/ j b6 Z3 [7 \1 n+ {- Lchar *killzero(char *res,float result)( }# S+ z4 P; J; ^* p6 S/ G1 a/ R
{0 h) f- P8 u. v) e( W% E- H
int i;
" B; O$ ]8 F' Q4 D% V+ A2 l- z) v$ ]
2 B, n# E: ~; P6 D" Y sprintf(res,"%f",result);
; Y5 @7 @7 p) w2 D# m" e i=(int)strlen(res)-1;
6 f I3 {6 y3 ~* E: b. u1 ] while(i&&res=='0')4 L* I. V. A* R. k
{& u3 ~$ T, k$ U1 q7 v
res='\0';
1 U6 o8 S% l4 L% ^ i--;
+ v$ u# i1 g3 ]: O: d }% l/ U M+ Z4 P3 d
if(res=='.')
; P- d) ^7 e( ?" ]; w7 v7 ^ res='\0';
8 `$ c+ O2 H% e0 B return res;' I, G8 f0 C; U4 i- W( C& T' P
}
6 }9 L* j& i; D/ s/ U4 j
* z( U8 f) I7 L9 `" K: mint main()
( m' H, ]4 w' g0 U3 }{& L" ^. Q i. @! `9 c
char ch;7 \, @7 \6 n5 c. l
char res[64];
* E, \( J0 ]9 F- g( U. b float result;& J2 W6 o/ K# Z; D; K) D6 X8 h
while(1)+ c! h6 e! D7 o# m% M* C
{
: z) ^! P. c) q6 H& n0 N result=compute();
* }+ G! m& `/ C- m- |4 q3 q printf("\nThe result is:%s\n",killzero(res,result));4 ^8 k; Q( Q1 L6 z% I" _: S: F
printf("Do you want to continue(y/n)?:") ;8 b" u. I( k) t" U- j
ch=getch();" F& ~+ `5 D W; r& D
putchar(ch);3 S2 F) Z7 `' d+ |
if(ch=='n'||ch=='N')0 w9 p7 u$ b% i
break;( q1 c9 @% `& k3 c
else" |: N$ P1 s7 F g: z- l
system("cls");
1 w' O7 e8 R7 J; l5 P }
3 C. F4 k& s5 L" `0 D3 i+ k return 0;
7 ~5 i4 b8 g* j" v# R3 H* c}
8 \! E7 N$ k# G$ d ~4 Y% c1 ~5 A' U
[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|