C语言:调试的概念和调试器的选择

所谓调试(Dubug),就是跟踪程序的运行过程,从而发现程序的逻辑错误(思路错误),或者隐藏的缺陷(Bug)。 在调试的过程中,我们可以监控程序的每一个细节,包括变量的值、函数的调用过程、内存中数据、线程的调度等,从而发现隐藏的错误或者低效的代码。 我敢保证,每个人都会遇到逻辑错误,而且会经常遇到,初学者更是错的离谱,所以,必须掌握调试技能,没有选择的余地,没有学会调试就是没有学会编程!

调试器(Debugger)

调试需要借助专业的辅助软件——调试器(Debugger)。现在主流 C/C++调试器有下面几种:

1) Remote Debugger

Remote Debugger 是 VC/VS 自带的调试器,与整个 IDE 无缝衔接,使用非常方便,初学者建议使用该调试器,本教程也以 VS2010 为例讲解调试技巧。

2) WinDbg

大名鼎鼎的 Windows 下的调试器,它的功能甚至超越了 Remote Debugger,它还有一个命令行版本 (cdb.exe),但是这个命令行版本的调试器指令比较复杂,不建议初学者使用。

3) LLDB

XCode 自带的调试器,Mac OS X 下开发必备调试器。

4) GDB

Linux 下使用最多的一款调试器,也有 Windows 的移植版,如果你不使用 VC/VS,GDB 将是一个不错的选择。

默认情况下,程序不会进入调试模式,代码会瞬间从开头执行到末尾。要想观察程序的内部细节,就得让程序在某个地方停下来,我们可以在这个地方设置断点。

所谓断点(BreakPoint),可以理解为障碍物,人遇到障碍物不能行走,程序遇到断点就暂停执行。

上图中,我们希望让程序在第 4 行代码处暂停执行,那么在第 4 行代码左侧的灰色部分单击鼠标即可插入断点。你也可以将光标定位到要暂停的代码行,然后按 F9 键插入断点。也可以在要暂停的位置单击鼠标右键,在弹出菜单中插入断点,如下图所示:

插入断点后,点击上方的“运行”按钮,或者按 F5 键,即可进入调试模式,如下图所示:

可以看到,程序虽然运行了,但并未输出任何数据,这是因为在输出数据之前就暂停了。同时,在 IDE 的上方出现了与调试相关的工具条,下方也多出了几个与调试相关的窗口:

 调用堆栈可以看到当前函数的调用关系。

 断点窗口可以看到当前设置的所有断点。

 即时窗口可以让我们临时运行一段代码,后续我们会重点讲解。

 输出窗口和我们之前看到的没有,用来显示程序的运行过程,给出错误信息和警告信息。

 自动窗口会显示当前代码行和上一代码行中所使用到的变量。

 局部变量窗口会显示当前函数中的所有局部变量。

 线程和模块窗口暂时无需理会。

如果你的 VS 缺少某个窗口,可以通过 VS 上方的“调试”菜单调出,如下图所示:

注意:必须在调试状态下才能看到图中的菜单。

如果你希望关闭某个窗口,可以在窗口标题处单击鼠标右键,在弹出菜单中隐藏,如下图所示:

断点的真正含义

严格来说,调试器遇到断点时会把程序暂时挂起,让程序进入一种特殊的状态——中断状态,这种状态下操作系统不会终止程序的执行,也不会清除与程序相关的元素,比如变量、函数等,它们在内存中的位置不会发生变化。

关键是,处于中断状态下的程序允许用户查看和修改它的运行状态,比如查看和修改变量的值、查看和修改内存中的数据、查看函数调用关系等,这就是调试的奥秘。

继续执行程序

点击“运行”按钮或者按 F5 键即可跳过断点,让程序恢复正常状态,继续执行后面的代码,直到程序结束或者遇到下一个断点。

在调试过程中,按照上面的方法可以设置多个断点,程序在执行过程中每次遇到断点都会暂停,如下图所示:

删除断点

如果不希望程序暂停,可以删除断点。删除断点也很简单,在原有断点处再次单击鼠标即可,也可以将光标定位到要删除断点的代码行,再次按 F9 键,或者在右键菜单中删除,如下图所示

代替暂停语句

在 VS 下,程序运行结束后不会自动暂停(一闪而退),要手动添加暂停语句 system("pause");,如果大家觉得麻烦,也可以在代码最后插入断点,强制程序暂停。

设置了断点,就可以观察程序的运行情况了,其中很重要的一点就是查看相关变量的值,这足以发现大部分逻辑错误。

将下面的代码复制到源文件中:

1. #include <stdio.h>
2. int main(){
3. int value_int, array_int[3];
4. float value_float;
5. char* value_char_pointer;
6. //在这里插入断点
7. value_int = 1048576;
8. value_float = 2.0;
9. value_char_pointer = "Hello World";
10. array_int[0] = 379; array_int[1] = 94;
11. //在这里插入断点
12. return 0;
13. }

在第 7 行和第 12 行插入断点。运行到第一个断点时,在局部变量窗口可以看到各个变量的值:

可以看到,未经初始化的局部变量和数组的值都是垃圾值,是随机的,没有意义。双击变量的值,可以进行修改。

点击“运行”按钮或按 F5 键,程序会运行到下一个断点位置,在局部变量窗口可以看到各个值的变化:

更加快捷的方式

除了在窗口中查看变量,还有一种更加便捷的方法:在调试模式下,把鼠标移动到要查看的变量的上方,即可看他它的值。如下图所示:

如果是数组、指针、结构体等还可以展开,如下图所示:

这种查看变量的方式在实际开发中使用很多。

添加监视

如果你希望长时间观测某个变量,还可以将该变量添加到监视窗口。在要监视的变量处单击鼠标右键,弹出如下菜单:

选择“添加监视”,在 VS 下方的监视窗口就可以看到当前变量:

这样,每次变量的值被改变都会反映到该窗口中,无需再将鼠标移动到变量上方查看其值。尤其是当程序稍大时,往往需要同时观测多个变量的值,添加监视的方式就会显得非常方便。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/502040.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python深度学习GRU、LSTM 、BiLSTM-CNN神经网络空气质量指数AQI时间序列预测及机器学习分析|数据分享...

全文链接&#xff1a;https://tecdat.cn/?p38742 分析师&#xff1a;Zhixiong Weng 人们每时每刻都离不开氧&#xff0c;并通过吸入空气而获得氧。一个成年人每天需要吸入空气达6500升以获得足够的氧气&#xff0c;因此&#xff0c;被污染了的空气对人体健康有直接的影响&…

Flink源码编译与运行

1 准备 准备好Java 8环境和编译器&#xff08;如IDEA&#xff09;。 下载源码&#xff1a; 官网&#xff1a;https://flink.apache.org/downloads/。GitHub&#xff1a;https://github.com/apache/flink。 2 编译 在IDEA终端&#xff0c;使用下面命令之一编译源码&#xff…

Elasticsearch:Lucene 2024 年回顾

作者&#xff1a;来自 Elastic Chris Hegarty 2024 年对于 Apache Lucene 来说又是重要的一年。在本篇博文中&#xff0c;我们将探讨主要亮点。 Apache Lucene 在 2024 年表现出色&#xff0c;发布了许多版本&#xff0c;包括三年来的首次重大更新&#xff0c;其中包含令人兴奋…

(四)基于STM32通过Event Recoder实现时间测量功能

目录 1. 了解Event Recorder 2. 硬件和软件准备 硬件需求 软件需求 3. 配置STM32工程 使用STM32CubeMX初始化项目 配置Event Recorder 4. 实现时间记录功能 初始化Event Recorder 时间间隔计算 配置Debug选项 测量结果查看 5总结 在嵌入式系统开发中&#xff0c;精…

Java 内存溢出(OOM)问题的排查与解决

在 Java 开发中&#xff0c;内存溢出&#xff08;OutOfMemoryError&#xff0c;简称 OOM&#xff09;是一个常见且棘手的问题。相比于数组越界、空指针等业务异常&#xff0c;OOM 问题通常更难定位和解决。本文将通过一次线上内存溢出问题的排查过程&#xff0c;分享从问题表现…

Python、R用深度学习神经网络组合预测优化能源消费总量时间序列预测及ARIMA、xgboost对比...

全文链接&#xff1a;https://tecdat.cn/?p38726 分析师&#xff1a;Qingxia Wang 在能源领域&#xff0c;精准预测能源消费总量对制定合理能源战略至关重要。当前&#xff0c;能源消费预测分析主要运用单一模型&#xff08;如灰色预测法、时间序列分析法等&#xff09;和组合…

【LLM-Agent】Building effective agents和典型workflows

note Anthropic的工程经验&#xff1a; 大道至简&#xff0c;尽量维护系统的简洁&#xff1b;尽量让过程更加透明&#xff08;因为你依赖的是LLM的决策&#xff0c;如果只看输出不看过程&#xff0c;很容易陷入难以debug的情况&#xff09;&#xff1b;对LLM需要调用的工具&am…

音视频入门基础:MPEG2-PS专题(4)——FFmpeg源码中,判断某文件是否为PS文件的实现

一、引言 通过FFmpeg命令&#xff1a; ./ffmpeg -i XXX.ps 可以判断出某个文件是否为PS文件&#xff1a; 所以FFmpeg是怎样判断出某个文件是否为PS文件呢&#xff1f;它内部其实是通过mpegps_probe函数来判断的。从《FFmpeg源码&#xff1a;av_probe_input_format3函数和AVI…

CSS——5. 外部样式

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>方法3&#xff1a;外部样式</title><link rel"stylesheet" href"a.css" /><link rel"stylesheet" href"b.css"/&g…

lenovo联想IdeaPad 15sIML 2020款(81WB)笔记本电脑原装出厂OEM预装系统Windows10镜像下载

适用机型 &#xff1a;【81WB】 链接&#xff1a;https://pan.baidu.com/s/1SF9uWaNdCKPkwKgsCWb18g?pwdh6qe 提取码&#xff1a;h6qe 联想原厂WIN系统自带所有驱动、带Recovery恢复重置、出厂主题壁纸、系统属性联机支持标志、系统属性专属LOGO标志、Office办公软件、联想…

WPS表格技巧01-项目管理中的基本功能-计划和每日记录的对应

前言&#xff1a; 在项目管理中&#xff0c;一般就是用些项目管理工具来管理这个任务和 task&#xff0c;但是就是要学这些工具很麻烦&#xff0c;比较好的方法&#xff0c;通用的方法就是用 Excel 表格去做&#xff08;这非常适合松散的团队组织&#xff09;&#xff0c;然后…

《前端web开发-CSS3基础-1》

文章目录 《前端web开发-CSS3基础》1.CSS引入方式2.选择器-标签和类3.选择器-id和通配符选择器4.画盒子5.字体修饰属性6.字体大小、粗细和倾斜6.1字体大小6.2 字体粗细6.3字体倾斜 7.行高8.字体族9.font复合属性10.缩进、对齐和修饰线10.1 文本缩进10.2 文本和图片对齐10.3 文本…

Mac M2基于MySQL 8.4.3搭建(伪)主从集群

前置准备工作 安装MySQL 8.4.3 参考博主之前的文档&#xff0c;在本地Mac安装好MySQL&#xff1a;Mac M2 Pro安装MySQL 8.4.3安装目录&#xff1a;/usr/local/mysql&#xff0c;安装好的MySQL都处于运行状态&#xff0c;需要先停止MySQL服务最快的方式&#xff1a;系统设置 …

网络IP协议

IP&#xff08;Internet Protocol&#xff0c;网际协议&#xff09;是TCP/IP协议族中重要的协议&#xff0c;主要负责将数据包发送给目标主机。IP相当于OSI&#xff08;图1&#xff09;的第三层网络层。网络层的主要作用是失陷终端节点之间的通信。这种终端节点之间的通信也叫点…

密钥管理系统在数据安全解决方案中的重要性

密钥管理系统在数据安全解决方案中占据着举足轻重的地位&#xff0c;其重要性体现在以下几个方面&#xff1a;一、保障数据机密性 密钥管理系统通过生成、存储和管理加密密钥&#xff0c;确保了数据的机密性。这些密钥用于加密和解密数据&#xff0c;只有授权用户才能访问和使…

关于PINN进一步的探讨

pinn 是有监督、无监督、半监督&#xff1f; PINN&#xff08;Physics-Informed Neural Networks&#xff0c;物理信息神经网络&#xff09;通常被归类为一种有监督学习的方法。在PINN中&#xff0c;神经网络的训练过程不仅依赖于数据点&#xff08;例如实验观测数据&#xff0…

设计形成从业务特点到设计模式的关联

规范和指引在应用架构、数据架构等各架构方向上形成规范性约束指导。同一个决策要点、架构单元在统一的架构原则指导下&#xff0c;会因业务特点差异有不同的实现&#xff0c;经过总结形成了最佳实践。在开展新应用的设计时&#xff0c;根据决策要点以及相关的业务特点&#xf…

Framebuffer 驱动

实验环境: 正点原子alpha 开发板 调试自己编写的framebuffer 驱动,加载到内核之后,显示出小企鹅 1. Framebufer 总体框架 fbmem.c 作为Framebuffer的核心层,向上提供app使用的接口,向下屏蔽了底层各种硬件的差异; 准确来说fbmem.c 就是一个字符设备驱动框架的程序,对…

STM32第十一课:STM32-基于标准库的42步进电机的简单IO控制(附电机教程,看到即赚到)

一&#xff1a;步进电机简介 步进电机又称为脉冲电机&#xff0c;简而言之&#xff0c;就是一步一步前进的电机。基于最基本的电磁铁原理,它是一种可以自由回转的电磁铁,其动作原理是依靠气隙磁导的变化来产生电磁转矩&#xff0c;步进电机的角位移量与输入的脉冲个数严格成正…

WPS-JS宏快速上手

WPS JS宏注意事项 代码后面可以不写分号“ ; ”&#xff1b; 缩进对程序的运行影响不大&#xff0c;但为了易读&#xff08;防止自己以后看不懂&#xff09;&#xff0c;还是乖乖写好&#xff1b; 代码是逐行运行的&#xff0c;意味着下面一行代码错了&#xff0c;前面的代码…