当我们在编写程序的时候,我们会遇到种种问题,有时候运行的结果和预期不同,甚至直接编译不通过。这时我们就应该寻找代码中的bug,那bug是什么呢?
bug中文翻译过来就是臭虫,最早的bug是从第一台大型计算机中出现的,当时在计算机中进去一只飞蛾,导致计算机出现问题,科学家们进入到计算机中找到这只虫,并把这次事件公布与众,才有了今天的bug。第一次被发现的导致计算机错误的飞蛾,也是第一个计算机程序错误。
所以我们在寻找代码中的bug时不应该意味的看,而是进入到程序里面一步一步进行测试,这样既可以精准的找到错误,也可以节约时间,这就要用到调试技巧了。
调试的意义
调试(英语:Debugging / Debug),又称除错,是发现和减少计算机程序或电子仪器设备中程序 错误的一个过程。
调试的基本步骤:
发现程序错误的存在
以隔离、消除等方式对错误进行定位
确定错误产生的原因
提出纠正错误的解决办法
对程序错误予以改正,重新测试
在这里我们提及一下debug和release两个版本,在程序中一般有两个版本,一个是debug版本(调试版本)另一个时release版本(发布版本),Debug包含调试信息,并且不作任何优化,便于程序员调试程序。 Release往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优 的,以便用户很好地使用。当我们在写程序或修改程序时,我们要用debug版本来进行。
Windows环境调试介绍
当我们想对一个程序进行调试的时候,我们在环境中先选中debug版本,这样代码才能正常运行调试。
我们首先得学会使用快捷键:
最常使用的几个快捷键:
F5 启动调试,经常用来直接跳到下一个断点处。
F9 创建断点和取消断点 断点的重要作用,可以在程序的任意位置设置断点。 这样就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。
F10 逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句。 F11 逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部(这是最 长用的)。
CTRL + F5 开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。
首先就是查看临时变量,适用于调试开始阶段,用于观察变量的值。
我们也可以查看相应的内存信息:
还可以查看调用堆栈:
可以查看汇编代码 :
可以查看寄存器信息:
这些调试工具我们都要好好去使用,可以将代码的bug快速找出,熟练掌握调试技巧。
举个例子求阶乘相加的和:
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); return 0; }
我们知道1!+2!+3!=9,但是我们在这个程序中却运行的是15,那问题是出在哪呢,我们就用调试来找出其中的问题。
当我们在运行到第3次循环时,3!=6,但是在运行到求3!时答案得到12,我们就由此分析是ret在每一次算阶乘时没有清0导致成2!*3!=12,所以我们应该修改程序,使在每一次循环时使ret=1即可。
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; ret = 1; for (j = 1; j <= i; j++) { ret *= j; } sum += ret; } printf("%d\n", sum); return 0; }
现在就是正确的程序了!
编程中常见的错误
1. 编译型错误 直接看错误提示信息(双击),解决问题。或者凭借经验就可以搞定。相对来说简单。
2.链接型错误 看错误提示信息,主要在代码中找到错误信息中的标识符,然后定位问题所在。一般是标识符名不 存在或者拼写错误。
3.运行时错误 借助调试,逐步定位问题。最难搞。
所以我们一定要用好调试这个技巧,争取做到:代码运行正常 、 bug很少 、 效率高 、可读性高 、 可维护性高 、注释清晰 、文档齐全 。当一个优秀的程序员!