章节目录

程序调试过程

本节阅读量:

假设你编写了一个不能正常工作的程序。代码编译通过了,但运行时得不到正确的结果。你该如何找到有语义错误的地方呢?如果你一直遵循最佳实践,编写一点代码就测试一下,那么你可能大致清楚错误在哪里;但也可能完全不知道。

所有的错误都源于一个简单的前提:你认为正确的东西,实际上存在问题。找出错误究竟在哪里确实是具有挑战性的。本节课将概述调试程序的一般过程。

由于我们还没有涵盖太多C++主题,本节中的示例程序会非常基础。这可能会让这里展示的一些技术显得有些大材小用。然而,这些技术是为更大、更复杂的程序设计的,在那些场景中会更加有用(那也是最需要它们的地方)。


调试的一般方法

一旦发现问题,调试通常包括五个步骤:

  1. 定位问题的根因,通常需要精确到有问题的代码行
  2. 理解问题为什么会出现
  3. 确定修复方案
  4. 修复导致问题的代码
  5. 测试程序,确保问题已经修复,且没有引入新问题

我们用上一课的简单程序作为示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include <iostream>

int add(int x, int y) // 函数期望是执行加法
{
    return x - y; // 但实际却执行了减法
}

int main()
{
    std::cout << "5 + 3 = " << add(5, 3) << '\n'; // 结果应该是8,但实际却是2

    return 0;
}

这段代码有一点很好:错误非常明显,因为错误的答案通过第10行打印到屏幕上。这为调试提供了一个起点。

根因:在第10行,传递的参数(5和3)是以字面量形式写的,因此那里没有错误。由于函数add的输入正确但输出错误,很明显是函数add产生了错误的值。函数add中唯一的语句是return语句,它就是罪魁祸首。至此,我们找到了问题所在。代码在做减法而不是加法,通过检查就能快速发现这一点。

理解问题:在这种情况下,为什么会生成错误的值?很明显,因为使用了错误的操作符。

确定修复方案:将操作符-更改为操作符+,并确保程序重新编译。

重新测试:实现更改后,重新运行程序,得到了正确的值8。对于这个简单的程序,这就是所需的全部测试了。

这个例子虽然很小,但说明了诊断任何程序时需要经历的基本过程。


3.0 语法和语义错误

上一节

3.2 调试策略

下一节


本节目录