文章目录
操作代码
可以将以下代码复制,进行下面的调试操作。
#include <stdio.h>
#include <string.h>
int f1(int* arr)
{
int n = 0;
for (n = 0; n < 20; n++)
{
arr[n] = n;
}
return 0;
}
int f2()
{
char arr[300] = { 0 };
int n = 0;
int m = 0;
for (n = 0,m=0; n <300; n++)
{
arr[n] = --m;
}
printf("strlen(arr)=%d\n", strlen(arr));
return 0;
}
int main()
{
char str[] = { 'a','b','c','d' };
printf("%s\n", str);
int arr[100] = { 0 };
f1(arr);
f2();
return 0;
}
一、逐过程、逐语句
1.逐语句 快捷键F11(+Fn)
逐语句就是按照代码一句一句的执行,按一次执行一句代码。
2.逐过程 快捷键F10(+Fn)
逐过程与逐语句在执行一句一句的代码时没有区别,最大的区别在于调用函数。当使用逐语句调用函数,会进入所调用的函数,可以一句一句执行该函数体内的代码;当使用逐过程调用函数,不会进入所调用的函数,直接将所调用的函数整个执行完,跳到调用函数语句的下一句代码。
二、打断点 快捷键F9(+Fn)
打断点与F5(+Fn)一起使用,F5是进入调试的快捷键。当按F5后进入调试状态,如果没有遇到断点就会一次性执行完所有代码;如果遇到了断点就会停在打断点的语句。
1.跳过一些确定正确无需调试的代码
示例:如图,假设我们已经将 f2() 函数前的代码调试好,我们要调试 f2() 的话,就不需要再去一步步执行它之前的代码,我们就可在 f2() 前打一个断点,再进入F5调试状态,就可以在 f2() 调用语句停下,之前的代码已经一次性执行完成了。
2.在循环体内打断点,设置条件
示例:我们执行 f2() 函数,结果如图。
根据代码知道,在arr字符数组中我们明明存放了300个元素,为什么只有255个元素呢?我们知道strlen函数计算字符串长度时计算的是字符串'/0'前的字符长度。根据分析,我们可以让循环在执行了255后停下来,然后单步执行,我们就可以看到第256次循环执行是否是将0放入了arr[255]。设置如图:
我们通过以上的调试可以发现arr[255]确实放入了0。
代码结果解析如图:
三、内存、监视
1.查看内存
示例:如图
我们看到str打印出来的并不是我们想要的结果,为什么在d字符的后面没有结束,而是出现乱码。我们知道字符串的打印是以'/0'结束,难道d字符后面不是'/0'吗?我们可以进行内存查看,如图:
我们通过查看内存发现,在d字符地址后的内存中有很长一段放的值没有出现'/0',含有随机值,所以并没有在d字符后停止打印,并且出现了乱码。
2.监视
我们可以通过监视看到我们想看的变量的值。操作如图:
总结
学会调试是一件很重要的事!我们在平时写代码的过程中长期实践就能灵活运用啦!
个人认为,调试的方法技巧有许多,不局限于固定的模式,总之就是想尽办法让bug原形毕露。