我就算跳出去死外边也不会学【实用调试技巧/程序员内功修炼】

简介: 我就算跳出去死外边也不会学【实用调试技巧/程序员内功修炼】

前言

       调试即排错,对程序调试,是每一位程序员的必备技能。但大神们总是能在短短几分钟内找到我们要找很久的bug。调试需要积累经验,不像语法规定那样,bug不是千篇一律,它随时有可能出现在任何地方。

       但并不是没有规律可循,我们可以通过定位,缩小范围来找到问题,下面就让我们开始内功修炼之路吧!

       以下皆以VS2019为例。

1. bug是什么?

       

这是计算机史上发现的第一个bug,它的原意为臭虫。现在是计算机程序漏洞的别称。

2. 调试是什么?有多重要?

我们是如何写代码的?

又是如何排查出现的问题的呢?

如果csdn有弹幕功能的话,大概我的屏幕会被"真实"塞满。

我们在开始找错时,总是会不知道问题在哪,一段时间后,修修改改后好像知道问题在哪一部分,但难以再细致地找错。这就是我们掌握的调试技巧不够,经验不足造成的。

2.1 调试是什么?

调试(英语:Debugging / Debug),又称除错,是发现和减少计算机程序或电子仪器设备中程序错误的一个过程。

发现和减少错误不等于消除错误,程序是人写的,难免会有bug。

2.2 调试的基本步骤

一般调试流程如下,下面会有详细的介绍

·发现程序错误的存在

·以隔离、消除等方式对错误进行定位

·确定错误产生的原因

·提出纠正错误的解决办法

·对程序错误予以改正,重新测试

2.3 Debug和Release的介绍

Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。

Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。

    下面时同一段代码被编译生产的.exe文件的大小

▶️Debug

▶️Release

3. Windows环境调试介绍

(linux开发环境调试工具是gdb,后期会介绍。)

3.1 调试环境的准备

只有在Dubug环境下,代码才能被调试

3.2 快捷键

经常使用的快捷键

F9

创建断点和取消断点

断点的重要作用:可以在程序的任意位置设置断点。

这样就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。

这里的停止执行不是关闭窗口,而是程序执行到断点为止。

或在想要设置断点的行中右击鼠标添加/删除断点。

也可以在最左边单击左键。

▶️断点也能设置停止执行的条件

将鼠标悬停在红点上,点击齿轮按钮,可设置条件。

F5

启动调试,经常用来直接跳到下一个断点处。常与F9配合使用

CTRL + F5

开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。

F10

逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句。

遇到函数不进入函数,直接执行完函数的内容,看不到函数内部的细节。

F11

逐语句,就是每次都执行一条语句,这个快捷键可以让我们看到函数内部的语句执行情况(这是最常用的)。

▶️假设按下了F11,调试----窗口里面有不少非常重要的功能,它能让我们看到程序在内存中的执行情况。

▶️ 假设我要看a的值是怎么变化的以及a的地址,打开监视和内存窗口:

 内存窗口中要输入&a,回车后,才能找到a的地址

▶️在各自的窗口中右击鼠标的菜单中也有选项:

▶️按下按钮也可停止调试,窗口都会被关闭:

3.3 调试的时候查看程序当前信息

3.3.1 查看临时变量的值/内存信息

▶️在监视/内存窗口添加好变量后,继续按F11/F10让语句按顺序执行;或者用鼠标按在指定行前的绿色箭头,执行到某一行,注意观察临时变量的值/内存信息是否符合预设。

3.3.2 查看调用堆栈

通过调用堆栈,可以清晰的反应函数的调用关系以及当前调用函数所处的位置。

查看/梳理:代码/模块的调用逻辑。

3.3.3 查看汇编信息

有两种方式

▶️右击鼠标

▶️调试---窗口

反汇编/调用堆栈以后会详细介绍,通过汇编语言,我们可以更深入地了解语句在内存中的执行方式、顺序。

3.3.5 查看寄存器信息

▶️窗口---寄存器

寄存器和汇编语言有十分紧密的关系,它也是计算机非常重要的部件,以后会详细讲解。

4. 调试的实例

4.1 实例1

//实现代码:求 1!+2!+3! ...+ n! ;不考虑溢出。

先用n=3测试

#include<stdio.h>int main(){int n = 0;//scanf("%d", &n);//求n的阶乘//1~n的数字int i = 0;int ret = 1;int sum = 0;for (n = 1; n <= 3; n++) {for (i = 1; i <= n; i++){ret *= i;}sum += ret;}printf("%d
", sum);return 0;}

ps:这是一个非常简单的例子,所以假装我们不知道错误

▶️运行

结果本应该是9,为什么是15呢?

▶️开始调试---监视

通过监视sum和ret的值,我们发现,当进行到第三次时,本该是6的ret变成了12,这时便将问题定位到ret ,通过对代码的分析,不难发现其实这是ret未初始化造成的问题。

4.2 实例2

这是nice公司(对,就是那个拍照的)的一道面试题,值得我们了解

#include <stdio.h>int main(){int i = 0;int arr[10] = {0};for(i=0; i<=12; i++){arr[i] = 0;printf("hehe
");}return 0;}

阅读一遍代码,不难发现循环中数组越界了,那么它的结果如何呢?打印12次hehe?

结果是死循环,为什么会这样呢?

必备知识

栈区的使用习惯:先使用高地址处的空间,再使用低地址的空间

数组下标越大,地址越高

▶️看看监视窗口

这里的i和arr[12]居然是同一块空间

▶️上面说到,栈区内存是先使用高地址的空间的,图来

因为i定义在arr前,所以i比arr更先使用高地址的空间

在vs编译器中,一般隔两个地址再创建新的临时变量

地址越高,数组下标也就越大,所以数组在初始化时,是逆着开辟空间的

▶️为什么可能会导致死循环?

因为i,arr是局部变量,它在内存中的栈区产生,而栈区的使用习惯是从高到低,如果当给两个变量分配内存时,i刚好比arr高两个地址,当数组越界到arr [ 12 ] 时,刚好等于i,改变arr[12] 的值就改变了i的值

▶️是否死循环既取决于编译器/x86/x64

▶️也与release和debug版本环境有关

打印i和arr[9]的地址,会发现release版本i的地址在arr的下面,因此release版本改变了内存,所以如果将i和arr的定义顺序调换,大概率不会导致死循环

5. 常见错误

5.1 编译型错误

一般是语法错误,通过查看错误信息或根据经验可较快解决。

双击错误信息,编译器会在代码行中提示

5.2 链接型错误

看错误提示信息,主要在代码中找到错误信息中的标识符,然后定位问题所在。一般是标识符名不

存在或者拼写错误。

5.3 运行时错误

前两种错误运行不起来,运行时的错误需要调试,就像求阶乘累加一样的操作。它是最磨人,也是让人提升能力最大的。

6. 优秀的代码

代码能跑起来就够了吗【代码优化/模拟实现库函数strlen()/C语言】

结语

这里只是介绍了调试需要的工具和使用方法,实际上,相比于写代码,我们可能会花更多时间在调试程序上。这是一个优秀的coder必不可少的素质,错误千变万化,我们要不断积累经验,总结,兵来将挡,水来土掩。

目录
相关文章
|
人工智能 程序员 vr&ar
竟有程序员40了还在撸代码?
竟有程序员40了还在撸代码?
149 2
|
SQL 人工智能 Java
程序员:你见过哪些要命的奇葩代码?
程序员:你见过哪些要命的奇葩代码?
112 0
|
存储 程序员 编译器
【C/调试实用技巧】—作为程序员应如何面对并尝试解决Bug?
【C/调试实用技巧】—作为程序员应如何面对并尝试解决Bug?
147 0
|
测试技术
初级软件测试面试题怎么找?提供的这两个地方你肯定用得上
最近几年,随着电子产品和互联网的蓬勃发展,各类科技公司如雨后春笋般出现,而软件公司作为科技类公司中的重要组成部分,在这支互联网大军中也占据了重要一席。因而,负责软件问题质检的软件测试岗位也逐渐成了这几年炙手可热的就业岗位之一。
148 0
|
JSON Java 测试技术
如何写出让人抓狂的代码?
如何写出让人抓狂的代码?
如何写出让人抓狂的代码?
|
存储 安全 搜索推荐
天选程序员:如何提个好问题?
天选程序员:如何提个好问题?
273 0
天选程序员:如何提个好问题?
|
设计模式 架构师 算法
程序人生 - 程序员:伤不起的30岁
程序人生 - 程序员:伤不起的30岁
125 0
|
存储 程序员 C++
如果当初学习编程时能有人给我这些忠告该多好
Cecily Carver 是多伦多的一位程序媛,和 Jennie Faber 一起创办了一个游戏制作工作室。她喜欢歌剧、舞蹈和弹钢琴。Cecily 在这篇文章分享她在编程道路上的所感所想,给出很多值得思考的编程箴言以及一些思想误区,比如在你学习编程之前思考一下你的目标、编程不是什么神秘的东西、坚持比方法更重要等,可以让我们在编程路上少走一些弯路,从而有更多的时间学习技术让自己变的越来越强大。
226 0
|
程序员
程序员好心帮应届生改代码后,结果扎心了!
近日,一名程序员在互联网社区的吐槽:公司一个应届毕业生,领导安排和我一起做项目,提交的代码有许多不合适的地方,我在没有和他提前沟通的情况下做了部分重构,结果直接喷我,让我不要改他的代码,老哥们,遇到过这种情况吗?对此,网友是如此评论的: 直接说让他自己改,改之前你应该先说,不过应届生也敢喷你,不是后台强,就是情商低;千万别自己改,你应该给他说怎么改,然他自己改,我就是应届生,我领导就这样做的。
1056 0