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

|
C语言表达式计算器
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
5 j( w& }5 ]. ~* g5 ]# `) W3 r$ u/ y% Z程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
) Z/ ]* \; ?% J$ g2 Z+ M. u! l/**************表达式计算器************/
5 }% v0 P4 [1 M#include <stdio.h>5 N# U9 p0 n' S7 q3 b/ p
#include <stdlib.h>, j: N. X* Q+ J
#include <string.h>
. H4 w: B [+ A) `1 `- v* q#include <conio.h>
8 g% R# L" b9 b1 m& D#include <malloc.h>
( q4 o- H3 f1 w$ q% I0 ~+ b, \+ |& V6 U
#define STACK_SIZE 100: _8 A# c. |, X; [3 {, c& W3 B
#define APPEND_SIZE 10
) L) q6 Y1 t2 Z3 D% m* d1 H4 z( P( x( y0 C7 a, F8 @
struct SNode{$ `$ A; ^/ Y" _/ g# `6 O
float data; /*存放操作数或者计算结果*/
9 [3 P2 c# B$ o0 S. ~ char ch; /*存放运算符*/
" ]6 F9 S, @. y/ h- D0 o};7 X* Y! h9 m$ X& u' t
# ~ x- t% \/ T( q2 l! S$ Hstruct Stack{
6 k3 P- e/ t0 z3 d, Z SNode *top;4 ~: Z5 ?( l1 r/ r: l2 N
SNode *base;
) t' o% k/ m% G5 N# ]1 Y" g: J8 I; t int size;
7 x+ Q2 x: v/ Z$ F, Z3 r. {};
/ W! h L5 }- x
0 U1 G9 P2 ]1 F% J% j5 f% V/ e/*栈操作函数*/* H- I0 c3 Q4 i! L8 o& ^
int InitStack(Stack &S); /*创建栈*/
3 E. k( J! j* ?, w' uint DestroyStack(Stack &S); /*销毁栈*/
/ E# K0 K7 K3 \0 F3 p' `; yint ClearStack(Stack &S); /*清空栈*/
: V# c& D( P G; t0 t. j/ aint GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
7 I# I7 _1 y9 Z( t8 bint Push(Stack &S,SNode e); /*将结点e压入栈*/
: z. M9 e: U4 N( i) B0 O3 ^int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/% P/ d. a" Y) g. O! Q( I! W3 b
4 e* B+ P# s5 B) ^! r! X4 _/*表达式计算器相关函数*/
& q+ o# O7 e, ichar get_precede(char s,char c); /*判断运算符s和c的优先级*/
% o! g' H0 d6 I3 A! t1 w! uint isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
; E) A- Y( r! V" f/ [/ f( Z% y) Tfloat operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/* D4 @1 P4 o" } N3 e: K
float compute(); /*表达式结算器主函数*/
5 u! o0 k3 v, @- x* W0 z1 o- W7 ~/ hchar *killzero(float result); /*去掉结果后面的0*/ 9 i8 d( a5 b, C* y
1 [, U' @/ y' G# {6 X8 c1 q
int InitStack(Stack &S)% |8 i# o0 {$ P* n, ~
{8 h" ^0 c, w$ @6 o2 J. I0 ~6 ^
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
% t$ p- u4 J3 B: i if(S.base==NULL)0 ^% d U& X: t
{
+ _' y/ b) L# u printf("动态分配内存失败!");6 \8 p& h0 W. ^ a- d
return -1;
8 o" k- p+ {0 ]- o. N O' v4 H }
& c9 R% X$ @( \* v. @$ E! R S.top=S.base;
6 I2 W0 V7 i! W' ? S.size=STACK_SIZE;
, Z6 p: b# q* B F- m0 E return 0;, W. X4 |2 q3 t; \! ?! l
}5 k7 I0 Y& s% \2 V0 j0 V
! h3 S0 J1 _0 e0 N% ^int DestroyStack(Stack &S)
* x0 g& S' w: \' Y4 D{
0 S n) X. i9 @ free(S.base);, h2 Y$ B0 z1 a. ?- A0 F
return 0;# T. m' `/ X: ]
}
' m$ M( f- c% e3 L& d7 j
% D( e) @. O( q" Lint ClearStack(Stack &S)& W$ z. r: m' m: W" E+ L( |$ Z# N
{
6 J3 n, e) L1 U1 V3 ^% l S.top=S.base;' i" N u7 b- ]2 \5 }1 Q6 o- ?$ v
return 0;
0 @. J7 f( ^! y}$ K( z, F2 J* @3 f
, n ?& V1 O9 q3 Sint GetTop(Stack S,SNode &e)( o) @6 ~- J# i& ~% [: a
{
4 m7 _8 x# ~# a if(S.top==S.base)0 w$ n$ e: \! t% `5 \
{3 z' k+ L b) D, F4 @
printf("栈以为空!");
1 c7 \& @8 a5 w% p return -1;
8 x [8 {/ z5 s! c }
6 ]$ t y m- }$ C e=*(S.top-1);' g( V8 R2 O2 N$ `* k6 q% W
return 0;" G! b8 {0 h8 Q( |' O/ \
}- b' `! s8 E# [5 D5 @
! ~7 a# v; }& ?) c* a. @$ ?int Push(Stack &S,SNode e)
3 ^4 g) P5 \* u. N% H{
+ e" t: j5 J% J. f$ ^ if(S.top-S.base>=S.size)) G; P2 \; A b: B% ~
{- C, A. L: K/ W$ J
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
+ G0 i$ W" T" D/ `0 |9 ? if(S.base==NULL)3 H( D3 |6 E1 ]
{
8 p% Y9 i, H9 K( a5 ?; U/ R4 D printf("动态分配内存失败!");3 D: Y- L! n2 D/ a
return -1;/ f* Z. }& u; w0 _
}3 W: ?: `& [7 ?; ?7 C3 W
S.top=S.base+S.size;
7 k/ @' {3 [2 m$ y% N; g+ N" n# @1 ?' i S.size+=APPEND_SIZE;
; V. G0 X7 Q2 J+ e' f. F! [2 @ }! B+ s1 n/ F2 \5 X/ D( [
*S.top=e;
8 C1 A. m% ]" r2 p, s9 f5 r: V S.top++;
$ B; j: n8 P& {$ [0 q q+ C8 \" A) P return 0;1 a7 Y8 |9 R5 r
}* _- z3 Y! y( d. d, S* I- Y6 {4 Y
5 T2 E, L7 }' e* r5 R: A" _! \
int Pop(Stack &S,SNode &e)7 V" B6 z9 n( O) e
{
2 D3 ` ^' @5 q: A( I if(S.top==S.base)
$ H0 \+ A( c6 H+ D/ J6 H {
% M. T, Q. z) X! J0 F printf("栈为空!");
2 O3 f* Q7 `6 Y v return -1;; s' x6 ^: A" ^0 u& T8 H
}. ^4 B6 q7 K) p l
e=*(S.top-1);" | q8 W3 {4 D; h0 d3 m
S.top--;% N9 O- U( K$ b1 Z! F: Q
return 0;5 _# Z. y5 }$ i: J3 R E
}
/ [' w- F; D# S+ [: N/ V4 o2 i9 Q( g) H$ E i5 M
char get_precede(char s,char c)6 x: {: W: M& n( u4 y; v) D
{
9 \# E+ C$ i# Q/ O: N# A5 v switch(s): A$ @7 ]* A8 j- Q5 t5 x
{% E3 }, N3 {, H
case '+': . `4 N9 j/ M) l) s
case '-':
) A: A: ?% u) [$ N5 ]; d if(c=='+'||c=='-')
* Y% u. R& {4 [; G A/ R6 ] return '>';6 t' e2 z/ F Y/ |
else if(c=='*'||c=='/')
" i% V, v2 @& C0 ~ return '<';
9 Q$ s, i6 g4 q8 }+ y else if(c=='(')* k5 G4 A3 e: m; s
return '<';
+ V$ }7 j0 C& B! Y- C5 u2 P else if(c==')')$ h5 x/ }! z( @* h- u
return '>';( B% O, w/ h1 r4 Y
else
/ Q3 [- o7 d* M return '>';: \0 V. ]# D; U" U- ]
case '*':
' I' P: O5 M- Z$ u$ A case '/':$ E8 @8 O9 |7 w# A. ]+ U
if(c=='+'||c=='-')" t7 g+ I$ }; u* }( @
return '>';& C5 D( h% I. C( p: p% r% }
else if(c=='*'||c=='/')) Y: G' b6 k2 _
return '>';
$ }3 q" P* s+ ?1 N( R) Z7 ~ else if(c=='(')
8 R8 D$ L/ D T. I6 J. ` return '<';
: i4 c# K" A+ U# Q5 d0 I% o else if(c==')')
% v) I( o5 M% }' O2 d return '>';) Q& E" C8 x: `
else
! [9 z) v( p; y( s" s' R return '>';
# m/ ~) f$ H3 ` case '(':6 Z# x' q" ]( ] @0 l, M& G e
if(c=='+'||c=='-')0 X; ~* h" O N6 d
return '<';/ e8 D; z$ l- F- h4 g
else if(c=='*'||c=='/') B/ ~. G. x. c- `& J) J f1 O
return '<';) Q+ G: r0 }; k6 [2 ?
else if(c=='(')
# e5 `; P; H, G4 g; [8 H return '<';
- f7 p* k( J. A0 p: T" R8 i" ? else if(c==')')4 h5 g( b; d: w; A# p) C( Z0 v
return '=';
3 z' Y# A4 w# K9 n6 |, O! ^ else
$ |- m" i$ f* m { return 'E';2 v8 H0 q0 I, f
case ')':
/ E: n: j7 T$ d B: R4 L' Q; | if(c=='+'||c=='-')
0 I' [0 _; d4 p# S1 h return '>';
4 _ V: ]7 k: J! B# z+ b e else if(c=='*'||c=='/'); A* `. C3 Y# s: ~- p
return '>';) w2 M9 |1 U. R$ n1 n
else if(c=='(')
+ x% t7 y- L& h4 e6 i4 n8 Q. ?" U return 'E';
: Q3 B5 n- L& g: w4 h' D5 P else if(c==')')6 t' H2 L# F, _' _
return '>';% A: ~2 o$ J# G+ A: D' E2 l" v% Z, i
else
) P* d% F4 W% n( ?/ k return '>';2 c6 F, E+ y& F# [# \
case '#':
# G- g( `8 | j$ C# _3 x* l) { if(c=='+'||c=='-')
" a! g, m3 r- ^; f% M1 L+ k$ S5 O return '<';7 }7 \: M* n9 P: P5 W7 Y
else if(c=='*'||c=='/')
% _/ f# ^% R0 b& e1 X* H return '<';
2 H- @" {1 ]7 w4 O0 c( Q5 m9 v1 } else if(c=='(')
+ f" q" q5 ]0 {1 f4 \% K( Q return '<';$ o0 q/ f0 s6 t& _- y6 |
else if(c==')'): z8 r# P0 ^7 J( \/ F0 s
return 'E';$ z. H5 o- Y5 q6 K
else1 e! i w$ q+ g, N6 ]+ @' W
return '=';, Q9 J9 E' i/ u+ Y, T* j
default:% k" ^9 Y; E* I J, i# ~
break;
" A0 x) L% T A$ `' e8 I4 a }8 E5 ^/ q; A2 I5 U
return 0; , X. K6 F: e9 e
}( G/ t, J5 t0 v+ I5 M4 R
# v' h/ a/ D- ~1 Kint isOpr(char c)( {0 f( e5 Q- z2 r! s
{
7 }+ i5 G8 i% n# K- p# y9 z if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
: r, v' h2 C1 M/ Y ^2 I% J8 o return 0;
. H" R/ p# X) W8 m else
# O3 n& z) b) H% t) g3 L3 n return 1;2 N1 W8 H( Z9 y l$ l
}
5 @4 G) b, X8 O. i" {& s
4 X* q, A4 [9 |/ X% q6 ]float operate(float x, char opr, float y)
1 `6 w& |7 h C! g{
" ?8 g9 ?) o( v2 }- Y. {/ ` float result;. m' c3 o8 W4 r7 f8 N* D8 Z
switch (opr)$ I2 x+ R# V: D0 }# M( @7 Z0 I
{
6 k6 e( h3 G- X; V6 N case '+':
8 H5 p7 v7 B3 c1 C* Y d result = x + y;
( `( [4 z+ k- @: D) j/ T) [ break;
; Q# w4 f" Q: B S( A" J case '-': " p. x# w, H X5 U9 ?& E: {
result = x - y;
$ ~1 p$ [, Y. D% Q- k1 b6 G( l. t1 F break;! g% J" H$ p) Q; q2 R9 k( g3 f
case '*': p) p( ~; X+ O* p3 Q
result = x * y;: ?/ O# z4 ~8 ^
break;7 Z, q8 g+ l8 L1 ?7 B
case '/':
& m- G" z* p$ p/ y if (y == 0)* B- E4 O3 Q7 I( P7 B
{: `4 x. a9 _ J4 n( s1 N! b4 ^- I
printf("Divided by zero!\n");
" ~+ M7 ~0 P4 ^' {9 U5 b& E return 0;! i. T& f8 _3 _' k* k* |4 V, m
}
; r' m9 w" a: s. }2 \ else
0 e1 F# a2 P/ G* c/ J {
2 W% d$ O& W. H& [3 S4 r" Q result = x / y;- r, D% I T" W% }
break;
T# s9 Y- `( G) \" G h* b# p1 Q% E* @ J }
1 e# _- R" L7 [# k" q/ E$ O default: ) d: L# C/ G8 d( e" v; y
printf("Bad Input.\n");
+ Q) M: R) u. F3 _5 U# z return 0;/ a; G; [4 z0 ~% b( R3 g1 }
}
" V% t6 R. s. B8 N& C- p! [& i return result;" v6 K5 p9 W0 D- }; }! l
} 0 m7 p& Z1 ?2 K+ A( Q& I
+ n' E* y/ Q) qfloat compute() /*计算的时候运算符栈顶结点的优先级始终最低*/9 |0 f9 s$ C j
{8 E1 C# G- ~, w
Stack optr,opnd;# s7 B/ B r' Q& {$ D/ ~$ g; ~
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
) U( {( o% E* p% B% q char c;& }# R+ {5 y; g8 I, Z- N% N
char buf[16];$ U! X: g5 x8 [2 D2 c
int i=0;
2 k$ A4 G3 c8 k! L( g& J
7 \( S: a- a# t- a, ]: Y InitStack(optr); /*用于寄存运算符*/) _5 r( |7 N. n7 V/ q% P5 w: D
InitStack(opnd); /*用于寄存操作数和计算结果*// Q, z! E9 p( x$ q4 Z6 S7 f7 Q
memset(buf,0,sizeof(buf));
( s B5 g/ n! [' w/ k
9 p! A% A2 E V& X8 E% h6 s printf("Enter your expression:");
3 c, |% h4 X) O# W3 Q4 ~) @
% ?: W4 T* q/ K7 x1 J- B. [/ U0 U opr_in.ch='#';
8 z D$ h+ {& z/ F8 b1 w Push(optr,opr_in); /*'#'入栈*/
5 M4 x0 r% m9 Y# X GetTop(optr,opr_top);
8 i' M! m6 J' p+ C: p c=getchar();
& ]5 i, r: }' O6 J! K- t' v: d0 j while(c!='='||opr_top.ch!='#')# y9 U! x8 L- y6 [# S8 Q8 ?) ]) F
{
: V" {8 \6 O& T. C2 s3 D: S; r if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/! W4 [/ I& `4 z2 v" B+ Y" P, {
{% W+ S# X- ]/ [
buf=c;
: A* D: E- E+ ?! W7 y i++;
# P. w7 A& d7 j' N5 l c=getchar();7 x( M: e1 o2 f) |6 U, g u9 p
}
) U* w, y8 [! M: z# { else /*是运算符*/% B) g1 y# A2 V3 y" \
{' V. v( T, D1 q2 |2 a! f
buf='\0';4 r9 S2 Q5 w# m( Y) l; k
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/0 S9 m# k+ t* H) ?. t
{ j+ c, R9 F; A# e# b: w
opn_in.data=(float)atof(buf);3 w) C: K' I3 p; x; ^8 o, |
Push(opnd,opn_in);# H; \. f1 J( u+ C6 y
printf("opnd入栈:[%f]\n",opn_in.data);
2 T; E5 l0 m2 { i=0;
& y# `! N& m, _9 z- T5 ?3 A, l memset(buf,0,sizeof(buf));) k- Q% ^: N' x( Y4 R
}
' b7 D8 J! D; V+ ?, z( u8 z0 Q* w opr_in.ch=c;
% l; n1 K) T+ Q. O, i1 C8 N& ? switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
% |( U: a9 \+ t3 n {
7 u3 q/ H2 `) ~; x case '<': /*优先级小于栈顶结点,则运算符入栈*/$ y; n2 l+ g4 [ {! E& T1 D
Push(optr,opr_in);
6 G- o( ]- [6 ^, ] printf("optr入栈:[%c]\n",opr_in.ch);- c; r! ]# F0 ^" `
c=getchar();
% |* a& Q, L7 e1 p7 \, C break;
; ^+ f7 R. P0 f0 k+ o( X' u case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/0 L( l4 E V. o0 {9 h
Pop(optr,e);
! W" m8 q& P4 N3 g printf("optr出栈:去掉括号\n");
9 B1 w$ X7 q. n8 Z9 ] c=getchar();1 U. j2 [ W6 l( i! V) a
break;& T+ L2 C6 G# I" [) {- h. D
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/ K1 y; Q8 S' G% u5 N1 Z
Pop(optr,opr_t);- C* r$ a; ~2 D0 [* h- f( h& Y# n( I
printf("optr出栈:[%c]\n",opr_t.ch);1 ~ G% B) j) n: Q
if(Pop(opnd,b)<0)
/ _& k% W1 ^8 ^, L3 n {' e2 h% L4 B0 K5 o6 }
printf("Bad Input!\n");
8 Z9 D Y0 P3 { fflush(stdin);
6 _2 M6 [/ n4 v/ p, D) I" d( S return -1; ^0 E Q+ S, r" E* }5 m
}
5 g3 T# N6 K$ J2 D& Q& | printf("opnd出栈:[%f]\n",b.data);
* h4 K8 V; a- W/ L8 G* Q if(Pop(opnd,a)<0)
: f9 w0 |9 s2 B. P* V6 H& D {, |" V8 J& b, n( g- G$ U( |5 i# A
printf("Bad Input!\n");8 {( ]- i7 r5 w9 I
fflush(stdin);0 g& e" S) M, s& q7 N C7 H
return -1;
$ S; N# i0 @! m }1 @8 C: {/ _' H5 E# R) f
printf("opnd出栈:[%f]\n",a.data);$ n- j+ O. ?1 @# M- M: ?
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*// B! L1 [! c8 d4 o1 T0 u2 n
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/: o$ z: s, C/ O; g( Q5 j2 q4 Y
printf("结果入栈:[%f]\n",opn_tmp.data);) O5 i5 A1 O* f6 Z0 {
break; c7 E) X/ x8 b
}
/ _$ ]2 i( K3 `; Q$ D, ~ }4 ?) U0 c; n0 g
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ ( X2 Y5 A) r Z* ?- G
}- p E# W6 \2 Y1 R U8 s* t
GetTop(opnd,opn_tmp);
0 @/ d: a+ P$ |0 }6 {7 Q: }1 {1 [ DestroyStack(optr);$ c8 V7 x+ _' D! j
DestroyStack(opnd);
! n3 S" N4 @/ [: @: l1 { return opn_tmp.data;$ |% k! v. F; d$ S
}
2 d" B$ l @0 M& M5 _7 D& R4 P
% @3 J1 A$ a0 ~6 z6 k! fchar *killzero(char *res,float result)0 S9 D0 U# ]( Q5 ?
{
0 |. `% s2 R1 x int i;
" y" C# |9 z8 t9 P7 h) l; n8 Z2 P( S8 `/ J# U; y R
sprintf(res,"%f",result);
7 z: x- k) c6 c i=(int)strlen(res)-1;
1 \& F; f5 L* p5 J) y* X3 m8 j while(i&&res=='0')
7 @* ^) }3 F- W V {
5 ?/ n8 A/ U* d res='\0';2 D& f* S( ^# j, Z2 l
i--;
0 u/ E# }$ N4 Y }0 h) l1 O7 T7 I l( t- v5 Q B. X+ s
if(res=='.')# P+ f; Y+ M9 d# J) G7 j. w7 y3 y
res='\0';& ~2 r" l3 R$ O: b( t: r
return res;
4 \# _: R# i* }$ `6 r}
' |" F$ {% x! {4 t; j U; L4 } j8 u! h
/ t7 k0 r0 X9 _0 L% c: nint main(). m0 U$ Y A0 R3 G$ L6 `1 ^. C4 a
{
) ^. l) r0 {/ X: G) ?, u char ch;
& o, o0 R5 |2 ^4 e8 n6 B char res[64];9 Y- d' r7 I/ L$ ]- A
float result;
, p# r1 w# V% i S3 i" j7 Z while(1)
+ f7 e: H d% ~' F {4 }) m! T2 e' u7 J9 U
result=compute();
* C! A- f$ a! D$ m' l1 y3 [4 ] printf("\nThe result is:%s\n",killzero(res,result));
3 v5 y- v5 U' G printf("Do you want to continue(y/n)?:") ;
9 U: H! H$ h# s9 B' i4 { ch=getch();
9 ^3 k0 [6 x1 s putchar(ch);
* w% k$ W: V# `" F7 u- l if(ch=='n'||ch=='N')
3 `7 j7 X3 Z! Z, a) g& U+ E break;
3 p2 r2 o, e- n; @, T. V; w6 c else& y/ N; ~& I3 L. F! M# d' I' }
system("cls");
' s/ r! Q! r! Z$ w& v% u% E6 D. y }) P) {7 V% [0 n! f
return 0;
, V) \& p L ] a}
/ X2 b) d4 s4 a9 E
7 v( H- A9 ]: \5 E K[ 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 ] |
|