程序员养成金手指——调试造就优秀

简介: 正片开始👀Bug👏bug意为臭虫,计算机术语里就是幺蛾子,对,你的程序又出幺蛾子了。为什么要叫bug?关于这个还有段有趣的历史

正片开始👀

Bug👏

bug意为臭虫,计算机术语里就是幺蛾子,对,你的程序又出幺蛾子了。为什么要叫bug?关于这个还有段有趣的历史


有一天赫柏正愉快地敲着Mark Ⅱ的代码时,计算机突然就停止运作了,那时的计算机远不如现在小巧,赫柏他们只能一个个排查计算机庞大的处理器群,经过一段时间的排查后停机原因终于被找到了。原来是一只飞蛾被计算机的光和热吸引,触发了电脑的短路,当然这只可怜的飞蛾也一命呜呼了按理说一般人也就是把飞蛾拿走,然后重启下电脑也就完事了,但赫柏显然不是一般人她小心翼翼地把这只飞蛾拿了下来,然后把它工工整整地粘在了记事本上… …


这就是历史上第一个 bug 的诞生。


调试的重要性👏

我估计前期我们找 bug 都是用眼睛瞅,特别是我们这种大一的刚接触的,现在还好,到了以后需要写大工程的时候,眼瞅不头疼的才是大哥,对于一个成熟程序员20%时间写代码而80%时间在调试代码。

我们写代码就是一个推理的过程,整个流程的正确与错误都是有迹可循的,推理的途径就是这些迹象。

一名优秀的程序员就是一个优秀的侦探,找到迹象,顺流而下是错误,顺流而上是真相,调试就是我们破案的过程。

调试基本步骤👏

1.找错(进行隔离,消除来定位错误)

2.知道错因

3.寻找解决办法

4.纠正,重测


Debug与Release👏

Debug(Debugging),即排错,称为调试版本,不作任何优化,包含调试信息,便于我们调试程序。

Release ,即释放,成为测试版本,往往进行各种优化,让代码在大小和运行速度上都是最优的,面向用户,可以很好的使用。但是!注意Release版本是没法进行调试的,这种观点仅限于我当前知识面的限制,实际上Release也是可以的,下面是大佬对我的指正意见:

image.png

快捷键👏

在调试过程中,掌握一些快捷键会大大增加我们的效率。以vs2019为例,我们先会设置断点如图(行标左侧设置)

image.png

断点设置在需检查代码的任意位置,运行到这一步就会停下给我们报告。断点完F5调试,执行窗口弹出后就会发现调试就会出现更多内容,我框出来的在之前记录C语言学习时都有用到。

image.png

注意F5是调试,Ctrl+F5是运行,通常会使用会F5跳到想要的断点处,有些电脑上比较装怪,快捷键没反应的,建议多按一个Fn键试试,Fn是功能辅助键,相当于一个开关,本质上 F5+Fn = F5。需要强调的是逐语句和逐过程,如果你想看每个细节,不放过每一个角落就用逐语句,两者的力度是不一样的,逐过程会跳过代码里的函数部分。

vs玩家重点推荐 Ctrl+k+c,注释选中行;Ctrl+k+u,取消注释,熟练运用会很方便。

其余还有很多不赘述,下面准备了超全的实用快捷键用法:


想深入了解的铁子戳这里


除了用调试验证代码的正确性,还可以用于研究具体的问题,举个栗子:

这道题是Nice的面试真题

请说明下面代码是否能正常运?运行结果是什么?为什么会出现这个结果?
int main()
{
int i = 0;
int arr[10] = { 0 };
for (i = 0; i <= 12; i++)
{
arr[i] = 0;
printf(“hehe\n”);
}
return 0;
}

这里当我们打开调试窗口直接开调:

image.png

OMG,是一样的。但我们这里的调试只能看到现象,他底层的原理我们要自己思考。

其死循环的逻辑大致是这样的,我们创建了一个变量i,arr,他们都是局部变量,而局部变量时放在栈上的,栈区上内存使用习惯是先使用高地址存储空间,再使用低地址。这里注意,我们开始给的十个大小的空间,i的变量是到12,这里明显是越界访问,但为什么没有报错停下来?结合我们刚刚监视的结果,我们再把格局打开:

数组随着下标的增长,地址是由低到高的变化,在我数组适当越界时,如果i和arr之间的空间适当的话,就有可能使arr向后越界时就访问到了i,造成了循环变量的i改变,最终会死循环。

image.png

这种错误其实存在偶然性,首先i和arr[12]相同,只是恰巧,但如果我把i换成11,结果就大相径庭了,我只形成了越界但没有改变循环变量i的值。其次,这个代码是严重依赖环境的,比如在VC 6.0里面i和arr就是连续的,gcc里面i和arr之间有一个空间。

打趣的是,我们在Release版本里面是不会报错并且会停下来,其实在刚刚的截图里面也是会报错的,但是!死循环停不下来,他根本没时间来报错。Rlease的优化并不是万能的,不要期待利用Release版本来掩盖代码的bug,最好的做法就是不要越界。


如何写出易于调试(优秀)的代码👏

1.硬性要求运行正常

2.bug少(估计没人敢保证零bug吧)

3.效率高

image.png

4.可读性高


5.可维护性(容易修改与二创)

6.注释(方便阅读)

7.文档齐全


常见的coding技巧👏

1.使用assert

意为断言,在代码执行前设的前哨,比如我们函数传参时,当我传的内容变成空指针,后面如果函数进行解引用操作,对于空指针解引用是会造成程序崩溃的,是很危险的,所以我们用assert当监护人能快一步该诉我们问题在这里;设置assert也是一个好习惯,面试官见了直呼老司机!

# include<assert.h>
void my_str(char* a, char* b)
{
  assert(a != NULL && b != NULL);//断言
  while (*b != '\0')
  {
    *a = *b;
    b++;
    a++;
  }
  *a = *b;
}
int main()
{
  char arr[10] = {0};
  char arr2[] = "bit";
  my_str(NULL, arr2); // 故意设成NULL程序会崩溃
  printf("%s\n", arr);
  return 0;
}

image.png

效果如上图就会显示断言失败。


2.尽量使用const

const我之前博客写过的常变量修饰符。

就上面模拟strcpy函数,如果有天有个内鬼改了你的代码,写成 *b = *a,就拷反了,编译器也会傻不拉叽的输出,尽管结果什么都没有。那怎么办呢?我在开头就定义好


char* my_str(const char *a,const char* b)

1

这样不管你咋改,我 *a,*b都是无法改变的。


注意const int *p=&a , const 在 * 左边时,修饰的是指针指向的内容,指针变量不影响 ;在 * 右边是,修饰指针本身,指针变量不能修改,其内容可以通过指针来改变。

3,形成良好的编码风格

4.注释!注释!注释!(好习惯讲三次)

5.避免编码陷阱


今天就到这里了,摸了家人们。


相关文章
|
SQL 关系型数据库 MySQL
mysql怎么备份
mysql怎么备份
626 7
|
10月前
|
人工智能 算法 数据管理
制作像素风《饥荒》类游戏的整体蓝图和流程
制作一个像素风《饥荒》类游戏的整体蓝图和流程
|
存储 JavaScript 搜索推荐
Node框架的安装和配置方法
安装 Node 框架是进行 Node 开发的第一步,通过正确的安装和配置,可以为后续的开发工作提供良好的基础。在安装过程中,需要仔细阅读相关文档和提示,遇到问题及时解决,以确保安装顺利完成。
984 155
|
Java
java springboot 8080端口号冲突时 修改当前项目端口号
java springboot 8080端口号冲突时 修改当前项目端口号
731 0
|
人工智能 Cloud Native Serverless
Serverless Devs 官网全新升级,Serverless+AI 重磅来袭
Serverless Devs 官网迎来全新升级,主站以 AI 应用开发的叙事透出项目特性和解决方案。应用中心(Registry)将各类热门 AI 应用模版、实用 AI 工具以及 AI 工作流等呈现给用户。本次升级主题为“一站式 AI/函数/应用开发”,希望为开发者提供更加便利的应用模版搜索和展示服务,本文将对本次升级的三大看点进行整理,欢迎您来体验!
|
人工智能 机器人 Serverless
《10 分钟构建 AI 客服并应用到网站、钉钉或微信中》解决方案体验评测
一文带你详细了解如何基于百炼平台、函数计算或者计算巢AppFlow10 分钟构建 AI 客服并应用到网站、钉钉或微信中,附全篇图文详解,欢迎阅读评价。
1141 10
《10 分钟构建 AI 客服并应用到网站、钉钉或微信中》解决方案体验评测
|
存储 安全 数据库
阿里云最新域名注册和续费、企业邮箱、云虚拟主机收费标准与价格参考
域名注册和续费以及企业邮箱和云虚拟主机是很多用户上云第一步需要购买的产品,从2024年9月1日开始,全球域名又迎来了一波价格上调,目前阿里云的.com英文域名的注册价格由原来的78元涨价到了83元,续费价格也涨到了90元,不过企业新用户注册有1元购等活动。企业邮箱目前活动价540.00元/1年起,云虚拟主机独享基础增强版月付49元/1个月起,年付588元/1年起。本文为大家整理汇总了截止目前,阿里云域名注册和续费及转入收费标准、企业邮箱收费标准与活动价格、云虚拟主机最新收费标准,以供参考。
|
数据可视化 uml
UML图讲解(关联关系,单向关联,双向关联,自关联,组合关系,依赖关系,继承关系,实现关系)
UML图讲解,关联关系,单向关联,双向关联,自关联,组合关系,依赖关系,继承关系,实现关系。
6510 0
UML图讲解(关联关系,单向关联,双向关联,自关联,组合关系,依赖关系,继承关系,实现关系)
|
uml
UML 类图几种关系(依赖、关联、泛化、实现、聚合、组合)及其对应代码
UML 类图几种关系(依赖、关联、泛化、实现、聚合、组合)及其对应代码
4094 0
|
API 计算机视觉
【OpenCV】—图像对比度、亮度值调整
【OpenCV】—图像对比度、亮度值调整
387 1