当我们会写简单的程序时,我们常常会遇到各种错误。例如,中英混血、少;、少}、少),函数名与申明不一致等等等等。这些错误我们都可以在output窗口根据系统提示去更改。
我们看到的就是最后的结果怎么样,那如果我想知道每一行我的代码其中变量、内存、执行位置是怎么样,我需要如何去做呢?
Debug (调试)delete bug 目的就是删除代码中错误
debug主要依赖于“打断点”和“查看内存”
断点
断点就是在行号前的红点,我们只要点击一下即可打上断点,这意味着,程序执行到此行就被挂起,断了。在此时我们就可以查看内存中的变化。
在此处打断点后我们再次运行会发现,调试台什么都没有,咩有打印hello world!
原因是打断点的第6行还未被执行,也就是说我们只在7行打断点调试台才会打印hello world!
如果第6、7行都打上断点,从定义上分析第六行处已经断了,所以相当于只在第6行打下断点。
为了逐行分析代码或函数执行情况我们需要知道以下四个按钮
continue 从断点处继续执行代码,通常继续执行多行。我们在6和10行打下断点,第一次运行会断在第六行,点击continue,会直接执行到第十行。这就是这个按钮。
step over 则是一行一行执行6、10断点,运行6行处,点击step over第七行,点击step over第八行
点击step over第九行……
step into我们第六行指向了Log函数,点击step into,我们就会跳转文件夹到Log.c,就可以看到函数具体对输入做了什么处理,会返回什么数据。这就依赖的是链接器,或者说经过头文件再经过头文件里的申明然后找到该函数。
step out,点击它将跳回到main中第6行。
具体例子
int main()
{
int a = 8;
a++;
const char* message = "Hello";
for(i=1;i<5;i++)
{
const char c = message[i];
std::cout<<c<<std::endl;
}
}
断点第三行,首先我们知道第三行并没有运行,那么此时a的值是一个随机数,点击step over,执行到第四行,此时完成对a赋值为8。
点击step over,执行到第五行,同样我们知道此时message为随机数。再次点击step over,执行到第六行完成对message赋值Hello。
在watch窗口上包含了name value type
我们在name处写下a就会得到他的具体数值和数据类型
我们将断点打在第六行,我们连续按step over当达到第九行时他又回到第六行。这就是循环语句,debug也让我们看到了代码执行的顺序。代码执行四次循环后执行结束
此时调试台会打印出
H
e
l
l
如果有100次循环我们看前五个已经足够了,我不关心剩下的循环,那么debug该如何跳出函数呢?step out 跳出函数
至此我们已经会使用debug的基础操作了。
内存视图
我们知道断点使用方法,还需要知道如何查看内存视图
DEBUG->Windows->Memory->Memory1
我们将会得到Memory1视图
还记得在变量那一张说bool内存大小是提到的,寻址方式。
最左侧就是地址,中间为16进制数字,55 就代表了一个字节(2、8、10、16进制转换)这些数据有的代表变量,有的代表函数。最右侧是ASCII码翻译后的字母。
那么我们要知道变量a发生了什么,我们首先要知道变量a的地址,“&a”
回车确认就会得到
为什么a处数据是cc cc cc cc呢?
还记得我们说过有debug和release两种模式调试代码,debug比release模式要慢,就是说debug它帮助我们改掉了许多东西方便我们调试代码。
cc cc cc cc就说明我们创建了一个变量但是还没将其赋值,对应着断点打在第三行。
点击step over,我们程序进入第四行此时已经将a赋值为8
可以看到在内存中也已经完成赋值。记得我们是int a = 8;需要四个字节内存,由此也可直观看到四个自己发生改变。
debug模式还有许多方便我们调试的小优化,如果你不想自己的代码去做这些事,或者发布的代码不去做这些可以点击release去生成代码,这就是二者区别。