【维生素C语言】第八章 - 实用调试技巧(一)

简介: 一名优秀的程序员是一名出色的侦探,每一次调试都是尝试破案的过程……本章将详细带你学习实用调试技巧!正式开启DEBUG

b7f8287d04e55a75e5f0e4a7cc7355c5_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MDUwMjg2Mg==,size_16,color_FFFFFF,t_70.png

前言


一名优秀的程序员是一名出色的侦探,每一次调试都是尝试破案的过程……本章将详细带你学习实用调试技巧!正式开启DEBUG生活。


一、调试(Debug)


0x00 何为调试

1ecf33b997712a8967680e4ac0f72d8f_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MDUwMjg2Mg==,size_16,color_FFFFFF,t_70.png

一名优秀的程序员是一名出色的侦探,每一次调试都是尝试破案的过程……


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


0x01 调试的基本步骤

📚 基本步骤:


    ① 发现程序错误的存在;


          ✅ 能够发现错误的人:


               ⑴  程序员,自己发现;


               ⑵  软件测试人员,测试软件;


               ⑶  用户,代价严重;


          📜 箴言:要善于承认自己的错误,不能掩盖错误;


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


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


    ③ 提出纠正错误的解决方案;


    ④ 对程序错误订正,重新调试;


二、Debug和Release的介绍


0x00 对比

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


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


📌 注意事项:Release 版本是不能调试的;


💬 用 Debug 和 Release 分别运行:


int main()
{
    char* p = "hello,world!";
    printf("%s\n", p);
    return 0;
}

🚩 Debug 环境下运行结果如下:

c53604bcb414604b91123c622ff85fe6_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MDUwMjg2Mg==,size_16,color_FFFFFF,t_70.png


🚩  Release 环境下运行结果如下:

b40c171eb0720c301057f6fb1d98be34_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MDUwMjg2Mg==,size_16,color_FFFFFF,t_70.png


💡 我们可以发现:Release进行了优化,使得程序在运行速度和代码大小上是最优的;


💬 Debug和Release反汇编展示对比:

8b077a115944f079dd980552d9eed171_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MDUwMjg2Mg==,size_16,color_FFFFFF,t_70.png


0x01 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 模式去编译,程序结果是 死循环:

1bda98e14020c38682d85fc4113964ba_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MDUwMjg2Mg==,size_16,color_FFFFFF,t_70.png


🚩 如果是 release 模式去编译,程序没有死循环:

0ca269fb91d573f9491db7809af48ee0_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MDUwMjg2Mg==,size_16,color_FFFFFF,t_70.png

💡 因为 release 的优化,避免了死循环的发生;


相关文章
|
4月前
|
存储 编译器 C语言
【C语言】VS实⽤调试技巧&(Debug和Release)监视&内存2
【C语言】VS实⽤调试技巧&(Debug和Release)监视&内存
|
4月前
|
程序员 C语言 C++
【C语言】VS实⽤调试技巧&(Debug和Release)监视&内存1
【C语言】VS实⽤调试技巧&(Debug和Release)监视&内存
|
1月前
|
C语言 索引
C语言编译环境中的 调试功能及常见错误提示
这篇文章介绍了C语言编译环境中的调试功能,包括快捷键操作、块操作、查找替换等,并详细分析了编译中常见的错误类型及其解决方法,同时提供了常见错误信息的索引供参考。
|
4月前
|
C语言
C语言使用宏定义实现等级调试输出PRINT_LEVEL
C语言使用宏定义实现等级调试输出PRINT_LEVEL
|
3月前
|
安全 编译器 程序员
【C语言】:VS实用调试技巧和举例详解
【C语言】:VS实用调试技巧和举例详解
28 1
|
3月前
|
存储 编译器 C语言
C语言学习记录——调试技巧(VS2019环境下)
C语言学习记录——调试技巧(VS2019环境下)
42 2
|
3月前
|
程序员 编译器 C语言
C语言中的assert.h:调试助手与断言详解
C语言中的assert.h:调试助手与断言详解
|
4月前
|
程序员 C语言 C++
C语言实用的调试技巧
C语言实用的调试技巧
33 3
|
4月前
|
程序员 编译器 测试技术
C语言初阶⑨(调试)(如何写出好的代码)(模拟实现strcpy和strlen)
C语言初阶⑨(调试)(如何写出好的代码)(模拟实现strcpy和strlen)
37 1
|
4月前
|
NoSQL 编译器 C语言
【C 言专栏】C 语言中的调试技巧与工具
【5月更文挑战第6天】在C语言编程中,调试是必不可少的技能,涉及基本技巧如打印输出、断点调试和单步执行,以及使用GCC、GDB、Visual Studio和Eclipse CDT等工具。高级技巧包括内存检查和性能分析。通过分析问题、设置断点、逐步调试和检查逻辑来解决错误。调试时需保持耐心,合理选用工具,记录过程,并避免过度调试。熟练掌握这些技能将提升代码质量和开发效率。
82 0
【C 言专栏】C 语言中的调试技巧与工具