在实际开发中,常常会出现这样的情况,我们可以大致把出现问题的代码锁定在一定范围内,但无法确定到底是哪条语句出现了问题,该怎么办呢?按照前面的思路,必须要在所有代码行前面设置断点,让代码一个断点一个断点地执行。
这种方案确实可行,但很麻烦,也不专业,这节我们就来介绍一种更加便捷的调试技巧——单步调试。所谓单步调试,就是让代码一步一步地执行。
下面的代码用来求一个等差数列的和,我们以该代码来演示单步调试:
#include <stdio.h>
int main(){
int start, space, length, i, thisNum;
long total = 0;
printf("请输入等差数列的首项值:");
scanf("%d", &start);
printf("请输入等差数列的公差:");
scanf("%d", &space);
printf("请输入等差数列的项数:");
scanf("%d", &length);
for(i=0; i<length; i++){
thisNum = start + space * i;
if( length-i > 1 ){
printf("%d + ", thisNum);
}else{
printf("%d", thisNum);
}
total += thisNum;
}
printf(" = %ld\n", total);
return 0;
}
在第6行设置一个断点,然后点击“逐过程调试”按钮,或者按F10键,程序就会运行到下一行并暂停:
再次点击“逐过程”按钮或按F11键,就会执行第7行代码,要求用户输入数据。用户输入结束后,黄色箭头就会指向第8行,并暂停程序。如此重复执行上面的操作,就可以让程序一条语句一条语句地执行,以观察程序的内部细节,这就称为单步调试。
刚才我们在第6行设置了断点,按下“逐过程”按钮或F10键,程序就会执行 printf(),并暂停在下一行代码处。
printf() 是一个函数,它本身由多条语句构成,如果你希望进入 printf() 函数内部,查看整个函数的执行过程,可以点击“逐语句”按钮,或者按F11键,这样程序就会进入 printf() 所在的源文件,如下图所示:
当需要跳出函数时,可以点击“跳出”按钮,或者按Shift+F11键,就会返回刚才的代码。
逐过程(F10)和逐语句(F11)都可以用来进行单步调试,但是它们有所区别:
逐语句(F10)不仅可以进入库函数的内部,还可以进入自定义函数内部。在实际的调试过程中,两者结合可以发挥更大的威力。
断点 + 查看/修改变量 + 逐过程调试 + 逐语句调试,这足以解决绝大多数逻辑问题,到此,初学者就已经学到了调试的基本技能。
在VS中,调试器还允许我们直接跳过一段代码,不去执行它们。将下面的代码复制到源文件:
#include <stdio.h>
int main(){
printf("111\n");
printf("222\n");
printf("333\n");
printf("444\n");
printf("555\n");
printf("666\n");
return 0;
}
在第3行设置断点,开始单步调试。假设我们不希望执行4~6行的代码,那么当程序执行到第4行时,可以将鼠标移动到黄色箭头处,直接向下拖动到第7行,如下图所示:
程序执行完成后,在控制台上会输出:
注意:随意修改程序运行位置是非常危险的行为,假设我们定义了一个指针,在第N行代码中让它指向了一个数组,如果我们在修改程序运行位置的时候跳过了第N行代码,并且后面也使用到了该指针,那么就极有可能导致程序崩溃。