调试(英语:Debugging / Debug),又称除错,是发现和减少计算机程序或电子仪器设备中程序 错误的一个过程。
目录
一.Debug和Release的介绍:
- Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。
- Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优 的,以便用户很好地使用。
所以我们说调试就是在Debug版本的环境中,找代码中潜伏的问题的一个过程。
选择好debug或release后,当程序运行起来时,文件夹中就会多一个名为debug或release的文件
二.实用的调试技巧
注:断点是能限制循环的条件的,如果循环3次,我只想看某一次循环,前面的不看
看一个代码
#include <stdio.h>
int main()
{
int i = 0;
int arr[10] = {0};
for(i=0; i<=12; i++)
{
arr[i] = 0;
printf("hehe\n");
}
return 0;
}
我们在调试的过程中 发现
虽然数组越界了,但是arr[10]和arr[11]还是能访问的,再向下调试一步
我们惊讶的发现 当arr[12]被赋值为0时,i竟然也变成了0,再想起上一步,arr[12]刚开始时的值是12也和i一样,我们大胆的推测,i 和arr[12]是否是在同一块空间,我们看一下它们的地址
我们发现,我们没有猜错,它们的地址相同,也就是说当arr数组项后越界访问时,正好访问到了i
我们画个图来理解
问题的关键在于
导致i的空间在arr的上面
因为栈区上内存的使用习惯是:先使用高地址处的空间,再使用低地址处的空间
由于数组越界访问成功了,说明 i 和数组arr之间留有一定的空间,而这格空间正好到arr数组越界访问到arr[12]时,访问到了i ,所以将 i 的值也改变为0,从此一直循环下去,进入死循环。
注:这是在vs编译器下
这个代码在vs中的Debug版本下的运行结果是死循环
而在Release下不会死循环,这是为什么呢
因为在Release下,为了避免死循环,编译器自动将 i 放到了 低地址处,arr即使越界访问也不会访问到 i ,但是这种情况下会报错:数组越界了!
由此可见
Release往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用
三. 学会快捷键
最常使用的几个快捷键:
F5
启动调试,经常用来直接跳到下一个断点处。
F9
创建断点和取消断点
断点的重要作用,可以在程序的任意位置设置断点。
这样就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。
F10
逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句。
F11
逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部(这是最
长用的)。
CTRL + F5
开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。
四.如何写出好(易于调试)的代码
优秀的代码:
常见的coding技巧:
示范:
模拟实现库函数 strcpy