C语言-实用调试技巧(上)

实用调试技巧(上)

什么是bug

bug的原意是臭虫,虫子。

世界上首次出现bug,是在1947年9月9日,赫柏对Harvard Mark II设置好17000个继电器进行编程后,技术人员正在进行整机运行时,它突然停止了工作。于是他们爬上去找原因,发现这台巨大的计算机内部一组继电器的触点之间有一只飞蛾,这显然是由于飞蛾受光和热的吸引,飞到了触点上,然后被高电压击死。
所以在报告中,赫柏用胶条贴上飞蛾,并把“bug”来表示“一个在电脑程序里的错误”,“Bug”这个说法一直沿用到今天。

在这里插入图片描述

现在,bug一般是指在电脑系统或程序中,隐藏着的一些未被发现的缺陷或问题(如:软件运行中因为程序本身有错误而造成的功能不正常、体验不佳、死机、数据丢失、非正常中断等现象。),简称程序漏洞,是程序设计中的术语。

什么是调试

调试的定义

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

  • 调试,形象的来说就是寻找蛛丝马迹,逆流而上,找到真相。
  • 一名优秀的程序员都是一名优秀的侦探,每一次调试都是一次破案的过程。
  • 调试就是寻找代码里面的问题并解决的过程。

发现程序的bug的有三类人:程序员自己,测试人员和用户

调试的步骤

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

debug和release

Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。

  • debug模式下可以调试和观察

Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。

  • release(测试人员测试完后没什么问题)模式下不能够很好的观察

下图为debug和release模式在vs中的位置(以下均已vs2019为例)

在这里插入图片描述
二者的异同:

  • debug文件夹下是调试版本的可执行程序,release文件夹下是发布版本的可执行程序(如下)
    在这里插入图片描述
  • 二者都需要在各自的模式下调试,才能产生exe文件
  • debug模式下,可执行程序41kb(较大)

在这里插入图片描述

  • release模式下,可执行程序9kb(较小)

在这里插入图片描述

Windows下的调试环境

调试环境的准备

windows环境下的开发环境可以为vs,如vs2019,vs2022,等 称为IDE,集成开发环境,它包含编辑器,编译器和调试器

linux环境下编译器为gcc,调试器为gdb;

将模式改为debug模式

快捷键

常用的快捷键有F5,Ctrl+F5,F9,F10,F11,如下

在这里插入图片描述
两个需要知道的前提:

  • 对于热键被锁的情况下,他的快捷键可能需要加上fn键,比如说逐语句F11,在单独按F11没有反应的情况下,可以使用fn+F11
  • 断点:打断程序执行,程序执行将会停在这里

在这里插入图片描述

F9设置断点:光标停在程序想要执行的那行处,按f9,出现如下的红点

按下f5调试后,执行就会停在断点处;
断点f9和调试f5是一起配合着使用的;
可以设置多个断点,每按一次f5,就会停在一个断点处;
在循环内部的断点,按循环的流程来看,相当于在循环内加了多个断点;
断点适用于代码数量较多条件下的调试或者是跨文件时使用;

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

f11逐语句(会进入被调用的函数内部),每次都执行一条语句

ctrl+f5 不调试直接运行,即使加断点也不会停下来

调试过程中查看程序的相关信息

主要有自动窗口,局部变量,监视,内存,反汇编,寄存器,调用堆栈,断点窗口,如下:

在这里插入图片描述

自动窗口:动态变化着的,不一定好用,系统自动显示或删除信息,不一定满足自己的要求;

局部变量:只展示出局部变量,也是系统自动显示,不一定满足自己的要求;

监视:自定义,想看哪个变量,就可以看哪个变量,还可以删除。如下:

在这里插入图片描述

这个要监视的对象,不仅可以是变量,还可以是其他的,比如地址,如下:

在这里插入图片描述

如果是数组的话,需要 数组名,数组元素的个数,比如:arr,12 如下

在这里插入图片描述

内存 :在内存窗口可以看到地址,包括全局全量,局部变量,数组等,如下:

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

数组的地址直接写数组名,如下:

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

反汇编:能够看到翻译成汇编语言后是什么样子的(汇编代码),如下:

在这里插入图片描述

寄存器,寄存器也可以在监视窗口查看(直接写寄存器的名字),如下:

在这里插入图片描述

调用堆栈(栈:从顶上放进去,从顶上拿出来),如下:

在这里插入图片描述

断点窗口,可以看到所有的断点,即使不在这个.c文件下,也能看到。如下:

在这里插入图片描述

实例分析

示例一

求 1!+2!+3! …+ n!

int main()
{
	int i = 0;
	int sum = 0;//保存最终结果
	int n = 0;
	int ret = 1;//保存n的阶乘
	scanf("%d", &n);
	for (i = 1; i <= n; i++)
	{
		int j = 0;
		for (j = 1; j <= i; j++)
		{
			ret *= j;
		}
		sum += ret;
	}
	printf("%d\n", sum);
	return 0;
}

运行结果如下:
在这里插入图片描述

通过计算,我们发现上述的结果并不正确,于是我们进行调试(逐语句)
在这里插入图片描述

我们发现ret在循环的过程中,它的上一轮的值被保存了下来;而我们是不需要在上一轮的基础上计算的,每轮结束后,都需要将其置1。

或者这样观察,我们发现当n=2的时候,sum的结果是没有问题的,因此可以推断出n=3时,程序存在问题,我们可以通过设置断点的条件,来直接达到n=3时的调试(f5)开始时刻。如下:

在这里插入图片描述
在这里插入图片描述
此种方法特别适用于循环过程中的调试,可以大大的节省时间。

实用调试技巧(下)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值