VS调试(1)

本文介绍了编程调试中的关键概念,包括Debug和Release版本的区别,调试步骤,以及常用的调试快捷键如F5、F9、F10、F11和Ctrl+F5。调试时,通过监视、内存、反汇编和调用堆栈等查看程序状态。此外,文章强调了断点在处理多行代码和跨文件函数时的重要性,并提到了如何设置断点条件来优化调试流程。
摘要由CSDN通过智能技术生成

Tips

1, 无论是在32位系统还是在64位系统下,那些类型诸如int什么什么的它所占的内存空间的大小都是不变的。

2. 这边还是得补充一下: 一个汉字是占两个字节的

3. 0x这个前缀表示这个是个16进制数字,数组名是数组首元素的地址

4. 字符数组与字符串两者在概念上是等价的,因此如果想要打印字符数组的内容的话,不用循环去遍历,只需要用%s直接打印即可

今天我们要开一个新的章节的学习,因为在未来写代码的过程中,调试是一个非常非常重要的能力,先预防针打一个,这个技能是非常非常非常非常非常重要

先打个加强针我老是忘记:黄色箭头指的那行代码是还没有执行,将要执行!!

什么是bug,调试是什么

1.电脑或者说软件里面的缺陷叫做bug

2.调试原先的对象是硬件,但后来引申到程序里面也是一样

3. 调试的基本步骤        

Debug与Release 

1. 当有了调试的基本步骤之后,接下来就要去调试了,那调试有没有一些基本的概念需要我们去认识呢?在这之前必须得了解两个东西: Debug与Release

2. Debug是什么意思呢?它通常称为调试版本,而Release称为发布版本。

3. Debug包含调试信息,并且不做任何的优化,便于程序员调试程序;Release称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好的使用。

4. 比如说在vs里面,如果是Debug的时候,按下f10,这个代码是可以调试的,各个变量是怎么变化的,每一步都可以观察得到,包括还可以进行输入,并且不断往下走的时候,这个代码是可以调试的。因为这个代码在编译的时候,与此同时产生了各种各样的调试信息,它把程序在运行的过程的上下文环境的信息都保留下来,里面包含了调试信息,可以让程序员来调试代码 

5. 我一旦改成Release版本,Release版本能不能进行调试?会发现值也不能进行很好的观察,代码也不按照我们的逻辑再走,因此,这个Release版本是不能进行调试的。它被称为发布版本

6. 测试人员测试完软件之后,发现没有太大的问题,这时候就要把软件进行发布,上线,这个发布与Release这里的发布版本是一个意思。再发布的时候,要把它变成Release版本进行发布。为什么呢?因为这里面没必要包含调试信息,如果包含调试信息的话,用户又不会进行调试。

7. 那么Release与Debug还有什么区别呢?Debug版本的可执行程序比Release版本的可执行程序要更大一点,因为包含了调试信息。

8.反正记牢: Debug是包含调试信息的,因此在这个下面是可以进行调试;而Release不包含调试信息,在Release下不能进行调试。程序员写代码的时候,那肯定要乖乖在Debug下写,因为要调试的 

9. VS其实并不能叫做编译器,应该叫做IDE(集成开发环境),这个集成开发环境里面集成了啥?集成了编辑器,编译器,调试器。那么调试,其实就用到了这边的调试器。

所以我们说调试就是在Debug版本的环境中,找代码中潜伏的问题的一个过程。 

之前说Release版本进行了各种优化,以方便用户使用。那么这些优化从哪边可以生动的体现呢?

有一些问题

Windows环境调试介绍

调试环境的准备

1. 其实就是改成Debug(因为Release是不能调试的,无调试信息好吧),在环境中选择Debug选项,才能使代码正常调试。 

学会快捷键

VS里面有一系列的快捷键。在这边介绍一下快捷键。

F5,F9

F5与F9一般都是配套使用,F5是不会单独使用的
F5:启动调试,经常用来直接跳到下一个断点处。
F9:创建与取消断点,断点的重要作用在于可以在程序的任意位置设置断点,这样就可以使得程序在想要的位置随意停止执行,之前的过程直接一步跳过。而在断点之后,继而一步一步执行下去 

现在介绍一下断点这个概念,断点就是打断程序执行,断点会让程序就突然停在那儿,它就是一个点哈, 程序就会停在那儿。按下F9,就会在某行代码前面出现一个大红点儿,再按一下,就会取消这个红点/断点,这个红点就被称为断点,程序执行到那边,就会停下来就不动了。断点A打在这儿,F5按一下代码就会执行到这儿(不是分行分句一句一句执行,是一下子进行执行,碰到断点停下来)然后就停在这儿,就会跳到这个断点A处,就是说不会一步一步走,直接会跳到断点A处;再在下面F9创建一个断点B,再按一下F5又会直接跳到下一个断点B处。当然,除了该断点A在循环体内,如果再进行一次循环,还是能够走到这个断点A,那么这个时候程序就会停下来,就不会跑到断点B,假设我这个循环有100次,那么该如何直接跳过这个烦人的重复100次循环呢?把在循环体中的断点取消了不就OK了。那么这个断点到底有什么用呢?简单的代码可能用不上断点,那么假设这个代码有500行、1000行、10000行,我如果觉得前5000行绝对没有问题,我直接一个断点就完事了,前5000行在调试过程中直接“一闪而过”跳过去,如果你真的F10F10F10地往下按,手指头都要按断了,断点在多行代码的时候是非常有用的。这时候有人就会问了,该如何倒回去?就跟你这么说吧,倒回去这种操作就是不靠谱的,别老是想着这种事情,大不了重新调试一次。) 

F10,F11

F10
这个是逐过程,通常用来处理一个过程。一个过程可以是一次函数调用,或者是一条语句。它和F11的区别在哪呢?
F11
是逐语句,就是说每次都执行一条语句。但是这个快捷键可以使我们的执行逻辑进入函数内部。
(就是说F10与F11在处理函数的方式是截然不同的,F10是不会让你去观察函数内部的具体细节,对于函数的处理直接一步到位。但我如果想去看一下函数内部是怎么执行的,这时候就必须用F11。遇到不是函数的语句,包括循环等等,按F10与F11两者没有任何区别。F11会让你进入到函数的内部,就可以观察函数的细节,两者遇到循环的话都是要每次执行的,破不了循环,要想一次跳过循环,就用断点。
当然在这边还是得讲一下另外一个,如果我们的代码是跨文件的,就打个比方吧,函数的声明放在头文件,函数的定义放在另外一个.c源文件。这时候我想看跨文件的函数内部的细节,只需要在那个函数内部打一个断点,程序无论如何都会经过这儿,因为如果它不经过这,代码走不下去的(这边再次强调一下:断点打完之后,要调试起来是按F5,而不是什么F10F11),至于前面这些细节,根本就不用去关心,我认为这个函数内部有问题,我断点打在函数内部,我让代码走到这个函数内部来然后给我停下。因此断点是在多行代码或者跨文件的时候使用起来非常方便的一种手段。

Ctrl+F5

这个叫做开始执行,不进行调试,如果你想让程序直接运行起来直接按Ctrl+F5,这时候就算在代码内部有断点,也没有任何影响,Ctrl+F5也不会停下来。因为我是执行程序,而不是调试 

 

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

1. 前面讲的是一些快捷键,有了这些快捷键之后就基本上可以尝试去调试代码,但是可能还不够。在程序执行的过程中,我想去观察这个程序的上下文的环境里面的相关数据。也就是说调试的时候如何查看程序当前信息?

2. 重点需要关注哪些东西呢?第一个就是监视,第二个就是内存,第三个就是反汇编,第四个就是寄存器。调用堆栈可能也会需要关注。

3. 还有两个是自动窗口与局部变量。自动窗口里面在监控的值都是在动态的发生变化。一切都是系统自动给你设置好的。但这个其实是并不好用,不能按照我的想法来,它会自作主张,看起来蛮人性化,但用的多了,就会发现并不好用。还有那个局部变量,与自动窗口非常类似,会自动加载上来程序在运行过程中产生的上下文环境的局部变量,只展示局部变量,这是与自动窗口的区别。但这些都不好,因为我不能随心所欲。

监视 

1. 我如果想要随心所欲的话,最好用监视窗口,可以根据实际的需求进行监视。在监视里面观察的非常方便,甚至都可以观察地址,想观察什么东西输入就行了。

2. 对于数组而言,在监视里面,有时候挺好观察,有时候不好观察(尤其在函数内部)。比如说函数里面数组名是arr(该数组有12个元素),一般来说是在监视窗口里面输入arr然后就可以很清晰的观察,但有时候也有不好观察的时候,这时候就输入arr, 12   就可以看到12个元素,这时候如果敲一个arr, 10   就能够看到前10个元素。

内存

1. 接下来还有内存,要观察内存的话也是十分方便。想要观察谁,只需要输入地址就可以(地址不知道?那就&取地址啊),本质上内存里面存的还是二进制,而且是以补码的形式,但是展示的时候,以16进制形式展示比较简短与方便。

2. 在内存里面的话,需要分别清楚,什么是内存地址,什么是内存条里面的数据

3. 一个字节对应一个内存单元,一个内存单元对应一个地址。

还可以查看汇编信息与寄存器信息 

查看调用堆栈 

1. 调用堆栈这个东西比如说可以去发现很多函数的调用的逻辑。这边就又需要注意一点,在VS里面,要调用main()函数的话,已经会有一系列的调用关系了,这就是说明main()函数也是被其他函数调用的。然后你接下来要用很多层函数,就会发现里面会一层一层向上显示。

2. 这个东西相当于数据结构里面的栈,还有一种东西叫做队列。栈和队列常放在一起,这是两种线性数据结构。那么这个队列是什么意思呢?队列就像你排队一样,比如说你在食堂排队买饭,从队尾进去,然后从队头出,像模拟排队一样,数据从这儿进去,然后从这儿出去。这种描述数据的使用,增加,删除的方式叫做队列。那栈呢,又是另外一种数据结构,栈的话有栈底与栈顶,数据如果要放进去的话,都是从顶上进去;数据如果要出来的话,也都是从顶上出来。最顶上的东西没有处理掉,那么在这之下的所有东西都不能动。然后你就会发现这个与调用堆栈里面的函数逻辑现象很是相似。

3. 你会发现这个就跟栈一样,因此我们这个名字就叫做调用堆栈,这种栈一样的一种形式可以模拟出函数的调用逻辑

 

 注:

1. 如果那个断点在循环体里面,那么还可以为这个断点添加条件,可以去特定指定当前循环的条件

2. 那么当我按下F5的时候,之前的那些循环条件就会跳过,比如说我规定循环变量n==5,那么n=1,2,3,4就会一次性执行完毕。直接来到n=5这个时候并且停止执行程序。

 

 

 



 

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

絕知此事要躬行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值