什么是BUG
调试是什么
所有发生的事情都一定有迹可循,如果问心无愧,就不需要掩盖也就没有迹象了,如果问心有愧, 就必然需要掩盖,那就一定会有迹象,迹象越多就越容易顺藤而上,这就是推理的途径 。 顺着这条途径顺流而下就是犯罪,逆流而上,就是真相。![]()
调试就是又称除错,是发现和减少计算机程序或电子仪器设备中程序 错误的一个过程。
调试的基本步骤
发现程序错误的存在以隔离、消除等方式对错误进行定位确定错误产生的原因提出纠正错误的解决办法对程序错误予以改正,重新测试Debug 和 Release 的介绍。Debug 通常称为调试版本 ,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release 称为发布版本 ,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优 的,以便用户很好地使用。调试的快捷键F5启动调试,经常用来直接跳到下一个断点处。F9创建断点和取消断点断点 的重要作用,可以在程序的任意位置设置断点。这样就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。F10逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句。F11逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑 进入函数内部( 这是最 长用的)。CTRL + F5开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。调试的时候查看当前程序的信息(前提是运行起来)1 查看临时变量的值
2查看内存信息![]()
地址中内存信息以16进制展示
3查看调用堆栈
4查看汇编信息
5查看寄存器信息![]()
调试的实例
#include<stdio.h> int main() { int i = 0; int sum = 0;//保存最终结果 int n = 0; int ret = 1;//保存n的阶乘 scanf("%d", &n); for (i = 1; i <= n; i++) { int j = 0; for (j = 1; j <= i; j++) { ret *= j; } sum += ret; } printf("%d\n", sum); //此代码为了实现1!+2!+...+n! //但是输入3 应该输出9 但是结果是15 return 0; }
我们可以去调试,去监视ret的值和sum的值
经过调试 我们发现ret的值是 1 2 12 ,所以我们发现ret的值应该在每次阶乘完置为1
调试的时候应该将结果和预期对比,调试的时候如果不符合预期则出现了错误
————————————————————————————————————————
#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; }
在i=12时,将a[12]=0,i也变成了0,因为a[12]和i是同一个地址,在vs中,因为数组定义完,会预留两个空间
因为这个代码是先定义i,所以i的空间先进了,然后定义数组,如果先定义数组,在定义i,就不会发生死循环,会发生数组越界(因为一直在死循环,所以没时间处理数组越界)
————————————————————————————————————————
编程常见的错误
1编译型错误
直接看错误提示信息(双击),解决问题。或者凭借经验就可以搞定。相对来说简单。
2链接型错误
看错误提示信息,主要在代码中找到错误信息中的标识符,然后定位问题所在。一般是 标识符名不 存在 或者 拼写错误比如我定义的是my_strlen函数,但是我调用的是mystrlen函数3运行时错误
借助调试,逐步定位问题。最难搞