编程终极技能-调试(上)

简介: 编程终极技能-调试

1.调试是什么?


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


2.调试的步骤


  1. 发现程序错误的存在
  2. 以隔离、消除等方式对错误进行定位
  3. 确定错误产生的原因
  4. 提出纠正错误的解决办法
  5. 对程序错误予以改正,重新测试


3. Release 和 Debug的介绍


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


例如:在VS2022中:


723d81be58eac55ea9930e0be8bd670a_ded2a484644c41bd92617eb2e95289a7.png


实例一:

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


这段代码在debug 模式去编译,程序的结果是死循环。

如果是 release模式去编译,则没有死循环。


他们之间有什么区别呢?


【Debug】下:


通过调试操作,发现数据访问的第12个元素刚好就是 i变量所在的空间,通过修改 arr[12]将 i改成了0。就这样 i 变量一旦增加到了12就会被改成0,程序发生了死循环。


原因:程序在栈上开辟空间时,优先会利用高地址的空间,因为此处i变量先创建,所以变量i的地址高于数组的地址。随后创建数组,数组的起始内存空间肯定是在i变量的下面,当数组越界访问时,访问的地址越来越高,由于i与arr数组的最后一个元素的地址空间只差了8个字节,刚好数组向上多访问两个元素,就访问到了i变量,并且数组还做了将i变量置为0的操作,此时, arr[i]就又开始访问数组的第一个元素了,等到访问到arr[i](i==12)时,又将i置为0,一直循环往复,形成了死循环。


1f6f15a49cbb178e098eb5c1d82a4012_63f9e3247d9d4117aeb383e14414a324.png


【release】下:


release版本之下,程序不会出现死循环。因为编译器做了一些优化处理。我们可以适当观察一下:


189ff178e3c6d19b43479a66f4d9b3f2_2f158de9dabd445b9d6ad7871ab3344a.png


可以发现:变量在内存中开辟的顺序发生了变化,影响到了程序的执行结果。


4. Visual studio的调试


4.1环境准备


首先要在编译环境中选择 Debug 选项,代码才能正常调试。


4.2快捷键的使用


1bce68f0733055e39da8d5d0f410c287_e332f5396ae14004b5080d7e473947f7.png


常用的快捷键需要记住,后期会帮我们节省很多时间。例如:shift+F11用于跳出该函数。


F5:启动调试,经常用来直接跳到下一个断点处


F9;创建断点和取消断点。断点可以在程序的任意位置设置。


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


F11:逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部(这是最常用的)。


CTRL + F5:开始执行但是不调试。


4.3 调试的时候查看程序信息


调试启动之后。


70a9f22c556504619fc4043e45f51545_c40fd5438ae4400cb03404eb3121a73a.png


查看内存信息:


bd23f35382d7e1c77e3ca6fcd3a7e70a_94293e828c984fd2a1b8485d3e500c08.png


总之,调试的功能应有尽有,要根据不同的实例恰当的选取。


相关文章
|
存储 安全 Java
SpringBoot实战(六)之使用LDAP验证用户
关于ubuntu16.04服务器安装配置LDAP参考链接为:https://www.howtoing.com/how-to-install-and-configure-openldap-and-phpldapadmin-on-ubuntu-16-04/ 本文主要讲LDAP相关的概念,普及相关知识和相关例子实战。
3852 0
SpringBoot实战(六)之使用LDAP验证用户
|
10月前
|
运维 监控 算法
监控局域网其他电脑:Go 语言迪杰斯特拉算法的高效应用
在信息化时代,监控局域网成为网络管理与安全防护的关键需求。本文探讨了迪杰斯特拉(Dijkstra)算法在监控局域网中的应用,通过计算最短路径优化数据传输和故障检测。文中提供了使用Go语言实现的代码例程,展示了如何高效地进行网络监控,确保局域网的稳定运行和数据安全。迪杰斯特拉算法能减少传输延迟和带宽消耗,及时发现并处理网络故障,适用于复杂网络环境下的管理和维护。
|
人工智能 测试技术 计算机视觉
7B最强长视频模型! LongVA视频理解超千帧,霸榜多个榜单
【8月更文挑战第1天】新模型LongVA实现7B级最强长视频理解!通过长上下文转移技术,LongVA能够处理超千帧视频,显著提升长视频理解精度。不同于传统模型依赖视觉重采样导致的信息损失,LongVA扩展语言主干上下文长度,无需额外视频训练即可理解大量视觉标记。在V-NIAH等基准上取得SOTA成绩,处理2000帧以上视频无额外复杂度增加。但实时应用及非视频任务仍面临挑战。[论文](https://arxiv.org/abs/2406.16852)
387 4
|
存储 容灾 NoSQL
同城双活的必修课 - 落地经验与关键挑战解析
同城双活作为一种容灾架构,通过在同一城市建立两个数据中心,以确保在一个数据中心发生故障时,系统能够快速切换到另一个数据中心,从而提高系统的可用性
1738 2
同城双活的必修课 - 落地经验与关键挑战解析
|
弹性计算 关系型数据库 MySQL
rds子网配置
在阿里云中配置RDS子网涉及五个关键步骤:1) 创建或选择VPC作为私有网络环境;2) 在VPC内创建子网并确保IP地址不重叠;3) 关联路由表和安全组以控制流量及访问权限;4) 创建RDS实例时指定VPC和子网;5) 确保ECS实例与RDS在同一VPC或配置相应跨VPC访问,并调整安全组规则。这样可保障RDS与其他资源的通信及网络性能。
353 6
|
数据可视化 物联网 区块链
探索Python中的数据可视化:使用Matplotlib和Seaborn绘制图表探索未来:区块链、物联网与虚拟现实的融合趋势与应用前景
【8月更文挑战第30天】本文旨在引导读者通过Python编程语言,利用Matplotlib和Seaborn库,轻松掌握数据可视化技术。文章以浅显易懂的语言,结合实用的代码示例,从基础的图表绘制到高级定制功能,逐步深入讲解如何在数据分析中运用这些工具。无论你是编程新手还是希望提升可视化技能的开发者,都能在这篇文章中找到有价值的信息,让你的数据“活”起来。
|
API 开发者 Python
Zohomail邮箱API发送邮件的方法
Zohomail提供RESTful API用于发送邮件,可通过HTTP请求集成到应用中实现自动化。要使用API,需获取访问权限,包括API密钥和访问令牌。发送邮件涉及构建HTTP POST请求、发送请求及处理响应。示例代码展示了Python发送邮件的过程。AokSend支持高效邮件发送服务,包括SMTP/API接口和触发式接口。
|
Kubernetes Cloud Native Devops
云原生技术落地实现之二KubeSphere DevOps 系统在 Kubernetes 集群上实现springboot项目的自动部署和管理 CI/CD (2/2)
云原生技术落地实现之二KubeSphere DevOps 系统在 Kubernetes 集群上实现springboot项目的自动部署和管理 CI/CD (2/2)
333 1
|
前端开发 API
minio预签名上传前端axios注意事项
minio预签名上传前端axios注意事项
432 0
|
人工智能 JavaScript 前端开发
视野修炼-技术周刊第42期
🔥强烈推荐 1. 生成带图的二维码 这篇文章讲解了如何利用 SD(Stable Diffusion) 将二维转成图像