什么是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;
}