当前位置: 首页 > article >正文

C++—9、如何在Microsoft Visual Studio中调试C++

       本文通过实例操作来介绍 Visual Studio 调试器的功能。调试器在运行过程中可提供许多方法让你查看代码的情况。 你可以逐步浏览代码、查看变量中存储的值、设置对变量的监视以查看值何时改变、检查代码的执行路径、查看代码分支是否正在运行等等。本实例主要是设置断点及查看内存的操作。

DEBUG是计算机排除故障的意思。马克2号(Harvard Mark II)编制程序的格蕾丝·霍珀(Grace Hopper)是一位美国海军准将及计算机科学家,同时也是世界最早的一批程序设计师之一。有一天,她在调试设备时出现故障,拆开继电器后,发现有只飞蛾被夹扁在触点中间,从而“卡”住了机器的运行。于是,霍珀诙谐地把程序故障统称为“臭虫(BUG)”,把排除程序故障叫DEBUG,而这奇怪的“称呼”,竟成为后来计算机领域的专业行话。如DOS系统中的调试程序,程序名称就叫DEBUG。DEBUG在windows系统中也是极其重要的调试操作。

debug的意思就是清除bug,我们必须诊断出程序出了什么问题?接下来让我们来学习断点和查看内存。

一、创建一个简单的项目

1、这是main.cpp,调用log函数。

2、log.h

3、log函数的定义

二、设置断点

       断点是一个标记,指示 Visual Studio 应在哪个位置挂起运行的代码,以查看变量的值或内存的行为,或确定代码的分支是否运行。 它是调试中最基本的功能。

        我们首先要做的是设置一个断点,然后逐步运行程序。我们可以在程序的任何一行代码上设置断点,当执行到这一行时,它会暂停,它将悬停整个程序,我们可以查看内存情况,一个正在运行的程序,内存几乎是它的全部,所以在诊断程序时能查看内存是非常重要的。因为通过查看内存你可以看到每个变量被设置成什么样子了。

如何插入断点?以下几种方法之一:

1、方法一:

2、方法二:

快捷键F9.

3、方法三:

在下图红圈位置单击。

设置断点的位置会出现一个红圈Breakpoint 。

三、通过调试器运行你的代码

1、确保你处于debug模式下。

       因为你在Release模式下,编译器会改变代码,你的断点有可能永远不被执行,因为你的程序被重新安排了。

2、单击本地Windows调试器

它能确保你在运行的时候附加了调制器。点击前后的变化如下图:

我们的程序将执行,并且变成这种样式。

设置断点的位置红圈上有一个黄色的箭头,指示当前指令指针所在的位置。

本地windows调试器按钮变成了继续按钮,它将像往常一样继续执行程序。

它右边还有三个重要的按钮:

这三个按钮会精确控制程序接下来会发生什么,step into逐语句F11会进入当前函数log,如果有函数,他就在这行代码中,所以这种情况下,我进入log函数。

step over逐过程F10,将转到当前函数的下一条语句。

step out跳出 shift+F11 实际上要跳出当前函数,让我们回到这个函数,在这个例子下,因为这是主函数。

F5:调试状态下运行程序

Ctrl+F5程序运行不调试

F10:逐过程调试(遇到函数调用的地方按F10,会执行函数并跳到函数调用下一句)

F11:逐语句调试,会在函数内部执行,如果不想看函数的执行过程按Shift+F11可跳出函数执行过程。

Shift+F11:跳出函数运行(如执行到一个函数内部,或cout语句定义的地方,此时并不想看这些执行过程,则Shift+F11跳出函数)

F12转到函数定义(把光标定位到一个函数,或变量上,按F12,会调转到函数定义或变量定义的地方

F9断点(把光标定位到相要加断点的那一行,按F9;或者直接在那一行最前面点鼠标左键会出现一个红点)

3、step into逐语句F11来看看发生了什么

程序跳转到这里了,进入log函数的开始位置。

现在可以把鼠标悬停在message变量上并查看它,可以看出这个变量被设置成了hello world!

当我们按F10,运行到下图:

黄色箭头在这一行,意味着它还没有执行这一行。

可以看到hello world!并没有被打印出来。

当我们再按F10的时候来看看运行结果

被打印出来了。

因为我们调用了std::cout函数,它将文本打印到了控制台。

通过设置断点和逐步执行程序,我们可以逐行运行我们的程序。

四、读取内存

1、我们来添加一些变量,让程序变得更有趣一些, 

运行F5

2、我们在主程序的第6行设置断点F9,F5。

我们来看一看a是什么?

为什么它是负的8.58亿?

记住:黄色箭头并不意味着我们运行了这段代码,我们正要运行它,但实际上我们还没有执行第6行,就是实际创建并设置变量的那一行。所以调试器给我们显示的是内存,因为我们还没有把变量设为任何值,它只是一个未初始化的内存,这意味着这个值只是显示给我们,并不是内存实际的值。

3、我们来看看下面这三个重要的窗口。

Autos和Locals基本上只是向你展示局部变量或者对你来说重要的变量。Watch,通常用来监控变量。可以按下变量的名字,回车。

你可以看到显示变量的值了。如果你还想查看string是什么,输入回车就可以。

4、我们有一个视图可以用来查看整个程序的内存,它的打开方式:

它打开的面板如下图:

当你想定位变量a实际存储在程序内存的位置,你只需要知道它的内存地址,要做到这一点,我们只需在Memory1窗口下的Address后面的文本框中输入输入“&”和a,变量名前面的&会取到此变量的内存地址,我们回车,就会被带到变量a的内存地址。

回车之后

这个内存是一大堆“cc”的事实,意味着它是一个未初始化的堆栈内存。 实际上编译器知道我们在尝试创建一个变量,但是我们还没有初始化,它会做一些额外的事情,比如在初始化内存之前将其设置为“cc”,很明显会使速度变慢了。我们不想在release模式中这样做,当我们真正release我们的程序或者发行游戏时,我们不想这样做,但是在调试时,它非常有用。

5、接下来,按下F10,

F10:逐过程调试(遇到函数调用的地方按F10,会执行函数并跳到函数调用下一句)

你会发现4个内存字节被设置为8.每位16进制数字是一个字节8位。

再按F10,

再再按F10,

因为是指针型的,输入指针所指地址,

104正好是十六进制的68.

68 65 6c 6c 6f,在ASCII的解释中,你可以看到它是hello。

继续按F10观察,可输入监视变量,

6、按shift+F11,可跳出当前循环。

Shift+F11:跳出函数运行(如执行到一个函数内部,或cout语句定义的地方,此时并不想看这些执行过程,则Shift+F11跳出函数)

7、但是现在只是想跳出for循环执行后面的语句,怎么办呢?

只需要重新设置断点,按F5就可以。


http://www.kler.cn/a/502002.html

相关文章:

  • 【Python】数据容器:列表,元组,字符串,集合字典及通用操作
  • Apache JMeter 压力测试使用说明
  • 如何将 sqlserver 数据迁移到 mysql
  • 六十九:基于openssl实战验证RSA
  • Termora 一个开源的 SSH 跨平台客户端工具
  • TCP封装数据帧
  • 性能测试工具Jmeter负载模拟
  • TPS61022 PFM的机制以及TPS61xxx转换器的PFM与PWM之间的负载阈值
  • 使用jquery的$.ajax提交带有FormData的post请求报错TypeError: Illegal invocation
  • 详解C#调用系统文件窗口:打开文件、保存文件和选择文件夹
  • 【Javaweb02】初探CSS:网页样式设计的入门指南
  • 《机器学习》——TF-IDF(关键词提取)
  • 如何用python实现语音输出
  • 积鼎科技:国产自主核反应堆流体仿真解决方案
  • 深度解析Linux中的调试器gdb/cgdb的使用
  • MySQL 16 章——变量、流程控制和游标
  • 青少年编程与数学 02-006 前端开发框架VUE 23课题、UI框架
  • huggingface/bert/transformer的模型默认下载路径以及自定义路径
  • 《使用 YOLOV8 和 KerasCV 进行高效目标检测》
  • 【机器学习案列】学生抑郁可视化及预测分析
  • 迁移WSL中的ext4.vhdx文件
  • MATLAB与Python中的快速傅里叶变换频谱分析
  • R9000P发热严重
  • 聚铭网络当选中关村华安关键信息基础设施安全保护联盟理事单位
  • 2Hive表类型
  • 计算机网络 | 什么是公网、私网、NAT?