|
今天给大家带来一个比较典型的问题,一个小括号引发的bug,问题虽小但值得注意。
! \" V+ x+ \3 h! _1 F9 G* ` 首先来看如下代码
7 [" e0 V+ z2 _" L- if (x == 0)4 q2 U# Q# l' L
- if (y == 0)
! e4 _6 A# h0 Z- `. ? - error();' C1 U: K* j) M8 W! B2 K
- else{' W4 \" k8 j1 m, v/ Z+ U
- z = x + y; X) W( H/ O# k$ R" {
- }
复制代码
# l. D) H3 f7 d& f( f D在上面这段代码中,作者的本意是处理两种情况x等于0以及x不等于0,对于x等于0的情况,如果y也等于0,就调用error()函数。如果x不等于0,首先求出x和y的和,然后赋值给z。 然而,上面这段代码实际上所做的却和编程者的意图相去甚远。 原因在于C语言中有这样的规则:else始终优先匹配同一对括号中最近未匹配的if。如果我们按照程序实际执行的逻辑来调整代码的缩进,那么代码实现的功能大致如下: - ! W$ S- S2 z. ~1 W
- if (x == 0) {7 R$ y! {5 q* W$ J! ^
- if (y == 0)
/ z0 t& m! }- q8 M5 m9 h - error();
/ y( }% A6 H5 F, S1 ~# o - else {
1 w6 ^ a. H7 ]# p: K - z = x + y;
& ]. o' c( g" g r) D - }
% a2 \+ P0 u3 m" L3 n% b8 j$ j - }
复制代码
" h% ?$ P( z! M观察上面的代码可以发现,如果x不等于0,程序不会进行任何处理。如果程序等于0,会进一步根据y的值是否为0进行处理。5 W/ U2 Z! w, k
如果我们想得到原来的例子中由代码缩进体现的编程者的本意,我们应该这样写这个函数。 - / b, g( L$ C# Q1 I4 h. L* U( y6 p2 p1 a
- if (x == 0) {
) B: S" ?2 ^" p# T6 S; H - if (y == 0) 9 N- V/ e; ]8 W( W
- error();* j' I2 x i5 o( h. K
- } else {9 _( G% P; D3 J: R B
- z = x + y;! N# N, i" e8 W, F3 Q8 L' q! k3 T
- }
复制代码
( M5 O7 Y1 j4 N, ^6 J现在else与第一个if正确匹配,即使它距离第二个if更近也是如此,因为此时第二个if已经被括号封装起来了。 一个小小的括号就会完全改变程序的执行流程,从这个例子中我们可以看出,不要随意省略括号是良好的编程习惯,请大家以后注意,感谢耐心阅读! 4 A; q6 ^4 B1 I/ ^8 G
|