目录
一定要熟练掌握调试技巧。
初学者可能80%的时间在写代码,20%的时间在调试。但是一个程序员可能20%的时间在写
程序,但是80%的时间在调试。
1. 什么是bug?
第一次被发现的导致计算机错误的飞蛾,也是第一个计算机程序错误。
2. 调试是什么?有多重要?
所有发生的事情都一定有迹可循,如果问心无愧,就不需要掩盖也就没有迹象了,如果问心有愧,
就必然需要掩盖,那就一定会有迹象,迹象越多就越容易顺藤而上,这就是推理的途径。
顺着这条途径顺流而下就是犯罪,逆流而上,就是真相。
一名优秀的程序员是一名出色的侦探。
每一次调试都是尝试破案的过程。
2.1 调试是什么?
调试(英语:Debugging / Debug),又称除错(排错),是一个动作,是发现和减少计算机程序或电子仪器设备中程序
错误的一个过程。
2.2 调试的基本步骤
发现程序错误的存在;
以隔离、消除等方式对错误进行定位;
确定错误产生的原因;
提出纠正错误的解决办法;
对程序错误予以改正,重新测试。
2.3 Debug和Release的介绍
Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。它可以调试。
Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优
的,以便用户很好地使用。它不可以调试。
在环境中选择 debug 选项,才能使代码正常调试。
3. windows环境调试介绍
3.1 学会快捷键
F9
创建断点和取消断点。断点——程序执行到断点处就会主动停下来。
断点的重要作用——可以在程序的任意位置设置断点。
这样就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。
F5
虽然是开始调试,但是通常使用F5跳到想要的断点处(经常用来直接跳到下一个断点处)。
F5可以从一个断点处直接一步跳到下一个断点处(前提是有两个断点后,把上一个断点区先后按F5就可以直接跳到下一个断点即使上一个断点后有循环操作也会直接一步跳过)。
F5的功能:F5会向后执行代码,到下一个逻辑上的断点。(遇到下一个断点是物理断点)
F9和F5是配合使用的。
如果程序中一个断点都没有,直接使用F5,运行程序就会没有结果就直接结束,因为F5在执行的过程中在没有遇到任何断点的时候就会直接一下把代码执行完,除非中途遇到断点才会停到断点处。
F10
逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句。
F11
逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部(这是最
长用的)。
CTRL + F5
开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。
SHIFT+F11
跳出函数,函数已经执行完毕。
更多快捷键出处:http://t.csdn.cn/l0YU0
多多使用快捷键,提升效率。
若想观察程序在走的过程中到底哪里发生了什么样的变化?怎么观察程序上下文环境的相关信息呢?则接下来讲:
3.2 调试的时候查看程序当前信息
这些窗口必须在调试起来之后才出现。
3.3.1 查看临时变量的值
在调试开始之后,用于观察变量的值。(窗口中变量没有调试到被创建之前看到的是随机值)
先看自动窗口,发现自动窗口中显示的是完全自动的,是VS编译器自动获取程序上下文环境中的某些变量的展示,一些相关的值一会可以看见一会自动消失了,不便于观察,所以很少使用自定窗口。
局部变量窗口:
局部变量可以把程序执行过程中上下文环境中的局部变量都列举出来——可以做相关的监视工作。
监视窗口:(使用最多)可以打开多个监视窗口。(窗口里面的所有数据都是自己敲出来的,若是几个窗口,这 几个窗口的数据是一样的)。
3.3.2 查看内存信息
在调试开始之后,用于观察内存信息。
当调试的过程中,不仅可以在监视窗口中看到值的变化,同时可以在内存窗口中看到数据在内存中发生的相应变化。
3.3.3 查看调用堆栈
通过调用堆栈,可以清晰的反应函数的调用关系以及当前调用所处的位置。
可以梳理函数调用逻辑。
可以很好的观察谁调用谁,这个过程相当于在栈顶放进一个个函数,像压栈,所以叫调用堆栈。
3.3.4 查看汇编信息
可以切换到汇编代码。
在调试开始之后,有两种方式转到汇编:
(1)第一种方式:右击鼠标,选择【转到反汇编】:
(2)第二种方式:
可以切换到汇编代码,可以看到C语言对应的汇编代码。
3.3.5 查看寄存器信息
可以查看当前运行环境的寄存器的使用信息。
寄存器窗口可以观察调试过程中每个寄存器的值发生的变化,在监视窗口也可以看到,输入想要观察的寄存器名字即可(原本是十进制数字,右击鼠标可以转化到十六进制数字显示)。
4. 一些调试的实例
4.1 实例一:求 1!+2!+3! ...+ n!
实现代码:求 1!+2!+3! ...+ n! ;不考虑溢出。
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
int i = 0;
int ret = 1;
int j = 0;
int sum = 0;
for (j = 1; j <= n; j++)
{
for (i = 1; i <= j; i++)//j是几算的是j的阶乘,i<=j产生1到j的数字
{
ret = ret * i;
}
sum += ret;
}
printf("%d\n", sum);
return 0;
}
输入:3;输出:15
因为j是1和2时都没出现问题,所以只调试j是3时,可以按F9断点和F5配合使用调试这部分——做法是:按F9,断点处右击选条件,即变成条件断点,然后按F5,输入3: