bug的定义:
第一次被发现的导致计算机错误的飞蛾,也是第一个计算机程序错误。,于是这只飞蛾被称之为bug,所有导致计算机不能正常运行的问题都是bug。
调试的基本方式:
1.发现程序错误的存在
2.以隔离、消除等方式对错误进行定位
可以使用printf打印一些数字或者注释来把不同模块的代码进行分割,以判断出错的位置
3.确定错误产生的原因
4.提出纠正错误的解决办法
5.对程序错误予以改正,重新测试
Debug和Release:
Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。
Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优 的,以便用户很好地使用。
#include <stdio.h>
int main() {
int i = 0;
int arr[10] = {0};
for(i=0; i<=12; i++)
{
arr[i] = 0;
printf("hehe\n");
}
return 0; }
上述代码在debug版本和release版本运行的结果是不一样的,在debug版本下,代码将执行死循环。而产生的原因是i和arr[12]所占用的地址是一样的,因此在我们改变arr[12]为0时,也机缘巧合的把i也变成了0,这样i又重新开始从0到12循环,产生了死循环。
这样bug的出现是因为我们数组的越界访问,编译器只能随机查看是否越界并进行报错,并不会在所有越界的情况下提供警告。和查酒驾一样,警察只会在容易酒驾的地方设卡,而不是所有地方都进行检查。所以,我们在写代码的时候一定要注意这种错误。
Windows环境下的调试:
调试环境:
我们一定要选择debug版本进行调试,否则编译器进行优化后我们的代码哪里有错误哪里没错误就不得而知了。
常用快捷键:
F5:启动调试,直接跳到下一个断点处
F9:创建和取消断点,断点的作用使程序停到自己想要的位置上。
F10: 逐过程执行语句,也就是当遇到函数和循环的时候会跳过。
F11:逐语句执行语句,可以进到函数的内部。
CTRL + F5: 使程序不经过调试直接运行起来
调试的实例:
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;
}
我们通过在调试,窗口,监视中可以看到各个变量的值,通过逐语句的执行,可以看到之所以出现bug是因为ret没有在执行一次后重置为1
如何减少bug的产生:
- 使用assert
- 尽量使用const
- 养成良好的编码风格
- 添加必要的注释
- 避免编码的陷阱。
编程常见的错误:
编译型错误:
看错误提示信息,双击定位到错误的位置,可以通过经验或者上网查相关的资料解决问题。
链接型错误:
找到错误提示信息的标识符位置,一般是标识符不存在或拼写问题。
运行时错误:
利用调试技巧,查看是否存在数组越界,野指针访问等问题,通过画图把软件运行的过程梳理清楚,边逐语句执行代码边画图,举出特殊的例子进行运行。
实在搞不定就去打打球,玩会游戏