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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
5 ^5 T e; f, s- o9 b# o- y程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
' X5 J7 T! y* R; f9 p/**************表达式计算器************/( t- H2 F2 G- d- ?; O0 W S2 ?# }; G0 I+ u
#include <stdio.h>
& Z1 d2 @8 {# q8 e# g#include <stdlib.h>
9 m1 W2 k% I7 F& T- h3 F#include <string.h>
9 ^7 H) Q& h; ` g. y' E#include <conio.h>
; l$ q5 B _ s8 q& \5 V }. q( y#include <malloc.h>
; t5 X# K3 X; W7 F) R
* M7 W* f2 D" d#define STACK_SIZE 100- T$ E) n7 \' e, A4 C
#define APPEND_SIZE 10
( r) \! f# R0 f2 Z' G
{: J. }) u5 pstruct SNode{
5 e3 N6 s0 z) p8 L float data; /*存放操作数或者计算结果*/
' q8 j) ^# L3 Q) l2 `5 Y char ch; /*存放运算符*/+ }- J9 c0 w7 G3 k
};
# j9 E( k/ y8 X: ]% P% J8 y2 C. J! C1 K
" `' |( I5 R5 e* G. k: Fstruct Stack{& U" x+ j3 `( q6 g) e2 A- K
SNode *top;
& q# u6 e) q8 @9 f2 B4 v SNode *base;8 ]; L/ B6 B S0 b
int size;
{# d( ~* X" w8 t};% @: L2 W# @' u$ ]
9 f4 P6 i5 B0 I/ y" x) k$ N/*栈操作函数*/
# [$ D; v$ U4 k2 y P( uint InitStack(Stack &S); /*创建栈*/3 u, ^1 s: Z# m& e; x
int DestroyStack(Stack &S); /*销毁栈*/
8 {% j* X& c$ ~int ClearStack(Stack &S); /*清空栈*/8 O6 K# Q; a5 o, m1 y2 l6 I
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/. U/ [1 S q" H
int Push(Stack &S,SNode e); /*将结点e压入栈*// ~/ d+ i. I6 n* r6 i4 D" E
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
' }$ ~) r" S2 M0 [7 w" e1 |
* Q0 C3 V: g5 E) D! q( v, F0 T) k/*表达式计算器相关函数*/
. l" z7 g& \& R8 r" J: Xchar get_precede(char s,char c); /*判断运算符s和c的优先级*/
+ N# q8 e: R; R( a: s$ Sint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*// X* f& J. e: ]! q. U( k! c/ I0 [# J: @
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/! ~; t/ j F1 j c' K
float compute(); /*表达式结算器主函数*/
& f, X2 \7 ^% X7 Zchar *killzero(float result); /*去掉结果后面的0*/ ; t+ V7 [+ p p8 v- K/ {0 ~
3 t' v: W0 H& D( B. Z+ x7 D4 r
int InitStack(Stack &S)9 l) I7 I/ J. t3 B
{
5 X6 C) j% ]9 ^: I4 ` S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));4 v' Q6 R2 w" y% I- m+ z
if(S.base==NULL)
# h9 x# ]; `7 Q. H+ F {* i/ D- }2 F( q8 s
printf("动态分配内存失败!");+ N9 Q r; s7 k0 x2 q! c
return -1;' M4 q; V; J0 f0 t2 X3 o, B; e
}
5 b. z* I# _" B5 U S.top=S.base;
' C8 \. \2 w% p S.size=STACK_SIZE;
D! @6 i: u: h! z) | return 0;
" E( `6 b# N! T! D7 x( s}
# a; Q4 X y. Z7 v/ P. s
* q" h: C1 ?. Q- h" Xint DestroyStack(Stack &S)
% n% E& F+ z1 ~; z( i{ y& q2 p: j" X$ y5 B; e
free(S.base);
) L$ ]7 y# @- C6 o% z! i return 0;. h3 {6 s$ k% f5 Q$ _6 \
}1 k; L$ j \* f+ y1 f: ^2 M7 F
) v' t- d* H' a/ E4 [int ClearStack(Stack &S)+ S0 {7 U8 ]1 X. `! L
{# J7 q7 n K" G2 U
S.top=S.base;/ e4 v) `! k* z% y9 F; N, H6 f
return 0;6 O1 I4 Q" Q$ O( R& v. \
}
9 A* _( B; `+ X5 l. L
) ^! H# M. l- e1 y0 G/ ?int GetTop(Stack S,SNode &e)
4 U+ p% m5 b0 O: @, q{
& b" @" Q2 L% P4 F8 f S if(S.top==S.base)% ]5 C( ]( W% V! j
{; D9 I$ E! k( I( N, |7 {
printf("栈以为空!");
+ n$ k5 g* _6 W0 q w return -1; e4 g+ A/ i6 X3 B( O
}, S- z+ Q. {0 |# z8 C
e=*(S.top-1);
- |2 L% }' o8 H0 s2 \) E: W! I return 0;2 {$ ~8 N& t4 E. H
}
5 m; H* b& d! ?
' J$ [3 ?4 l; F6 xint Push(Stack &S,SNode e)! v+ [9 i3 s" R- f
{
; ^* F& r+ [8 q if(S.top-S.base>=S.size)9 \2 D! r& Y6 ?& \$ j
{- B5 Q6 |' F+ Y6 {8 X' i! [
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));/ O8 I4 {1 h5 o! c: h) D
if(S.base==NULL)
! M% G' f$ D3 n% R2 j8 T+ Q+ B {1 v; X* c A+ X H, @, h3 f
printf("动态分配内存失败!");
3 y& y. v/ }; I4 a return -1;% J0 |3 P, _7 f) b U0 q! V- z
}
$ R. W& n, Z% Q% z1 v' U S.top=S.base+S.size;! L8 y# K" `% j* d5 p
S.size+=APPEND_SIZE;; b m' R6 m( X" b
}9 s( Q8 Q: }& [% c4 }2 w
*S.top=e;
8 M2 ^# R" ?* I S.top++;, E5 O3 p, ]- v; w& Q. T
return 0;
. C1 _# q. k/ a4 Y3 i; n}0 X. u* U7 W- K# i! V+ I9 l2 ]
& E, g5 g/ h O% c4 k) Hint Pop(Stack &S,SNode &e)% q* f7 \% w6 _( [9 ]& ?
{4 \% b' m% n8 P2 q3 ?
if(S.top==S.base)/ Z" ]0 z* A5 S5 J
{
1 o8 Z$ T: h& W printf("栈为空!");
- V0 W1 E: {- c+ y return -1;. `* V% x8 `/ h. Q; H# Y p1 B) [
}+ y+ z6 m/ B* G5 p: x0 _* O
e=*(S.top-1);, j7 }6 W2 B8 Z" c
S.top--;
: M: S7 P3 Q: F! O8 \% v9 z return 0;
. b' j n, Y6 }5 S( F* }& T2 ]}
5 H: [) }* v% }: ~+ t# V& b. V
9 I) Q' y9 Z) f, Pchar get_precede(char s,char c)# i6 K- ?7 ^) [
{) m7 t( a+ u; R' @8 S; l
switch(s)" O, Y6 O" L! a& p/ N; Y
{
) Y% V: w/ h7 m0 \' K case '+':
/ |+ }- g6 M1 U3 H b+ Q" w case '-':8 F5 M, H) {8 k3 V6 U6 P. R& |
if(c=='+'||c=='-')
; R/ a7 i) M( R/ ?) x return '>';
( u/ Y0 S9 l: V j9 X( Q% e else if(c=='*'||c=='/'). W: y7 c2 G! Q0 v
return '<';! G3 U' Z2 h' s. k
else if(c=='(')& h1 C2 m: v5 P: u" Q
return '<';' U; y' B$ Z* ^0 U7 ]7 o8 L
else if(c==')')
. _, \$ ?" q& C/ O8 _ return '>';
! ~( W. D# k7 K& o2 }0 s else
; x, L! t. R; U9 g, v return '>';2 o5 ]* F5 ^9 D" k U5 m* l4 }* Q- A' ]
case '*':* y6 h- u* B' A3 j: [# I2 Y' _
case '/':
" Z0 p7 j/ x6 h$ N$ a) p if(c=='+'||c=='-')
- ~% [% h; V% H; N t return '>';
% y8 p9 X7 M- ~/ J0 e6 M) d, z; }( S else if(c=='*'||c=='/')3 f4 _, i+ L$ C& x
return '>';$ Y Y/ ?% }& `$ R% n
else if(c=='(')
( s$ U: H; D! Z% G/ ^6 B7 L return '<';0 V ]% ]& n$ n! H3 a6 O
else if(c==')')' g F" o0 j, n! t H, d( G5 f8 I
return '>';7 @8 D/ W) v# H' b
else
, y" l9 x' V; m+ O& @8 n return '>';
, d7 c E: Q4 g3 V! p case '(':! h+ I$ G4 ~) G: }; ?
if(c=='+'||c=='-')" t. g0 r9 Y! [6 L% P/ \' W
return '<';
( W5 ]5 |' A8 s- @* o4 H7 _ else if(c=='*'||c=='/')' G9 a. I. L) @
return '<';
0 Y1 }2 Z) X9 K+ @ else if(c=='(') W8 b4 g) R7 M9 [
return '<';
- g4 ~+ i* }6 ~( ?( w5 L else if(c==')') z0 t5 a7 R) a( f
return '=';0 V+ W1 U, M4 J7 M# ^& I/ p
else" H3 ^6 b; F0 E, Z
return 'E';) B% `/ W( Q, X
case ')':: ^' s3 Z# x) A5 @# O% a
if(c=='+'||c=='-')4 ]9 `2 e$ o, F* |' Z' ?8 N9 P& @
return '>';. Z2 u, Q# S3 o: M" Q1 E; p; q
else if(c=='*'||c=='/')
e. A6 x! {& M) E0 w2 k return '>';) r, W# A, O/ U; T1 _( [, T; K
else if(c=='(')
+ v" _, ~/ M; ~& G return 'E';2 j; ]! U2 A& j3 @, G. c
else if(c==')')
- |: j. s; A* l/ e return '>';: P$ Y! n3 Y3 ~9 J$ Q& H# C
else
4 g6 @# R% t) V4 o return '>';* K# g# A; s. ]. v {# ]) J* A4 ^* r
case '#':' `7 x' L+ m# t% q+ x
if(c=='+'||c=='-')
+ c0 m& H5 {$ U( i% H- T) E return '<';
' V% J, w; A% o% l) {% x; }( l" Q else if(c=='*'||c=='/')
) d$ l C# _' }/ Y* v! G' W. X return '<';
9 x" B( k$ _/ H6 H7 U else if(c=='(')
- S/ |4 R# j+ W6 a0 y return '<';
$ @) ^/ w- E0 G S! v7 W else if(c==')')
' Z0 l6 l/ E+ D" P1 j return 'E';$ Z7 C& c6 d! r1 r! J
else+ Z- a/ e! }# ]+ s
return '=';
; [. Y- l6 H) M2 `! p default: b* v6 q u" A* F6 Z, J& C2 H) C- h
break;+ D6 O( ?7 S8 `% ~7 Q+ Q! F
}2 E9 g* z/ h/ M2 N9 A% j0 x
return 0; % W7 U: Q% s8 I5 A C# ~/ \
}
. ?# X# W7 k$ a; C+ }7 U
+ Z# m" Z( F4 f& j9 O/ d+ d( Zint isOpr(char c)/ {5 _; b! Y& y7 d9 o, y
{
6 a( |: I$ {! [' L if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
9 n" ~+ s6 ~. J6 f return 0;
: }: u8 V/ \1 ? else ' }8 m4 F% v" ~
return 1;4 G. D' {* [ m% P# y
}8 s# ~3 @( N) m5 c8 q' e5 w4 J
6 H2 U# k r6 J2 Dfloat operate(float x, char opr, float y)
8 s. ]0 W, p3 f! `0 E{
; h; S9 A C1 ?! r float result;3 w! N# w( u6 Y$ F
switch (opr) ]' Y* i) e" K
{
/ g/ a4 N. S9 ]7 B0 J8 K+ y- Q case '+':
) J3 U* b9 H0 D& u( K8 B8 \- \ result = x + y;
+ |' o1 A2 F! p8 M* f break;* j1 z8 S: N8 @! N/ s) G. M
case '-': ) w0 }! p: c `2 T# c* Q0 ?+ R9 _' [
result = x - y;7 s9 Z. H9 Z8 {8 } R3 y `
break;
7 F R! q5 u" T: {' \( l case '*': + K' y. Z6 ~3 p& r
result = x * y;
3 ^7 \6 F: v# N4 | break;: d0 y* T. Y g1 L) F+ t" u. D& Q' m
case '/': 0 Y' S+ N0 @) f/ `
if (y == 0)
8 X- B0 b9 }' D# M6 }$ x% k& _ {
0 v+ c* Q( M1 E8 z; B printf("Divided by zero!\n");
# o) u4 I& r- N/ s return 0;
4 g' H. K. K) |& _1 |7 `* \! P1 P" V }# @6 w/ o5 D% L2 R8 @" X
else; N; g$ C* O/ W$ _
{
1 N$ K) ]- |4 J, y5 Z# n: Y result = x / y;* N ]" d, G, _, h& Z7 ?7 Q, \7 L: d
break;
: C! K7 U3 j# z9 @6 C% j }
- E: C/ t& Q$ O/ H default:
, f- E7 w5 @3 j& [, k0 ^0 Q. { printf("Bad Input.\n");
8 u# N( i2 S$ w6 D# U' r return 0;
- g# y: Y/ ~- m. H }
, ^( Z% J+ H) m, d T& ?5 {6 w return result;3 v. ]* y% X+ @: ~( |# n
}
" r3 ?6 A+ U, ]! K) E
5 W/ K/ [2 F h2 O$ Afloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/& f% {7 e* r; x* s+ V; J
{' o8 C" l8 G1 ~# Y p
Stack optr,opnd;8 [4 w/ \/ x: v% F" e( K
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
w2 X2 g, y6 s: _8 v# Q% d char c;* s2 }! f9 o, h J
char buf[16];
- b4 S* U2 _" ], x: l( W int i=0;
8 @" N0 M& m3 v 6 `; `; c, _- r9 p
InitStack(optr); /*用于寄存运算符*/
+ s2 o$ y0 d6 t. X9 A; |7 F+ O$ ]# j7 H* X InitStack(opnd); /*用于寄存操作数和计算结果*/! k# g* M" s8 d
memset(buf,0,sizeof(buf));" k; A8 z- S# O) `4 F1 q- c- F
Z) y/ N& N2 K5 k& S4 f4 U7 H
printf("Enter your expression:");
0 g$ w7 p# u$ b' b1 ?) k
1 M* f1 a3 \3 ~! C$ ~- Z opr_in.ch='#';
/ s/ }$ u- u+ w! z- \' B Push(optr,opr_in); /*'#'入栈*/
/ @0 P+ L' V4 h2 ~6 z/ ]) @ GetTop(optr,opr_top);+ a+ C3 E! t+ s/ M: G
c=getchar();
+ U' k* h9 i) E% S, a# e2 o while(c!='='||opr_top.ch!='#')0 @4 I* W4 e8 T
{5 X$ `8 C! V8 u, B, N: V
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/7 y, Q# Z: s5 F( v6 J- P7 ?
{* ]7 b. f& L6 f. E3 D6 j, g" j
buf=c;$ \ y j: x; t; M% X& w
i++;
: g9 U7 N7 K1 @, E0 P c=getchar();
/ d6 {& ^4 Y" ^% k" x! ` }( n+ r! }. w0 ~$ o/ w% A" A
else /*是运算符*/& `* t6 q5 l- L1 B9 ~+ j
{
: i% |2 f! ~' D2 D+ I( t buf='\0';
* n+ [/ l! X* y" o if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
* P: i+ k# d( Z9 A/ o% m6 c$ N7 A& Q- d {' | y1 }" U5 V5 ], b% ]
opn_in.data=(float)atof(buf);
; u7 B9 o) N @ Push(opnd,opn_in);
% s: }( d& _0 R printf("opnd入栈:[%f]\n",opn_in.data);
, t* a) @7 w: [7 G" |4 p5 o i=0;% `9 V2 ?5 F' I( ~/ d
memset(buf,0,sizeof(buf));* {! W' Y6 K; ]4 k5 @0 T) I* D
}! g% s# u3 k6 v) `4 ?: k4 @5 ~5 w
opr_in.ch=c;
1 D+ I- [. Q% {" ^/ Y switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*// W. T" n1 M0 _2 _
{( w' I, ^4 s0 e' s
case '<': /*优先级小于栈顶结点,则运算符入栈*/; H& c$ [9 t+ D5 j7 F' z
Push(optr,opr_in);
- N% b; X: A. X! u8 X# k* R printf("optr入栈:[%c]\n",opr_in.ch);$ L/ o/ e/ [' f0 r5 n5 A9 D
c=getchar();( N& A/ b2 I* a5 q) x
break;
/ h& ~4 [" k0 p' \ case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
. v0 E1 I; X2 k, S T7 E+ P Pop(optr,e);+ r' j+ s0 i9 ?$ h2 d
printf("optr出栈:去掉括号\n");
4 M' s+ V' n5 f# q$ {8 E) s c=getchar();
: F/ n5 v4 A$ O break;2 _0 ~( L- C2 j1 ~ r# R$ }5 r) i
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
q2 Y2 f, W7 C% L$ ?' s+ G Pop(optr,opr_t);
; [$ k' F2 x1 o printf("optr出栈:[%c]\n",opr_t.ch);
* V; z& d" m+ f8 J if(Pop(opnd,b)<0)" x" ^ X) l" ?7 t
{
5 @6 D1 p7 r5 V I) F1 r printf("Bad Input!\n");* p) Z$ P3 A1 W9 P; C
fflush(stdin);
: A* z+ N% c* F0 C# ` return -1;6 u' w; I) q- x1 D% I, [+ L
}$ {6 J7 E- |# D1 @, ~) B
printf("opnd出栈:[%f]\n",b.data);
; @4 r) P& d( V4 N8 r if(Pop(opnd,a)<0)
/ m& f. G U& V {& \$ C) ?) v5 R9 D& k9 q) j
printf("Bad Input!\n");; r; G% {9 \0 n4 F9 ?1 U4 w
fflush(stdin);
7 t5 J, h, }4 D2 U return -1;2 i' r" O2 Z9 U4 P! a d
}
. d' g8 S9 l! z printf("opnd出栈:[%f]\n",a.data);
+ z; B9 O5 r2 b/ C* l, v, k- z opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/( K* M; d+ K& c/ i
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/6 M6 ]% J- t7 ~
printf("结果入栈:[%f]\n",opn_tmp.data);
d" v4 ~. K# V break;' J+ u5 j4 E; O) ~) H# W* V
}
7 X* m. m5 o+ c1 H' [ U7 o }
2 _5 m" n, K5 I9 e7 | GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
4 v+ H) }; E; Q' _! Y4 l }5 t! ^5 a7 v* n+ b7 F1 ^6 \
GetTop(opnd,opn_tmp);0 T: R0 l4 z3 l9 W8 V
DestroyStack(optr);& z1 R- Y3 D# }6 H+ k
DestroyStack(opnd);) n5 C1 ^5 @7 R1 m2 y
return opn_tmp.data;5 c0 r& t; q7 g$ e
}
9 Z! W3 L6 ?; m/ C2 r, D' f* }
l; m: D2 W( a8 D1 Pchar *killzero(char *res,float result)+ A% s+ ~: a* m y a8 U0 E/ Q
{/ {: B7 R$ O& u: Z+ n$ \/ r
int i;& v9 N* v! A: w$ e
$ C( M. D5 h' R( A; e: n! W sprintf(res,"%f",result);& b! b) R. y1 Y
i=(int)strlen(res)-1;) m) h0 b' A* J2 p
while(i&&res=='0')
- e6 S4 s, i: M* _- A$ C ^ {
{6 B2 y% I4 s res='\0';* Q: ]1 @" F7 x/ Q( m$ z* H! u
i--;( T6 G2 M' j, K0 S/ Z
}
$ j& W5 b) c3 O& {% f+ C8 X if(res=='.')
/ e2 g+ ]* } {1 g$ [' J res='\0';& H, k1 }% D n+ T+ t% X7 t/ q
return res;$ C$ i! v- b( k0 e4 }* n
}
$ }+ k0 B9 F3 e. P# J. a+ `- ~* k, e, Y- e; }9 j
int main()
( c* E: _) R- f7 j1 ^$ g{
. i; D$ @$ ~ i" p4 H1 p1 W1 j char ch;$ L, B; ~) j+ g! a
char res[64];
* y! P" m3 i. \2 u3 F float result;
, Q8 p# s, Q$ w, u while(1)
7 d7 t( p; U/ H$ ] {
r' f/ {9 r. M2 i: u7 }, E9 h result=compute();2 q1 Q( D/ j9 H' S0 a6 ~
printf("\nThe result is:%s\n",killzero(res,result));& ~$ J% B8 W4 s4 J6 L" Q) z
printf("Do you want to continue(y/n)?:") ;
, y- V2 n7 v' l ch=getch();7 ~7 F: R& j& U
putchar(ch);
3 r. n8 R3 {# V: ~2 W, }& `' e if(ch=='n'||ch=='N')
z8 ?9 B7 ~% x1 ]% q t7 F" g break;
3 R" r. V1 d4 H8 o0 M7 g else
" K; Z" K4 ~3 P5 n system("cls");; A3 E; T0 n! T; X6 \: |+ _
}
9 Q- @3 R0 T) i8 f' i0 q! J& ? return 0;
9 A& A5 e/ _4 s4 A- O+ m: ~}# m; O# k% a$ E' {
7 C. }' |% W9 j[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|