什么是bug
调试是什么?有多重要?
debug和release的介绍
windows环境调试介绍
一些调试的实例
如何写出(易于调试的)代码
编程常见的错误
1.什么是bug
软件缺陷
2.调试(Debug)是什么?有多重要?
调试就是找bug(Debug)的过程,又称除错,是发现和减少计算机程序或电子仪器设备中程序错误的一个过程。
调试的基本步骤:
2.1现程序错误的存在,以隔离,消除等方式对错误进行定位
(看一下错误当前在那个范围内,定位他的范围定位他的模块)
2.2确定错误产生的原因
2.3提出纠正错误的解决方法
2.4对程序错误予以改正,重新测试
3.Debug和Release
Debug通常被称为调试版本,它包含调试信息,并且不做任何优化,便于程序员调试程序
Release称为发布版本,它往往是进行各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户更好的使用
任何的可执行程序最终会编译产生一个可执行程序,如果采用Debug调试的方式,会产生一个可执行程序,但是他是Debug版本的可执行程序,如果设置成Release,就会产生一个Release版本的可执行程序
Debug版本的可执行程序是可以调试的,因为文件中包含了调试信息,在release版本的可执行程序里面是不可以进行调试的
system("pause");//让窗口不会一闪而过,
代码写的时候应该把环境改成Debug版本的,以便我们随时调试
- 对于Debug和Release,有时候,在Debug版本的测试下是没问题的,但是在Release版本下可能会出现问题,因为Release在测试的时候会自行去优化,从而会改变原来一部分小的代码,有时候会出错。
4.Windows调试环境介绍
4.1环境的准备
需要在vs编译器里面把Release改成Debug环境
4.2学会快捷键
断点:让我们能快速的并执行完程序的结果并来到问题处,再按一次(f5)在执行断点处他会继续执行程序逻辑的下一步
最常使用的几个快捷键
F5
启动调试,经常用来直接跳到下一个断点处(红点)。
F9 创建断点和取消断点 断点的重要作用,可以在程序的任意位置设置断点。 这样就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。
F10 逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句。
F11 逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部(这是最 常用的)。
CTRL + F5 开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。
4.3调试的时候查看程序的当前信息
查看临时变量的值
自动窗口,局部变量,监视,内存,调用堆栈
5.一些调式的实例*
这个程序为何会死循环?
#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;
}
首先,这个程序明显存在越界访问,而我们调用超过第十一个元素的时候,他已经存在越界访问了,但是我们说开辟的空间会存储在栈区,而栈区的默认使用是:先使用高地址处的空间,再去使用低地址处的空间,而数组会随着下标的增长,地址也是由高到低进行变化的,在这里(int i)是第一个创建的空间,所以他是会在最高地址处栈区进行开辟空间的,而导致这个死循环的原因是(arr)与(int i)属于同一块地址,那为什么会是同一块空间呢?是因为(i)他要访问第十个以后的空间,而数组(arr)只创建了10个空间,所以会存在越界访问,我们又说创建变量会默认使用高地址的空间,而数组随着下标的增长,地址由低到高变化,所以栈区只是一块范围,它也是有局限的, 而arr(i)访问第13个空间的时候,它们两的空间便碰在在一起了,在arr(i)被赋值为0的时候,变量i也会随之变为0,因为它们是同一块空间,所以又会从0开始,然后导致死循环,如果我们先创建(int arr)再去创建变量(int i)
就不会发生循环。
6.如何写出(易于调试的)代码
优秀的代码 :
6.1:代码运行正常
6.2:bug很少
6.3:效率高
6.4:可读性高
6.5:可维护性高
6.6:注释清晰
6.7:文档齐全
6.1常见的coding技巧
6.1.1:使用assert
6.1.2:尽量使用const
6.1.3:养成良好的编程风格
6.1.4:添加必要的注释
6.1.5:避免编程的陷阱
模拟实现库函数strcpy--(strcpy(目的地, 源头))
#define _
#include<stdio.h>
void my_strcpy(char* dest, char* src)
{
while(*src !='\0')//当不等于\0的时候进去,等于\0的时候停止
{
*dest = *src;//取出b和#进行交换
src++;//指针++跳转后一个源头#进行交换
dest++;//指针++跳转后一个目的地i进行交换
}
*dest = *src;//取出最后一个\0与#进行交换
}
int main()
{
char arr1[] = "##############";
char arr2[] = "bit";
my_strcpy(arr1, arr2);
printf("%c\n", arr2);
return 0;
}
优化版本
#include<stdio.h>
void my_strcpy(char* dest, char* src)
{
assert(dest !=NULL);
assert(src !=NULL);
while(*dest++ = *src++)
{
;
}
}
int main()
{
char arr1[] = "##############";
char arr2[] = "bit";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}