资讯专栏INFORMATION COLUMN

【C语言基础】实用调试技巧

lsxiao / 3422人阅读

摘要:调试的基本步骤发现程序错误的存在以隔离消除等方式对错误进行定位确定错误产生的原因提出纠正错误的解决办法对程序错误予以改正重新测试和版本的介绍通常称为调试版本,它包含调试信息,并且不做任何优化,以便于程序员调试。

在我们编写代码的时候难免会遇到很多问题,我们光靠眼睛是很难看出来哪里出问题了,这时我们往往需要动手一步一步的运行程序找出问题的所在,这个过程就是调试的过程。在IT界流传着这么一句话“一名优秀的程序员也是一名优秀的侦探”所以当我们遇到问题时,还是要多动手,尝试调试,才能有进步。希望大家多多给予支持,赠人玫瑰,手有余香!

一:什么是Bug?

现在提起bug,大都想到的是「程序错误、漏洞」,其实bug的原意为「昆虫」
为什么变成这样呢? 因为世界上第一个程序错误就是由一只昆虫所造成的

1947年9月9日,葛丽丝·霍普(Grace Hopper)发现了第一个电脑上的bug。当在Mark II计算机上工作时,整个团队都搞不清楚为什么电脑不能正常运作了。经过大家的深度挖掘,发现原来是一只飞蛾意外飞入了一台电脑内部而引起的故障(如图所示)。这个团队把错误解除了,并在日记本中记录下了这一事件。也因此,人们逐渐开始用“Bug”(原意为“虫子”)来称呼计算机中的隐错。 —— 维基百科

二:什么是调试

所谓调试(Debug),就是让代码一步一步慢慢执行,跟踪程序的运行过程。 比如,可以让程序停在某个地方,查看当前所有变量的值,或者内存中的数据;也可以让程序一次只执行一条或者几条语句,看看程序到底执行了哪些代码。

2.1:调试的基本步骤

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

2.2:Debug和release版本的介绍

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

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


可以看出在文件大小上有了明显的差异。

下面,我们用一个代码示例来说明Release相对于Debug版本发生了优化。
代码示例:

int main(){	int i = 0;	int arr[10] = {1,2,3,4,5,6,7,8,9,10};	for (i = 0; i <= 12; i++)	{		arr[i] = 0;		printf("hehe/n");	}	return 0;}

上述代码在Debug版本中运行时导致了死循环,而在Release版本编译时,程序没有死循环。这之中的区别就是因为优化问题而出现的。
这是因为在一些编译器中,在栈中储存如果i和arr之间的空间适合的话,就有可能使用的arr数组向后越界就访问到了i,造成循环变量i的改变,最终死循环。

注:
i和arr是局部变量
局部变量是放在栈区上的
栈区上内存的使用习惯是:先使用高地址处的空间,再使用低地址处的空间。
数组随着下标的增长,地址是由低到高变化。

三:Windows调试环境介绍

3.1:调试环境的准备

注:Debug可以调试,Release不可以调试。

在环境中选择Debug选项,才可以正常调试

3.2:快捷键的使用

我们介绍几个最常用的快捷键:
F9:设置断点或取消断点,可以在任意位置设置,这样可以使得程序在想要的位置停下来。
F5:启动调试,往往与F9设置断点配合使用,使开始调试就跳到断点处。
F10:逐过程调试,一个过程可以是一条语句,也可以是一个函数。遇到函数不进入函数内部。
F11:逐语句调试,每次执行一条语句,可以使执行逻辑进入函数内部。shift+F11跳出函数。
CTRL + F5:开始执行不调试。

设置断点+F5 再F10或者F11(进入函数内部) shift+f11 退出函数

3.3:调试查看当前程序信息

3.3.1:查看临时变量的值

在调试开始之后,用于观察各个变量值的变化;

3.3.2:查看内存信息

在调试开始之后,用于观察内存信息;

3.3.3:查看寄存器信息

3.3.3:查看调用堆栈

通过查看调用堆栈,我们可以看出函数的调用关系以及当前调用所处的位置;

四:调试实例

下面我们给出一个简单的调试实例,让大家可以切身体会一下调试的过程,朋友们可以动手试一试。

int main(){	int n = 0, sum = 0;	int ret = 1;	scanf("%d", &n);	for (int i = 1; i <= n; i++)	{		for (int j = 1; j <= i; j++)		{			ret *= j;		}		sum += ret;	}	printf("%d/n", sum);	return 0;}

如果我们输入3,正确答案应该是9,而程序运行相互来确实15,这时我们可以通过调试找出问题的所在。

五:如何写出好的代码

5.1:什么是优秀的代码

  • 代码运行正常;
  • Bug很少;
  • 效率高;
  • 可读性高
  • 可维护性高;
  • 注释清晰;
  • 文档齐全;

5.2:常用的Coding技巧

  • 使用assert();
  • 合理使用const;
  • 养成良好的编码习惯;
  • 添加必要的注释;

OK!!!观众老爷们,这里只是介绍了简单的调试技巧,如果朋友们觉得有一点点作用的话,希望朋友们能够给予小菜鸟一点支持!后续继续给朋友们带来更好的博文,还希望朋友们能够继续关注,小菜鸟致力于把自己的学习经验与个人理解更多的分享给大家,望大家喜欢与指正。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/124505.html

相关文章

  • ES6的7个实用技巧

    摘要:交换元素利用数组解构来实现值的互换调试我们经常使用来进行调试,试试也无妨。提供了完整的环境,并且支持自定义域名指向,动态计算资源调整,可以完成各种应用的开发编译与部署。 7 Hacks for ES6 Developers Hack #1 交换元素 利用数组解构来实现值的互换 let a = world, b = hello [a, b] = [b, a] console.log(a...

    CastlePeaK 评论0 收藏0
  • 实用Javascript调试技巧分享

    摘要:见过太多同学调试只会用简单的甚至,看着真为他们捉鸡。。下面我就分享一些实用且聪明的调试技巧,希望能让大家调试自己代码的时候更加从容自信。其实提供了文件的搜索功能,只不过大部分时候我们给忽略了。。 见过太多同学调试Javascript只会用简单的console.log甚至alert,看着真为他们捉鸡。。因为大多数同学追求优雅而高效地写代码,却忽略了如何优雅而高效地调试代码,不得不说是有点...

    jk_v1 评论0 收藏0
  • IntelliJ IDEA 超实用使用技巧分享

    摘要:超实用使用技巧分享长篇前言工欲善其事必先利其器最近受部门的邀请,给入职新人统一培训,发现有很多新人虽然日常开发使用的是,但是还是很多好用的技巧没有用到,只是用到一些基本的功能,蛮浪费这个优秀的。 IDEA 超实用使用技巧分享(长篇) showImg(https://segmentfault.com/img/remote/1460000019977268?w=1280&h=800); 前...

    fevin 评论0 收藏0
  • 节省时间的那些 Linux 命令

    摘要:基础的网络管理命令或者,。使用来随机打乱一个文件中的行或者选择一个随机的行。比如,这条命令可以将重音都小写,并且去掉通过扩展并且丢掉要将文件切片,可以试试根据大小切分或者根据模式切分。前言:有网友在问答网站Quora上提问:有哪些省时小技巧,是每个Linux用户都应该知道的? Joshua Levy 平常就在 Linux 平台工作,并且他积累了不少实用命令行技巧,他在回复中精选出一部分。对...

    DoINsiSt 评论0 收藏0
  • 实用浏览器调试技巧(动画、节点删除、节点增加)

    摘要:今天分享一些平时不常用,但总有一天你会用到的浏览器调试技巧。如图彩蛋介绍一个在浏览器中全局搜索代码的方法,点击面板,会看到左侧有目录结构,右键目录结构。如图小扩展还有一个场景一个页面会从后台请求字体包,字体包会在某个时刻通过加入到标签中。 今天分享一些平时不常用,但总有一天你会用到的浏览器调试技巧。先来看一个H5页面,下面是地址http://liticool.info/wsvist/i...

    honmaple 评论0 收藏0

发表评论

0条评论

lsxiao

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<