调试意义、步骤及方式

调试意义、步骤及方式一只死在继电器上的飞蛾 被戏称为计算机史上的一个 bug

大家好,欢迎来到IT知识分享网。

调试

1.什么是bug?

在这里插入图片描述

一只死在继电器上的飞蛾,被戏称为计算机史上的一个“bug”。

调试便是找bug的过程。

2.调试是什么?有多重要?

2.1调试

调试(Debugging/Debug),又称除错,是发现和减少计算机程序或电子仪器设备中程序错误的一个过程。

2.2调试的基本步骤

  • 发现程序错误存的存在
  • 以隔离,消除等方式对错误进行定位
  • 确定错误产生的原因
  • 提出纠正错误的解决方法
  • 对程序错误予以改正,重新测试

发现bug的可能是:1.程序员自己 2.测试人员3.客户

2.3Debug和Release的介绍

Debug通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序

Release称为发布版本,它往往是进行各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好的使用

使用Debug和Release分别进行运行后,文件夹中会产生对应的两个文件

在这里插入图片描述

使用Debug版本可以进行调试等操作,Release版本则没有调试信息

在这里插入图片描述

2.3.1常用的快捷键及功能
1.F5

启动调试,经常用来直接跳到下一个断点处。

2.F9

创建断点和取消断点

断点的重要作用,可以在程序的任意位置设置断点。

这样就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。

在这里插入图片描述

选中需要停止的行后,使用快捷按键F9即可设置断点。在使用F5调试程序时将会在第11行停止调试。

多个断点位置,F5后将会在下一个逻辑断点处停下。

在这里插入图片描述

如图第一个断点的位置在第13行(一个循环体结构中),我们在该断点继续执行语句,那么逻辑的下一个断点将会是它的第二次循环而不是第15行的断点。

断点也可以通过鼠标直接单击断点位置进行添加和取消断点。

条件断点

在这里插入图片描述生效后如图:

在这里插入图片描述

i==5时生效,停止输出后面的语句。

3.F10

逐过程,就是每次都执行一条语句,一个过程可以是一次函数调用或一条语句。

F10与F11在普通的语句中没有什么区别,有区别的是函数上。

F10会把函数当作普通的语句直接跳过,而F11可以进入函数内部查看函数运行的过程

4.F11

逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部(这是最常用的)。

5.CTRL+F5

开始执行不调试,如果你想让程序不调试直接运行

3.调试的时候查看程序当前信息

3.1查看临时变量的值

在调试开始之后,用于观察变量的值。

调试起来后,才可以查看下面的选项。

在这里插入图片描述

3.1.1自动窗口

自动串口可以自动获取变量的值。

不过,在调试的过程(比如进入函数内部),那么当前的变量会自动消失,被函数内部的变量取代。(过于自作主张)观察数据不方便。

在这里插入图片描述

简言之,就是会自动获取变量的监视窗口。

3.1.2监视

在调试开始之后,用于观察变量的值。

在这里插入图片描述

3.1.2.1数据结构怎么监视多个数据

数组结构在函数中正常的查看只能查看第一个数据。

我们可以使用(a,个数)来获取对应个数的数组元素。

在这里插入图片描述

a,10就是获取10个元素的。

3.1.3内存的查看及解析

调试后可通过窗口——>内存,查看内存

在这里插入图片描述

内存中的数据解析:

在这里插入图片描述

3.1.4调用堆栈

在调试的情况下,在调试窗口——>调用堆栈

可以查看函数的调用情况(谁被谁调用),

在这里插入图片描述

上面的函数被下面的函数调用:

行9被行13调用,而行13被行17调用……

在这里插入图片描述

数据结构中的栈;

4.一个调试的案例

对数组进行越界访问。

# define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> 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("haha\n"); } return 0; } 

上面的代码运行后可能会出现循环。

原因:

下图所示,未定义的第12个数组元素默认的值为12,且与i的大小相同

在这里插入图片描述

接着运行程序对arr[12]进行修改,发现i也等于0:

在这里插入图片描述

原因就是:

在这里插入图片描述

5.如何写出好的代码(易于调试)

5.1优秀的代码

  1. 代码正常运行
  2. bug很少
  3. 效率高
  4. 可读性高
  5. 可维护性高
  6. 注释清晰
  7. 文档齐全

常见的coding技巧

  1. 使用assert
  2. 尽量使用const
  3. 养成良好的编码风格
  4. 添加必要的注释
  5. 避免编码的陷阱
技巧1:assert

断言,直接拦截错误

例子:编写函数完成strcpy库函数的功能,使用assert进行拦截空指针

# define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <string.h> #include <assert.h> //2.实现库函数strcpy void my_strcpy(char* dest, char* str) { 
    //断言,判断,如果错误讲直接报错 assert(str != NULL); //因为是赋值所以为真,但*str等于0时,*dest也等于0,ASCII码值为0,为假停止 while (*dest++ = *str++) { 
    ; } } int main() { 
    char ch1[20] = "XXXXXXXXXXXXX"; char ch2[] = "hello World!"; int* p = NULL; //my_strcpy(ch1, ch2); my_strcpy(ch1, p); printf("%s", ch2); } 

assert返回错误的位置:

在这里插入图片描述

技巧2:const

const 修饰指针变量

1.const 放在*号左边(const int *p= &num;)

意思是:p指向的对象不能通过p来改变了,但是p本身的值可以改变

2.const放在*号右边(int* const p = &num;)

意思是:p指向的对象是可以通过p来改变的,但不能修改p变量本身的值

1.const 放在*号左边

普通的变量可以使用赋值进行修改:

int num = 10; num = 20; 

使用const修饰后就不能修改:

const int num = 10; num = 20;//报错:表达式必须是可以修改的左值 

但使用const修饰后也并非不可以改,可以获取指针进行修改:

const int num = 10; int *p= &num; *p = 20; printf("%d", num); 

使用const修饰指针变量后,就不能通过指针变量修改变量了:

const int num = 10; const int *p= &num; *p = 20;//报错:表达式必须是可以修改的左值 

指针变量指向的对象不能改变,但指针可以改变

const int num = 10; const int *p= &num; int n = 10; //*p = 20;//erro p = &n;//ok 
2.const放在*号右边

限制p变量本身

const int num = 10; int* const p = &num; int n = 20; p = &n; 
使用assert和const优化求字符长度的函数
# define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <assert.h> //传入数据使用const修饰,防止出现bug时被修改 int my_strlen(const char* str) { 
    //判断是否是空指针 assert(str != NULL); int count = 0; while (*str != '\0') { 
    count++; str++; } return count; } int main() { 
    char str[] = "hello World!"; int len = my_strlen(str); printf("%d", len); } 

6.编程常见的错误

6.1编译型错误(语法错误)

直接看错误提示信息(双击),解决问题。或者凭借经验就可以搞定。相对简单。

6.2链接型错误(出现在链接期间)

链接型错误(出现在链接期间)- 找不到符号(1.不存在。2.写错了)

看错误提示信息,主要在代码中找到错误信息中的标识符,然后定位问题所在。一般是标识符名不存在或者拼写错误

例如:

int a = 0; int b = 0; int c = Add(a,b);//未定义 //无法解析外部符号Add printf("%d",c); 

无法通过点击跳转到对应位置

6.3运行时错误

借助调试,逐步定位问题。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/135784.html

(0)
上一篇 2025-07-02 13:33
下一篇 2025-07-02 13:45

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信