错误的排查指发现并解决错误。错误的发现就是找出错误的原因和发生错误的语句。由于常将错误成为bug,所以错误的发现也被称为debug。错误的解决是在发生错误之后,通过分析错误的原因,纠正错误的语句。错误的解决要依赖于实际的程序和程序员。
1,错误信息的理解
当发生错误时,编译器会给出一些提示,根据这些提示就可以查找并定位到错误发生点。
2,错误发现的办法
有些错误从错误提示就可看清楚原因,这类错误多是编译、链接时的硬错误。对于程序中的逻辑错误、堆栈溢出、算法错误等,有时很难发现错误发生点。即使错误提示给出了错误的发生点,有时也并不是真正的位置和原因,这时就需要对程序进行调试来查找并解决问题。调试一般有以下3中方法。
1)调试器
首先是使用专业的调试工具,如gdb、dbx、valgrind等专门的调试工具。其次是使用IDE集成的调试工具。这些工具都是通过设置断点来跟踪程序。当运行到断点处时,程序终止,然后就可以“但不”、“跳过”,“进入”等多种方式跟踪程序的执行。
2)加输出语句
有些时候,使用调试器的调试过程比较慢,比较难看出直观的结果。这是可以考虑自行在程序内缴入输出语句,将有一位的变量值输出。通过与预期结果的比较,观察这些值的变化,从而定位错误发生点并找出错误。
在Visual C++中,如果选择支持MFC,还可以使用TRACE宏来输出内容。该宏是将内容输出到debug窗口中,而且只有在debug状态下才能起作用。
3)断言
用户还可以使用断言来判断某个值是否是0,有assert、ASSERT、VERIFY这3中。其中assert是标准的C++中的宏,ASSERT和VERIFY是MFC中的宏。用被测试的变量或表达式作为它们的参数,如果参数为0就会弹出错误窗口。
说明:从广义上来讲,程序错误并不表示程序一定就存在问题,只是说程序没有按程序员的预期去执行。例如,如果算法设计有误,或者程序逻辑错误,那么就程序本身来说没有任何问题,它忠实地按照代码的安排执行。但是计算的结果却不是预期的。
调试的原则
调试就是理解系统的行为并调整到需要的状态的过程。一般来讲,调试需要遵循以下3个原则。
调试的原则之一就是要理解系统的行为。这就是说,程序员要首先理解系统在干什么,而不是想当然的认为系统应该怎么样。如果不理解系统,就不能指望让系统完成预期的工作。因为任何一个改动都有可能影响到其他的方面,这样有可能解决了旧的bug,却带来了新的bug。
调试的原则之二是对程序的任何改动都要小心谨慎,避免引入新的问题。对程序的任何改动都有引入新的问题的危险性。如果解决了一个问题,又引入了一个或多个新的问题,那么就得不偿失。但是这是难以避免的,只要加入新的未经测试过的代码就有可能导致新的问题存在。基于这个原因,也建议程序员在编程时尽量采用封装技术。这样当被封装的对象测试无误后,就可以重复利用,而不必担心程序的调试会影响对象的内部。
原则之三是保持版本的跟踪,即每次改动都最好保留一份备份版本。因为,并不能保证每次的程序改动都是正确无误的。有时改动后新引入的问题比原来的问题更棘手,更难解决。如果有一份先前的版本就可以还原,或者说撤销本次的改动,这样就可以避免花费不必要的精力去解决新的问题。
——摘自《C++从入门到精通》 秦广军等编著