💘作者:你我皆为凡人
💘博客主页:你我皆为凡人的博客
💘名言警句:时间不会为任何人停留,而事物与人,无时不刻也在变化着。每一个人,也都在不停向前!
💘觉得博主文章写的不错的话,希望大家三连(✌关注,✌点赞,✌评论),多多支持一下!!
💘系列作品:
文章目录
目录
🙈 前言
调试在程序编程中具有很重要的地位,调试可以帮助程序员解决很多问题。Bug是由一个或多个缺陷造成的,所以要花一些时间来改正一些程序中的Bug,学会调试,可以让你写代码如鱼得水,更加自如
提示:以下是本篇文章正文内容,下面案例可供参考
💫什么是bug
这是第一次被发现导致计算机错误的飞蛾,也是第一个计算机程序错误,后来把导致计算机出现问题不能正常工作给称之为bug
💫调试是什么?有多重要?
在所有发生的事情中,都一定有迹可循,如果没有破绽问心无愧,那么不需要掩盖任何迹象,而如果问心有愧,那么必然有事实要掩埋,而出现bug就代表问心有愧,就一定会有迹象,而迹象越多就越容易顺腾而上,而这就是推理的途径
而每一名优秀的程序员都是一名出色的侦探
每一次的调试都是尝试破案的过程
💞调试是什么?
调试又称作除错,是发现和减少计算机程序或者电子仪器 设备中错误的一个过程
💞正常人迷式调试
我们是如何写代码的,一般是这样的:
而我们遇到问题又是如何排查解决呢?一般是这样的:
💞正确调试的基本步骤
- 发现程序错误的存在
- 以隔离、消除等方式对错误进行定位
- 确定错误产生的原因
- 提出纠正错误的解决办法
- 对程序错误予以改正,重新测试
💫debug和release的介绍
Debug 通常称为调试版本 ,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release 称为发布版本 ,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。
关于debug与release相同代码的反汇编语言对照
那么这两个在文件中存放的大小有什么不一样呢?优化好的和自己调试有什么区别
💫windows环境调试介绍
💞调试环境的准备
在环境中选择debug选项,才能使代码正常调试
💞学会快捷键
最常用的几个快捷键
F5启动调试,经常用来直接跳到下一个断点处。F9创建断点和取消断点断点 的重要作用,可以在程序的任意位置设置断点。这样就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。F10逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句。F11逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑 进入函数内部 (这是最常用的)。CTRL + F5开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。
💞调试的时候查看程序当前信息
🔹查看临时变量的值
在调试开始之后,用于观察变量的值
🔹查看内存信息
在调试开始之后,用于观察内存信息
🔹查看调用堆栈
通过调用堆栈,可以清晰的反应函数的调用关系以及当前调用所处的位置
🔹查看汇编信息
方法一:
方法二:
🔹查看寄存器信息
💞多动手调试才能有进步
一定要熟练掌握调试技巧初学者可能80%的时间在写代码,20%的时间在调试。但是一个程序员可能20%的时间在写程序,但是80%的时间在调试。我所讲的都是一些简单的调试,以后可能会出现很复杂调试场景:多线程程序的调试等。多多使用快捷键,提升效率。
💫一些调试的实例
💙实例一
实现代码:求1! +2!+3!+....+n!;不考虑溢出
这样的代码如果给初学者来说是极其容易写出bug来的,比如下面这个代码:
int main()
{
int n = 0;
scanf("%d", &n);
int i = 0;
int ret = 1;
int sum = 0;
int j = 0;
for (j = 1; j <= n; j++)
{
for (i = 1; i <= j; i++)
{
ret *= i;
}
sum += ret;
}
printf("%d\n", sum);
return 0;
}
这个错误代码为什么会显示15呢?乍一看没有毛病,实则出现了问题,那么如何解决呢?其实这就是锻炼调试能力的一次机会 ,具体过程就不再演示,大家可以复制代码到vs中实验调试技巧,打开监视,一步一步的看每个变量的值
💙实例二
研究一下下面代码中为何会出现死循环呢?
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;
}
如果刚上手的小白或者新手来说一般觉得是越界访问了,为什么会死循环呢?
下面我们来进行调试前后比较,来进行解释:
开始:
结束:
突然发现,当i等于12的时候,arr【12】也在发生改变,而arr【12】变成0,i也变成了0,这样i就一直循环往复,那么到底是为什么呢?为什么i和arr【12】会同时发生改变呢?会不会他两同时就是一块空间呢?
此时我们发现确实处于一块儿空间,那么是什么原因导致的呢?下面一张图让你了解
💫如何写出好的(易于调试)的代码
💞优秀代码的特点
🔹 代码运行正常🔹 bug很少🔹 效率高🔹 可读性高🔹 可维护性高🔹 注释清晰常见的 coding 技巧:🔹 使用assert🔹 尽量使用const🔹 养成良好的编码风格🔹 添加必要的注释🔹 避免编码的陷阱。
💞const的作用
int main()
{
//int num = 10;
//num = 20;
//printf("%d\n", num);//可以正常改变
//const int num = 10;
//num = 20;//无法改变
//const修饰指针变量
//1 const放在*的左边
//const int* p = #
//int n = 100;
//*p = 20;//err p指向的对象不可以通过p来改变,但是p原有的值是可以改变的
//p = &n;//ok
//2 const放在*的右边
//int* const p = #
//int n = 100;
//p = #//err p指向的的对象可以通过p来改变,但是p原有的值不可发生改变了
}
结论:
const修饰指针变量的时候:1. const如果放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。但是指针变量本身的内容可变。2. const如果放在*的右边,修饰的是指针变量本身,保证了指针变量的内容不能修改,但是指针指向的内容,可以通过指针改变。
💫编程常见的错误
💞编译型错误(语法错误)
一般来说很简单,直接看错误提示信息(双击)就可以解决问题,或者凭借经验就可以搞定这个问题
💞链接型错误(出现在链接期间)
看错误提示信息,主要在代码中找到错误信息中的标识符,然后定位问题所在,一般是标识符名不存在或者拼写错误
💞运行时错误
借助调试,一步一步定位问题出在哪里,最难搞的一个,这个大家应该经常见,写了代码却没有达到自己的预期结果所以只能调试来解决到底是哪里出错了
希望大家做一个有心人,积累排错经验,写出好的代码,少的bug
💞习题练习入口
看完这些不具体操作操作那么是不可以的,可以点击上方直达去练习一些有关习题,也可以随便看一看C语言的一些习题,练习练习选择题和编程题,让自己的知识得到巩固,直接点入标题就可直达,另外想获得大厂内推资格也可以去看看:
💞题外话
在这里博主插句题外话,可直接跳过,我有一个朋友因为满脸痘印毁脸三年,现在恢复的很好,大家如果有同样的困惑和问题,可以去他朋友圈看看加他了解一下:lpy16128227
效果是真的不错,我亲眼看到他痘痘都没有的,具体情况找他了解
🙈 总结
调试对于写好一个程序是非常有帮助的功能,通过调试可以发现一些细微的Bug,这样就可以及时的发现并且改正。调试还有很多有用的操作比如监视局部变量,即时窗口,调用堆栈,调试多线程程序,调试并行程序等。因此深入学习调试是十分重要的!