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、方法三:

在下图红圈位置单击。

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

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

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就可以。

相关推荐
_w_z_j_26 分钟前
C++----模拟实现string
开发语言·c++
特立独行的猫a27 分钟前
redis客户端库redis++在嵌入式Linux下的交叉编译及使用
linux·数据库·c++·redis·redis客户端库
张槊哲29 分钟前
const(C++)
开发语言·c++
oioihoii34 分钟前
C++23 中 constexpr 的重要改动
c++·算法·c++23
pystraf1 小时前
UOJ 228 基础数据结构练习题 Solution
数据结构·c++·算法·线段树
牙痛不能吃糖,哭1 小时前
C++面试复习日记(8)2025.4.25,malloc,free和new,delete的区别
开发语言·c++
冰茶_1 小时前
.NET MAUI 发展历程:从 Xamarin 到现代跨平台应用开发框架
学习·microsoft·微软·c#·.net·xamarin
ChoSeitaku2 小时前
17.QT-Qt窗口-工具栏|状态栏|浮动窗口|设置停靠位置|设置浮动属性|设置移动属性|拉伸系数|添加控件(C++)
c++·qt·命令模式
软行3 小时前
LeetCode 每日一题 2845. 统计趣味子数组的数目
数据结构·c++·算法·leetcode
小贾要学习3 小时前
【C++】继承----下篇
android·java·c++