【C初阶】实用调试技巧

news2024/9/20 8:42:33

实用调试技巧

  • 前言
  • 一、什么是bug?
  • 二、调试是什么?
    • (一)调试
    • (二)调试的基本步骤
    • (三)Debug和Release的介绍。
        • 1.简单介绍
  • 三、Windows环境调试介绍
    • (一)调试环境的准备
    • (二)快捷键
    • (三)调试的时候查看程序当前信息
      • 1.查看临时变量的值
      • 2.查看内存信息
      • 3.查看调用堆栈
      • 4.查看汇编信息
      • 5.查看寄存器信息
  • 四、一些调试的实例
    • (一)求 1!+2!+3! ...+ n! ;不考虑溢出。
    • (二)程序死循环的原因
  • 五、如何写出好(易于调试)的代码?
    • (一)优秀的代码:
    • (二)示范
    • (三)const作用
    • (四)模拟strlen函数
  • 六、编程常见的错误
    • (一)编译型错误
    • (二)链接型错误
    • (三)运行时错误
  • 总结


前言

调试相信在大多数初学者的眼里似乎不是那么重要,但是却在未来使用的时候非常重要,当你用过调试并进行深入了解后,你会停不下来用调试进行对代码的编译,所以我们大家需要好好学习调试的技巧,本章节我们将从根源剖析什么是计算机的问题以及如何去解决问题。


一、什么是bug?

bug是什么意思?bug本意是臭虫、缺陷、损坏、窃听器、小虫等意思。现在人们将在电脑系统或程序中,隐藏着的一些未被发现的缺陷或问题统称为bug(漏洞),如一些游戏中不完善的地方。 另外由于现在社会的发展bug另有一种引申意义用来形容某事物厉害的超乎想象BUG可以使电脑系统崩溃,容易被攻击,现有修复漏洞工具。
BUG的解释
史上第一个BUG,第一次被发现的导致计算机错误的飞蛾,也是第一个计算机程序错误。
在这里插入图片描述

二、调试是什么?

(一)调试

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

(二)调试的基本步骤

在这里插入图片描述

(三)Debug和Release的介绍。

1.简单介绍

在这里插入图片描述
在这里插入图片描述

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

三、Windows环境调试介绍

在这里插入图片描述
我们今天演示的是VS2022 IDE编辑器下的环境。

(一)调试环境的准备

在这里插入图片描述
在环境中选择 Debug 选项,才能使代码正常调试。

(二)快捷键

在这里插入图片描述

常使用的几个快捷键:

F5 - 开始调试。经常用来直接跳到下一个断点处。不会单独使用,一般配合F9进行使用。
F9 - 创建断点和取消断点。断点的重要作用,可以在程序的任意位置设置断点。这样就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。设置的断点只要满足条件就跳过去,而在循环中的值不足以跳出循环,那就会在循环里面的断点一直停着,直到跳出循环到循环外的断点。

在这里插入图片描述
F10 - 逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句。
F11 - 逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部(这是最常用的)。
Ctrl+F5 - 开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。

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

1.查看临时变量的值

先F10调试,调试起来后再按照下面的步骤。
在这里插入图片描述
a,n,k,sum是在动态变化的。
在这里插入图片描述

2.查看内存信息

在这里插入图片描述
我们进行取地址查看一下:
在这里插入图片描述

3.查看调用堆栈

通过调用堆栈,可以清晰的反应函数的调用关系以及当前调用所处的位置
在这里插入图片描述

4.查看汇编信息

在这里插入图片描述
可以切换到汇编代码。

在这里插入图片描述
在关于函数的栈帧与创建中,有明确的书写这一部分,大家如果感兴趣可以看一看以下的链接:
函数的栈帧的创建与销毁

5.查看寄存器信息

在这里插入图片描述
可以查看当前运行环境的寄存器的使用信息。

四、一些调试的实例

(一)求 1!+2!+3! …+ n! ;不考虑溢出。

大家可以看看这串代码为什么输出的是15而不是9呢?
在这里插入图片描述
那我们来调试一下吧!
在这里插入图片描述
当n为3的时候,我们发现ret==2,原来是没有更新ret的值呀!在每一次的大循环的时候,ret的值都要更新为1,所以我们重新写一下代码:

//实现代码:求 1!+2!+3! ...+ n! ;不考虑溢出
//5!=5*4*3*2*1
//
int main(){
	int i = 0;
	int sum = 0;//保存最终结果
	int n = 0;
	int ret = 1;//保存n的阶乘
	scanf("%d", &n);//3
	//1!+2!+3!=1+2+6=9
	for (i = 1; i <= n; i++){
		int j = 0;
		ret = 1;
		for (j = 1; j <= i; j++){
			ret *= j;
		}
		sum += ret;
	}
	printf("%d\n", sum);
	return 0;
}

(二)程序死循环的原因

这道题目我在数组的博客中已写,大家可以转到数组的博客去看一下,也可以看我下面的图片:

【C初阶】数组中关于数组越界死循环
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五、如何写出好(易于调试)的代码?

(一)优秀的代码:

  1. 代码运行正常
  2. bug很少
  3. 效率高
  4. 可读性高
  5. 可维护性高
  6. 注释清晰
  7. 文档齐全

常见的coding技巧:

  1. 使用assert
  2. 尽量使用const
  3. 养成良好的编码风格
  4. 添加必要的注释
  5. 避免编码的陷阱。

(二)示范

模拟实现库函数:strcpy。
以下博客链接是我写的关于模拟strcpy函数的博客:
模拟strcpy函数

(三)const作用

如下图,解释了const的作用。
在这里插入图片描述

结论:
const修饰指针变量的时候:

  1. const如果放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。但是指针变量本身的内容可变。
  2. const如果放在*的右边,修饰的是指针变量本身,保证了指针变量的内容不能修改,但是指针指向的内容,可以通过指针改变。

(四)模拟strlen函数

以下博客链接是我写的关于模拟strlen函数的博客:
模拟strlen函数

六、编程常见的错误

(一)编译型错误

直接看错误提示信息(双击),解决问题。或者凭借经验就可以搞定。相对来说简单。
在这里插入图片描述

(二)链接型错误

看错误提示信息,主要在代码中找到错误信息中的标识符,然后定位问题所在。一般是标识符名不存在或者拼写错误。
在这里插入图片描述

(三)运行时错误

借助调试,逐步定位问题。最难搞。
即结果是错误的,那我们就需要调试去解决这个问题。


总结

调试是很关键的,在这篇博客中,我引进了很多外部的链接,那当然都是我之前写的博客,更加详细具体,大家通过此次学习学习到了关于程序的错误和常见的调试技巧。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【SAP Abap】SAP ALV开发(REUSE_ALV_GRID_DISPLAY_LVC)全网最详细 DEMO

SAP ALV开发&#xff08;REUSE_ALV_GRID_DISPLAY_LVC&#xff09;全网最详细 DEMO1、ALV 简介2、演示程序1、ALV 简介 ALV 报表程序&#xff0c;是我们在 SAP 项目中最常开发的程序类型。 SAP 系统提供了三种 ALV 实现方式&#xff0c;分别是&#xff1a; FM ALV&#xff0c;…

win10下安装多个JDK配置方法

环境变量配置 此电脑 --- 属性 -- 高级系统设置 -- 环境变量 -- 系统变量 -- 新建 1、配置JAVA_HOME JAVA6_HOME jdk1.6的安装路径 JAVA8_HOME jdk1.8的安装路径 JAVA_HOME %JAVA8_HOME% 两个%表示引用变量的值&#xff0c;直接用JAVA_HOME&#xff0c;就能表示一连串长…

SAR影像变化检测方法之(SAR_CD_DDNet(无监督变化检测))论文阅读

一、论文信息 1、论文标题&#xff1a;Change Detection in Synthetic Aperture Radar Images Using a Dual-Domain Network 2、代码链接&#xff1a;https://github.com/summitgao/SAR_CD_DDNet 二、摘要 合成孔径雷达(SAR)图像的变化检测是一项关键而具有挑战性的任务。现…

Android---BottomAppBar

目录 BottomAppBar FloatingActionButton UI 完整代码 BottomAppBar Material Design 的一个重要特征是设计 BottomAppBar 。可适应用户不断变化的需求和行为。因此&#xff0c;BottomAppBar 是一个从标准物质指导的演变。它更注重功能&#xff0c;增加参与…

ansible 第三天

1.挂载本地光盘到/mnt 2.配置yum源仓库文件通过多种方式实现 仓库1 &#xff1a; Name: RH294_Base Description&#xff1a; RH294 base software Base urt: file:///mnt/BaseOS 不需要验证钦件包 GPG 签名 启用此软件仓库 仓库 2: Name: RH294_Stream Description &#xff1…

Android Studio 用WIFI无线调试adb (3种方法)

最近数据线一直被boss借走&#xff0c;一旦借走就无法调试了&#xff0c;所以就打算不用数据线调试了&#xff0c;使用WIFI进行调试。 一、命令 1、首先配置adb环境变量 首先找到andoridSDK的路径中的platform-tools文件夹 &#xff0c;将他的路径复制我的是 C:\Users\YiShi…

365天深度学习训练营-第P7周:YOLOv5-Backbone/YOLOv5-C3模块实现

目录 一、前言 二、我的环境 三、代码实现 1、C3模块 2、Backbone模块 一、前言 >- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营](https://mp.weixin.qq.com/s/xLjALoOD8HPZcH563En8bQ) 中的学习记录博客** >- **&#x1f366; 参考文章&#xff1a;36…

【算法】day03:动态规划dp

努力经营当下&#xff0c;直至未来明朗&#xff01; 文章目录1. 青蛙跳台阶2. 矩形覆盖3. 二进制中1的个数4. 链表中倒数第k个结点普通小孩也要热爱生活&#xff01; 1. 青蛙跳台阶 跳台阶 1&#xff09;思路&#xff1a;如果青蛙在第n个台阶上&#xff0c;那么它要么来自n-1…

python命名规范

1.命名有字母、数字和下划线三个组成 2.项目名、包名、模块名、python文件名 都应该用英文开头&#xff0c;不能纯数字&#xff0c;否则无法识别 3.脚本名不能跟系统模块或三方模块重复 4.函数、类、方法、参数名称不能跟系统现有名称重复 5.类名必须以大写字母开头、除了类…

Kafka在windows下下载、启动、测试详细教程

目录 下载地址 启动 启动zookeeper 启动kafka 队列操作 创建消息队列名 删除消息队列名 查看所有的队列 测试 生产测试 消费测试 下载地址 Apache KafkaApache Kafka: A Distributed Streaming Platform.https://kafka.apache.org/downloadswindows下kafka3.0版本的…

G120系列变频器进行参数备份(上传或下载)的2种基本方法介绍(Startdrive+SD卡)

G120系列变频器进行参数备份(上传或下载)的2种基本方法介绍(Startdrive+SD卡) 1. 通过SINAMICS SD存储卡对G120系列变频器进行参数上传/下载的具体方法 适配范围:CU240B-2(DP)/CU240E-2(DP/PN)/CU250S-2(DP/PN) 可将变频器的参数设置保存至 SINAMICS SD 卡。在进行变频器更…

回归预测 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络多输入多输出

回归预测 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络多输入多输出 目录回归预测 | MATLAB实现CNN-LSTM卷积长短期记忆神经网络多输入多输出预测效果基本介绍程序设计往期精彩参考资料预测效果 基本介绍 MATLAB实现CNN-LSTM卷积长短期记忆神经网络多输入多输出&#xff0c;运行…

docker swarm 集群部署和验证

docker swarm可以轻松的部署集群,实现负载均衡,服务器的扩容和扩容的反义词. 首先docker的官方文档非常的不稳定,梯子也不解决问题.还好有替代 docs.docker.com 用不了 https://docs.docker.com.zh.xy2401.com/engine/swarm/swarm-tutorial/ 很好 场景: 三台机器 x.x.x.104 x.…

经典文献阅读之--FAST-LIVO(Fast-LIO系列的激光视觉惯性里程计)

0. 简介 在此之前博主对Fast-LIO2和R3LIVE进行了系统性的学习。最近文章《Fast and Tightly-coupled Sparse-Direct LiDAR-Inertial-Visual Odometry》提出了FAST-LIVO&#xff0c;这是一种快速LiDAR惯性-视觉里程计系统&#xff0c;它建立在两个紧耦合的直接里程计子系统之上…

结构体、枚举、联合(14)

目录 1、结构体 1、结构的声明 2、特殊的声明 2、结构的自引用 3、结构体变量的定义和初始化 4、结构体内存对齐 1、结构体的对齐规则&#xff1a; 2、为什么存在内存对齐? 3、修改默认对齐数 5、结构体传参 2、枚举 1、枚举类型的定义 2、使用 3、优点 3、联合…

MAC(m1)-Vagrant下载安装

Vagrant是一款用来构建虚拟开发环境的工具&#xff0c;它其实算是一个跨平台的虚拟机管理工具。 Vagrant是构建在虚拟化技术之上的虚拟运行环境管理工具。通过使用Vagrant我们可以快速去构建 我们想要的虚拟环境&#xff0c;同样其搭配virtualbox来进行使用&#xff0c;通过构…

重磅来袭!2023年大版本更新,看看有哪些是你期待的功能和优化吧

Hello&#xff01;好久不见&#xff0c;最近两个月我们的攻城狮和产品汪都在潜心的优化产品&#xff0c;我们将于1月5日上线 v10.7.0版本。本次版本迭代&#xff0c;我们更新了上百项体验优化&#xff0c;并将在未来几周发布更多功能和改进。 本次我们对前端底层架构进行优化重…

vue3笔记案例——Teleport使用之模态框

模态框 理想情况下&#xff0c;我们希望触发模态框的按钮和模态框本身是在同一个组件中&#xff0c;因为它们都与组件的开关状态有关。但这意味着该模态框将与按钮一起渲染在应用 DOM 结构里很深的地方。 使用 Teleport 传送组件可以将组件传送至其他层级的DOM结构中 效果图 …

数据流图实例应用

数据流图实例应用 参考链接&#xff1a; https://blog.csdn.net/xiaoxiang2017/article/details/81460397 https://blog.csdn.net/m0_53130858/article/details/127234104 数据流图&#xff1a;简称DFD&#xff0c;它从数据传递和加工角度&#xff0c;以图形方式来表达系统的逻…

Talk预告 | 几何的魅力: 黑盒攻击新策略

本期为TechBeat人工智能社区第468期线上Talk&#xff01; 北京时间1月4日(周三)20:00&#xff0c;清华大学软件工程专业博士——马晨的Talk将准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “几何的魅力&#xff1a;黑盒攻击新策略”&#xff0c;届时将介…