【C初阶】实用调试技巧

本文介绍了调试的重要性,详细讲解了什么是bug和调试的基本步骤,包括Debug和Release模式的区别。在Windows环境下,特别是VS2022IDE中,阐述了调试环境的设置、快捷键使用以及如何查看程序当前信息,如变量值、内存、调用堆栈、汇编和寄存器。通过实例展示了如何调试代码,以及如何写出易于调试的代码,提到了const的作用和编程常见错误类型。
摘要由CSDN通过智能技术生成

⭐博客主页:️CS semi主页
⭐欢迎关注:点赞收藏+留言
⭐系列专栏:C语言初阶
⭐代码仓库:C Advanced
家人们更新不易,你们的点赞和关注对我而言十分重要,友友们麻烦多多点赞+关注,你们的支持是我创作最大的动力,欢迎友友们私信提问,家人们不要忘记点赞收藏+关注哦!!!


前言

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


一、什么是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函数

六、编程常见的错误

(一)编译型错误

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

(二)链接型错误

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

(三)运行时错误

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


总结

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

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2022horse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值