你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

C语言一个小括号引发的bug

[复制链接]
gaosmile 发布时间:2020-6-4 16:38
今天给大家带来一个比较典型的问题,一个小括号引发的bug,问题虽小但值得注意。
' N0 v9 J2 |5 a  R+ _: _: y  I* P
首先来看如下代码

  1. 4 _1 N/ X6 j$ u, V$ ]/ H2 @
  2. if (x == 0)
    3 g& x6 e/ ]0 x- q+ f  a
  3.   if (y == 0)9 a7 n) i3 T/ Q: @6 v7 f( b  l5 h
  4.     error();% ]0 |* ]& g( P: Z1 X
  5. else{6 Z% p8 j2 X+ r( Y: f. n, W
  6.   z = x + y;5 K/ n4 H# a  e! N/ g! @; W
  7. }
复制代码

+ 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。如果我们按照程序实际执行的逻辑来调整代码的缩进,那么代码实现的功能大致如下:
  1. , i3 I; P( g, t  L
  2. if (x == 0) {, c: f- k7 F! a5 [  o
  3.   if (y == 0) 1 E- x5 m% r, A( P% S& k6 o6 O
  4.     error();
    : L- L$ l. I8 I% Q! {/ ^' K
  5.   else {
    # Q* w; o& Q. D) S
  6.     z = x + y;
    4 c$ P, P1 r6 ]! L
  7.   }
    4 G/ A9 b/ k9 _$ e& \1 @
  8. }
复制代码
& o) \& J, R) c+ d! ~
观察上面的代码可以发现,如果x不等于0,程序不会进行任何处理。如果程序等于0,会进一步根据y的值是否为0进行处理。1 R8 K2 n  t# _4 F
如果我们想得到原来的例子中由代码缩进体现的编程者的本意,我们应该这样写这个函数。

  1. & l& o1 D* G4 z  g
  2. if (x == 0) {
    ) K/ I7 G0 N/ _+ S. ~7 k3 Z8 e
  3.   if (y == 0)
    - I3 }) R  M9 G. \
  4.     error();& x; [$ _% G4 d
  5. } else {0 V. _7 B+ Q$ i' h0 L3 j
  6.   z = x + y;
    % m4 E6 D3 ]4 ]2 B4 e- G
  7. }
复制代码
4 i' y) K3 T% ]: ^2 O$ i  e
现在else与第一个if正确匹配,即使它距离第二个if更近也是如此,因为此时第二个if已经被括号封装起来了。
一个小小的括号就会完全改变程序的执行流程,从这个例子中我们可以看出,不要随意省略括号是良好的编程习惯,请大家以后注意,感谢耐心阅读!
" v6 u0 w! x, L* o2 U2 v8 N/ q* k
赞 收藏 评论3 发布时间:2020-6-4 16:38

举报

3个回答
shanji 回答时间:2020-6-4 22:06:03
感谢版主科普,期待有关于指针易引发bug的帖子
李康1202 回答时间:2020-6-5 08:38:36
谢谢分享
chinwei730 回答时间:2020-6-5 13:29:49
感谢分享
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版