|
今天给大家带来一个比较典型的问题,一个小括号引发的bug,问题虽小但值得注意。
' N0 v9 J2 |5 a R+ _: _: y I* P 首先来看如下代码
4 _1 N/ X6 j$ u, V$ ]/ H2 @- if (x == 0)
3 g& x6 e/ ]0 x- q+ f a - if (y == 0)9 a7 n) i3 T/ Q: @6 v7 f( b l5 h
- error();% ]0 |* ]& g( P: Z1 X
- else{6 Z% p8 j2 X+ r( Y: f. n, W
- z = x + y;5 K/ n4 H# a e! N/ g! @; W
- }
复制代码
+ e2 e8 d+ N. ?4 @0 C! _) f& F* l在上面这段代码中,作者的本意是处理两种情况x等于0以及x不等于0,对于x等于0的情况,如果y也等于0,就调用error()函数。如果x不等于0,首先求出x和y的和,然后赋值给z。 然而,上面这段代码实际上所做的却和编程者的意图相去甚远。 原因在于C语言中有这样的规则:else始终优先匹配同一对括号中最近未匹配的if。如果我们按照程序实际执行的逻辑来调整代码的缩进,那么代码实现的功能大致如下: - , i3 I; P( g, t L
- if (x == 0) {, c: f- k7 F! a5 [ o
- if (y == 0) 1 E- x5 m% r, A( P% S& k6 o6 O
- error();
: L- L$ l. I8 I% Q! {/ ^' K - else {
# Q* w; o& Q. D) S - z = x + y;
4 c$ P, P1 r6 ]! L - }
4 G/ A9 b/ k9 _$ e& \1 @ - }
复制代码 & o) \& J, R) c+ d! ~
观察上面的代码可以发现,如果x不等于0,程序不会进行任何处理。如果程序等于0,会进一步根据y的值是否为0进行处理。1 R8 K2 n t# _4 F
如果我们想得到原来的例子中由代码缩进体现的编程者的本意,我们应该这样写这个函数。
& l& o1 D* G4 z g- if (x == 0) {
) K/ I7 G0 N/ _+ S. ~7 k3 Z8 e - if (y == 0)
- I3 }) R M9 G. \ - error();& x; [$ _% G4 d
- } else {0 V. _7 B+ Q$ i' h0 L3 j
- z = x + y;
% m4 E6 D3 ]4 ]2 B4 e- G - }
复制代码 4 i' y) K3 T% ]: ^2 O$ i e
现在else与第一个if正确匹配,即使它距离第二个if更近也是如此,因为此时第二个if已经被括号封装起来了。 一个小小的括号就会完全改变程序的执行流程,从这个例子中我们可以看出,不要随意省略括号是良好的编程习惯,请大家以后注意,感谢耐心阅读! " v6 u0 w! x, L* o2 U2 v8 N/ q* k
|