文章目录
大家好,这里是笨鸟先飞上课学习了一些调试的小技巧在这里分享给大家!
种一棵树最好的时间是十年前,其次是现在
1.0什么是BUG?
历史上第一个被发现的计算机错误,是因为有一只飞蛾堵住了晶体管,这也是第一个计算机错误。
2.0调试是什么?有多重要?
所有发生的事情都一定有迹可循,如果问心无愧,就不需要掩盖也就没有迹象了,如果问心有愧, 就必然需要掩盖,那就一定会有迹象,迹象越多就越容易顺藤而上,这就是推理的途径。
顺着这条途径顺流而下就是犯罪,逆流而上,就是真相。
一名出色的程序员是一名出色的侦探。
每一次调试都是尝试破案的过程。
我们初学者是怎么写代码的?
又是如何排查问题的呢?
这是初学者常犯的错误,我们要拒绝迷信式调试。找出问题所在
2.1调试是什么?
调试(英语:Debugging / Debug),又称除错,是发现和减少计算机程序或电子仪器设备中程序
错误的一个过程。
2.2调试的基本步骤
- 发现程序错误的存在
- 以隔离,消除等方式去错误进行定位
- 确定错误产生的原因
- 提出纠正错误的方法
- 对程序错误予以改正,重新测试
2.3Debug和Release的介绍。
Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。
Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优 的,以便用户很好地使用。
我们可以看到在发布版本(Release)的大小是比调试版本(Debug)要小的,因为它已经被优化过了。
我们在调试时一定选择Debug环境,才能进行正常的调试。
3.0调试中快捷键的使用
F5
启动调试,经常用来跳到下一个断点处。
F9
用来创建断点和取消断点
断点的重要作用,可以在程序的任意位置设置断点
这样就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。
F10
逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句。
F11
逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部(这是最常用的)。
CTRL+F5
开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。
[(146条消息) VS中常用的快捷键_MrLisky的博客-CSDN博客_vs快捷键](https://blog.csdn.net/mrlisky/article/details/72622009)
3.1断点的使用
在将断点打到13行时,按住F5会直接来到断点处,我们可以看到之前的程序已经全部运行,输出也打印在了屏幕上。断点为我们在调试过程中省去了许多麻烦,在我们知道前面都没有问题,而我们有问题时可以剩去前面调试的部分。
3.2调试时查看当前程序信息
3.2.1查看临时变量的值
在调试开始过后,用于观察变量的值。
3.2.2查看内存信息
在调试开始之后,用于观察内存信息。
3.2.3查看调用堆栈
通过调用堆栈,可以清晰的反应函数的调用关系以及当前调用所处的位置。
3.2.4查看汇编信息
在调试过后,有两种方法转到反汇编。
第一种,调试过后鼠标右键点到反汇编
第二种
4.0调试一定要多多动手才能进步
一定要熟练掌握调试技巧。
初学者可能80%的时间在写代码,20%的时间在调试。但是一个程序员可能20%的时间在写
程序,但是80%的时间在调试。
- 多多使用快捷键,提升效率。
5.0调试实例
5.1实例一
实现代码求1!+2!+3!+4!…+n!
int main()
{
int i = 0;
int sum = 0;//保存最终结果
int n = 0;
int ret = 1;//保存n的阶乘
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
for (j = 1; j <= i; j++)
{
ret *= j;
}
sum += ret;
}
printf("%d\n", sum);
return 0;
我们这串代码在输入3时,我们期待3的阶乘之和为9,但是实际输出却是15.这就说明我们的代码出现了问题,我们这个时候就需要调试来解决问题。
通过我们分析我们代码逻辑当i=1时,我们求1!,当我们i=3的时候应该求的是3!ret的值应该是6,通过调试我们发现此时ret的值变为了12,我们通过倒推,这个12是6乘以2得来的,那这个2是那来的呢?原来是上个循环当i=2时,ret的值就变为了2。而我们想到这里就知道了改进的方法,每次循环之前将ret的值变为1,不然会一直累积乘。
通过调试我们可以发现问题,并且去解决它。
5.2实例二
int main()
{
int i = 0;
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (i = 0; i <= 12; i++)
{
arr[i] = 0;
printf("hehe\n");
}
return 0;
}
此题这是来自一本书《C陷阱与缺陷》,同时在nice公司的笔试题中也考过类似题目,非常的有意思拿出来与大家看看。
我们观察这个程序,第一眼看到的可能是数组越界访问了,明明是下标只有9,却访问到了12。按照我们正常来思考,它可能要输出13个hehe在屏幕上,因为这个程序循环13次嘛。
但其实这个道题的答案是死循环的输出hehe,
这是为什么呢?
注意:这里i和数组arr的距离并不是固定两个字节,这取决于我们使用的编译器,万不可死记硬背当作万能公式。
这其实是一个很偶然的现象,但它确实存在。让我们的前辈摔过跟头,我们需要注意一点。
6.0优秀的代码
- 代码运行正常
- bug很少
- 效率高
- 可读性高
- 可维护性高
- 注释清晰
- 文档齐全
6.1常见的coding技巧
\1. 使用assert
- 尽量使用const
- 养成良好的编码风格
- 添加必要的注释
- 避免编码的陷阱。
6.2模拟实现strcpy
6.3const修饰指针变量
7.0编译常见错误
7.1编译型错误
直接看错误提示信息(双击),解决问题。或者凭借经验就可以搞定。相对来说简单。
7.2链接型错误
看错误提示信息,主要在代码中找到错误信息中的标识符,然后定位问题所在。一般是标识符名不 存在或者拼写错误。
7.3运行时错误
借助调试,逐步定位问题,最难搞。
温馨提示
做一个有心人,积累排查经验。