八.调试的技巧

news2025/2/25 9:57:42

目录

一.调试

1.何为调试?

 2.调试的基本步骤

二.debug和release的介绍

三.Windows环境调试介绍

1.调试环境准备

2.学会快捷键

(1)F5

(2)F9

(3)F10

(4)F11

(5)CTRL+F5

3.调试时查看当前环境信息:

(1)监视

(2)查看内存信息

(3)查看调用堆栈

(4)查看汇编信息

(5)查看寄存器信息

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

1.优秀的代码:

2.常见的coding技巧:

3.assert

4.const

五.编程常见的错误

1.编译型错误

2.链接型错误

3.运行时错误


一.调试

1.何为调试?

定义:调试,又称除错,是发现和减少计算机程序电子仪器设备中程序错误的一个过程;

 2.调试的基本步骤

(1)发现程序错误的存在;

           能够发现错误的人:

             a.程序员,自己发现;

             b.软件测试人员,测试软件;

             c.用户,代价严重;

(2)以隔离、消除等方式对错误进行定位;

         能知道大概在什么位置,再确定错误产生的原因是什么;

(3)提出纠正错误的解决方案;

(4)对程序错误订正,重新调试;

二.debug和release的介绍

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

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

注:Release 版本是不能调试的;

例:

 int main()
{
    int arr[10] = {0};
    int i = 0;
    for(i=0; i<=12; i++) {
        arr[i] = 0;
        printf("hehe\n");
    }
 
    return 0;
}

 在debug环境下,改代码会死循环打印hehe,这是因为:

局部变量是放在内存中的栈区的,栈区的使用习惯是:先使用高地址处的空间,再使用低地址出的空间。

 栈区内存的分配如下图所示:

数组arr与变量i中间恰好有两个整形空间,arr[12]恰好就是变量i所在的空间,所以将arr[12]该为0,i也会改为0,因此会继续循环,死循环打印hehe。

注意:上述代码是在vs2019环境下设计出来的,数组arr和变量i之间不一定恰好有两个整形空间。

将上述代码放在releas环境中:

程序没有死循环,因为release会进行优化。

三.Windows环境调试介绍

1.调试环境准备

在环境中选择debug,才能正常调试。

本篇使用vs2022进行演示。

2.学会快捷键

(1)F5

作用:启动调试,经常用来直接调到下一个断点处;

注:

  ① 如果直接按 F5 ,如果没有阻挡的话程序一口气就跑完了;

  ② 使用 F5 之前如果想查找错误,可以使用F9,设置断点

例:

 int main()
{
    int arr[10] = { 0 };
    int sz = sizeof(arr) / sizeof(arr[0]);
 
    int i = 0;
    for (i = 0; i < sz; i++) {
        arr[i] = i + 1;
    }
    for (i = 0; i < sz; i++) {
        printf("%d\n", arr[i]);
    }
 
    return 0;
}

 运行结果图示:

(2)F9

作用:创建断点和取消断点,断点可以在程序的任意位置设置,这样就可以使得程序在运行过程中随时停止,继而可以一步步执行下去;

例:

 

 运行结果图示:

 这时按下F5会直接跳转到断点部分,停留在11行

(3)F10

作用:通常用来处理一个过程,一个过程可以是一次函数的调用,或者是一条语句;

(4)F11

作用:每次都执行一条语句,观察的细腻度比 F10 还要高,可以进入到函数内部;

注:F10F11 大部分情况是一样的,区别在于 F11 遇到函数时可以进到函数内部去,函数的内部也可以一步步观察,而 F10 遇到函数调用完之后就跳出去了;

例:

#include <stdio.h>

void test()
{
    printf("hehe/n");
}

int main()
{
    test();

    return 0;
}

当按下F10调试:

代码经过test(),但不会访问函数内部,然后屏幕打印hehe。

当按下F11调试:

 代码会跳转到test函数,访问其内部,然后屏幕打印hehe。

(5)CTRL+F5

作用:开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。
总结:

F5 - 启动调试

F9 - 设置/取消断点

F10 - 逐过程

F11 - 逐语句 - 更加细腻

Ctrl + F5 - 运行

更多快捷方式请跳转: http://t.csdn.cn/7bo0Z

3.调试时查看当前环境信息:

调试-->窗口-->选择对应的选项

只有调试时才会显示窗口里的选项

(1)监视

用于查看变量的值:

(2)查看内存信息

在调试开始之后,用于观察内存信息

(3)查看调用堆栈

 

(4)查看汇编信息

(5)查看寄存器信息

 总结:

  1. 多多动手,尝试调试,才能有进步。
  2. 一定要熟练掌握调试的技巧。
  3. 初学者可能80%的时间在写代码,20%的时间在调试,但是一个程序员可能20%的时间在写程序,但是80%的时间在调试;
  4. 我们所讲的都是一些简单的调试,以后可能会出现很复杂的调试场景,多线程程序的调试等。
  5. 多多使用快捷键,提升效率。

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

1.优秀的代码:

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

2.常见的coding技巧:

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

3.assert

assert()断言:如果括号内为假,编译器报错,如果为真,什么事都不会发生。

头文件    #include <assert.h>

#include <stdio.h>
#include <assert.h>
 
char* my_strcpy(char* dest, char* src)
{
    assert(dest != NULL); // 断言   "dest不能等于NULL"
    assert(src != NULL);  // 断言   "src 不能等于NULL"
 
    while (*dest++ = *src++)
        ;
}
 
int main()
{
    char arr1[20] = "xxxxxxxxxx";
    char arr2[] = "hello";
    my_strcpy(arr1, NULL); // 实验:传入一个NULL
    printf("%s\n", arr1);
 
    return 0;
}

 运行结果如下:

 编译器报错,并会指出错误所在行。

4.const

const修饰变量的时候:

1.const放在*的左边,const修饰的是指针指向的内容,表示指针指向的内容,不能通过指针来改变了,但是指针变量本身可以修改

2.const放在*的右边,  const修饰的指针变量本身,表示指针变量本身的内容不能被修改,但是指针指向的内容,可以通过指针来改变。

 例:

const int num = 10;
int* p = &num;
int n = 1000;


const int* p = &num;
*p = 20;   //不可改
p = &n;    //可以改


int* const p = &num;
*p = 20;   //可以改
p = &n;    //不可改

五.编程常见的错误

1.编译型错误

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

2.链接型错误

看错误提示信息,主要在代码中找到错误信息中的标识符,然后定位问题所在。

一般是 标识符名不存在 或者 拼写错误 。

3.运行时错误

代码明明跑起来了,但是结果是错的;

借助调试,逐步定位问题,利用本章说的实用调试技巧解决;


本篇到此结束,码文不易,还请多多支持~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/39705.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java学习】JavaWeb ---- JDBC

文章目录JDBC 快速入门ResultSet数据连接池JDBC 快速入门 下载jar包&#xff08;百度&#xff09;->add as library 代码 package com.ith.jdbc;import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement;public class demo1 {public stati…

HTTPS一定安全吗

https是一种通过计算机网络进行安全通信的传输协议&#xff0c;主要目的是提供对网站服务器的身份认证&#xff0c;保护交换数据的隐私与完整性&#xff0c;但不能说使用htttps就一定绝对的安全。 有一点需要了解的是&#xff0c;使用HTTPS 在内容传输的加密上使用的是对称加密…

使用dreamweaver制作采用DIV+CSS进行布局——美食甜品店铺加盟企业HTML静态网页 ——学生美食网页设计作品静态HTML网页模板源码

&#x1f468;‍&#x1f393;静态网站的编写主要是用HTML DIVCSS JS等来完成页面的排版设计&#x1f469;‍&#x1f393;,常用的网页设计软件有Dreamweaver、EditPlus、HBuilderX、VScode 、Webstorm、Animate等等&#xff0c;用的最多的还是DW&#xff0c;当然不同软件写出的…

C++标准库分析总结(九)——<适配器>

目录 1 适配器简介 2 适配器使用分类 2.1 容器适配器 2.2 函数适配器 2.2.1 常见的函数适配器 2.2.2 bind2nd 2.2.3 not1 2.2.4 bind用法 2.3 迭代器适配器 2.4 X适配器 1.6.1 ostream_iterator 1.6.2 istream_iterator 1 适配器简介 把一个原本存在的东西&#xf…

递归和排序算法的应用

一、递归常见问题和注意事项 1. 堆栈溢出&#xff1b; 2. 警惕重复运算&#xff1a; 可以使用一个数据结构&#xff08;散列表&#xff09;将已经计算过的f(k)保存起来&#xff0c;每当调用到f(k)时&#xff0c;先产看下是否已经求结果&#xff0c;从而避免重复计算。 3. 将递…

【嵌入式Linux】5.Ubuntu 交叉编译工具链安装

前言 交叉编译器中“交叉”的意思就是在一个架构上编译另外一个架构的代码,相当于两种架构“交叉”起来了。 其基本特点是: 1、它肯定是一个 GCC 编译器。 2、这个 GCC 编译器是运行在 X86 架构的 PC 上的。 3、这个 GCC 编译器是编译 ARM 架构代码的,也就是编译出来的可…

MongoDB 的安装、启动与连接

MongoDB 的安装、启动与连接一、MongoDB Community Server1. 安装(1) 下载(2) 安装1) 解压2) 配置环境变量3) 配置数据库存放目录a. 创建b. 赋权2. 启动验证二、MongoDB Compass安装三、连接一、MongoDB Community Server 1. 安装 (1) 下载 官网下载安装 (2) 安装 1) 解压…

three.js之访问几何体数据与几何体的旋转平移

文章目录访问几何体数据简介例子BoxGeometryPlaneBufferGeometry旋转、缩放、平移变换注意专栏目录请点击 访问几何体数据 简介 一般我们在开发项目的时候&#xff0c;可能会加载外部模型&#xff0c;这个时候&#xff0c;我们就需要获取到几何体的顶点数据这个时候&#xff…

Kubernetes入门

文章目录1、K8s快速入门1&#xff09;简介2&#xff09;架构&#xff08;1&#xff09;整体主从方式&#xff08;2&#xff09;master节点架构&#xff08;3&#xff09;Node节点架构3&#xff09;概念4&#xff09;快速体验&#xff08;1&#xff09;安装minikube&#xff08;…

商城项目环境准备 — docker安装elasticsearch

文章目录一、操作系统虚拟内存设置为262144二、拉取elasticsearch镜像三、创建docker容器挂载的目录四、设置挂载文件访问权限五、启动elasticsearch六、访问一、操作系统虚拟内存设置为262144 原因&#xff1a;系统虚拟内存默认最大映射数为65530&#xff0c;无法满足ES系统要…

十万部冷知识:“梅西”是怎么炼成的

随着2022卡塔尔世界杯小组赛第二轮的打响&#xff0c;现在第一支确定被淘汰的队伍已经出现了&#xff0c;它就是东道主卡塔尔队。它也成了继南非世界杯以来&#xff0c;史上第二个小组赛出局的东道主。而在明天的凌晨3点C组的比赛中&#xff0c;广大球迷朋友们关注的阿根廷队也…

C/C++指针入门详解(一)

一、引言 指针是一个地址&#xff0c;这个地址不仅可以是变量的地址&#xff0c;也可以是其它数据结构的地址。为了方便调用这个地址&#xff0c;C/C是通过指针变量来使用这个地址的。而我们常说的指针&#xff0c;其实在一定程度上说的是指针变量&#xff0c;但是我们必须清楚…

通用后台管理系统前端界面Ⅺ——信息列表页(弹窗复用增改、CRUD前端基础实现)

因为需求发生了点变化&#xff0c;所以把之前的代码稍改一下&#xff0c;把之前的信息列表全复制到用户列表中&#xff0c;最后效果一样。UserList.vue <template><div class"UserList"><!-- 查询、重置 --><el-form :inline"true" :…

UnityShader_基础理论

渲染流程 此处的渲染流程只是一个概念流水线。大概分为应用阶段、几何阶段、光栅化阶段。 应用阶段 主要输出渲染所需的几何信息&#xff0c;包括点、线、三角面等&#xff0c;传递给下一阶段使用&#xff1b;这一阶段主要CPU处理&#xff0c;该阶段产生的产物就是渲染图元…

【ML特征工程】第 6 章 :降维:用 PCA 压缩数据薄饼

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

Java并发-synchronized使用方法

synchronized 关键字介绍 Java 中的每个对象都可以把它当作一个同步锁来使用&#xff0c;这些 Java 内置的使用者看不到的锁被称为内部锁&#xff0c;也叫作监视器锁。代码在进入 synchronized 代码块前会自动获取内部锁&#xff0c;这时候其他线程访问该同步代码块时会被阻塞…

十七、CANdelaStudio深入-创建新工程

本专栏将由浅入深的展开诊断实际开发与测试的数据库编辑,包含大量实际开发过程中的步骤、使用技巧与少量对Autosar标准的解读。希望能对大家有所帮助,与大家共同成长,早日成为一名车载诊断、通信全栈工程师。 本文介绍CANdelaStudio创建新工程的过程,欢迎各位朋友订阅、评论…

别卷了!今年局势不一样开始裁员濒临失业

我被优化了&#xff0c;公司劳动合同都当天解除完&#xff0c;电脑也今天全部打包完&#xff0c;非常快&#xff0c;我也是惊呆了&#xff0c;刚刚和他们部门的人吃完饭&#xff0c;感觉今天就是一场梦&#xff0c;昨天还是催着做需求&#xff0c;今天说散就散”&#xff0c;前…

论文浅尝 | Efficient RDF graph storage based on RL

笔记整理&#xff1a;郑国鹏&#xff0c;天津大学硕士链接&#xff1a;https://link.springer.com/article/10.1007/s11280-021-00919-x动机知识是人工智能的基石&#xff0c;它通常以RDF图的形式表示。各个领域的大规模RDF图对图数据管理提出了新的挑战。关系型数据库因其成熟…

Java8 Collectors.toMap() 的使用

目录一、简单介绍用法1&#xff1a;根据某一属性&#xff0c;对对象的实例或属性做映射用法2&#xff1a;根据某一属性&#xff0c;对对象集合进行去重二、Duplicate key 异常1&#xff09;异常重现&#xff1a;2&#xff09;异常截图&#xff1a;3&#xff09;异常说明&#x…