首页 理论教育 科学调试方法-零基础C++从入门到精通

科学调试方法-零基础C++从入门到精通

时间:2023-08-20 理论教育 版权反馈
【摘要】:坚持采用科学的调试方法是非常有必要的。动手写15.2.4我们通过动手写15.2.4阐明了bug重现的重要性。动手写15.2.5我们通过动手写15.2.5讲解了二分查找的方法。运行结果如图15.2.8所示:图15.2.8整型下溢我们可以看到输出屏幕中不断地出现递减的巨大数字,这个数值有些接近unsigned int的最大值,于是我们怀疑可能是程序中发生了整型下溢。由于unsigned int到了0以后再减小就会下溢,我们尝试把循环条件改成i>0,并假设结果不会发生下溢。

科学调试方法-零基础C++从入门到精通

静态检查只能捕获一部分可能导致bug的代码模式,而在实际开发中我们还是必须花费大量的时间和精力依靠断点和其他的工具来调试程序。

许多初学者可能犯的一个错误就是胡乱地用蛮力调试,或者随意地修改参数,凭着侥幸心理希望异常能够立刻消失。这在某些情况下可能是有用的,但并不能解决根本问题,很可能在之后修改代码时又出现同样的问题,而且因为没有理解问题的根本所在,所以我们也没有学到任何正确的调试知识。

坚持采用科学的调试方法是非常有必要的。虽然这增加了调试时的思考负担,但实际上能节省不少的时间和精力。

bug一般都出现在程序的结果中,表现为屏幕、文件输出的数据或图像不正确,又或者是运行时发生了崩溃。发生崩溃还是比较容易解决的,因为IDE往往可以直接通过调试器定位到发生崩溃的地方,从而直接找到bug的根本原因(Root Cause)。

如果是程序的输出出现了问题,那么第一步我们要能够稳定地重现(Reproduce)bug,然后去寻找bug的根本原因。因为如果第一次添加断点调试就能够找到根本原因,而第二次却不能重现bug的话,我们也不会知道在修正了根本原因以后,bug到底是不是因为我们的修改而消失的。

动手写15.2.4

我们通过动手写15.2.4阐明了bug重现的重要性。当我们输入100的时候,运行结果如图15.2.4所示:

图15.2.4 重现bug

我们可以看到0到99累加的结果只有86,这显然不对。由于我们不知道这个bug只在一定条件下触发,在修改代码后,我们又输入了10。

图15.2.5 没有重现bug

结果如图15.2.5所示,看起来是正确的,所以我们以为这样bug就算解决了,但其实输入10的时候原本就是没有bug的。现实中比这更复杂的情况比比皆是,有的时候程序可能需要10个选项,而只要有一个选项不一样就不一定能重现bug。所以说,如果不能重现bug,就算做了修复,我们也无法得知修复是不是有效的。

在能够重现bug以后,我们就可以开始定位bug的根本原因了。定位的第一种方法是使用二分法。我们当然可以一行一行地步进,寻找出错的语句,但是这样做效率很低。使用二分法的话,我们可以只添加几个断点就定位到问题。

动手写15.2.5

我们通过动手写15.2.5讲解了二分查找的方法。这个示例的运行结果如图15.2.6所示:(www.xing528.com)

图15.2.6 二分查找bug

我们看到,实际计算结果与预想的不一样,我们利用二分查找的方法直接查看中间结果c的值。

图15.2.7 定位到中间的语句

如图15.2.7所示,c的结果是21,而我们预想中的结果是25,因此c的计算已经出问题了。接着我们看到a和b的值都是正确的,所以一定是c的计算过程出现了问题。经过仔细查看,我们发现了最后的“a”应该要写成“b”。就这样,我们利用二分查找很快地定位到问题的根本原因。

定位bug的根本原因的第二种方法是假设并验证的方法,这与科学家做科研的方法很类似。在代码中难免会有一些我们特别不自信的或者怀疑的代码,我们发现bug后,可以对这些代码进行一些假设,并修改代码,然后再次运行看看是否还存在bug。

动手写15.2.6

我们通过动手写15.2.6讲解了假设验证法。运行结果如图15.2.8所示:

图15.2.8 整型下溢

我们可以看到输出屏幕中不断地出现递减的巨大数字,这个数值有些接近unsigned int的最大值,于是我们怀疑可能是程序中发生了整型下溢。由于unsigned int到了0以后再减小就会下溢,我们尝试把循环条件改成i>0,并假设结果不会发生下溢。修改之后的运行结果如图15.2.9所示:

图15.2.9 验证假设

我们发现修改之后的结果与预想的一样,于是我们证实了程序发生了整型的向下溢出,接下来我们只要想办法避免这个问题就行了。

需要注意的是,假设验证法中的假设是在对代码有一定理解的基础上做出的,如果随便假设就又会沦为我们一开始说的随意修改参数,企图光靠侥幸解决bug的情况了。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈