C语言实用调试详解

news2024/12/30 2:54:47

目录

什么是bug?

调试是什么?有多重要?

调试是什么?

调试的基本步骤

Debug和Release的介绍

Windows环境调试介绍 

调试环境的准备

学会快捷键

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

查看临时变量的值

查看内存信息 

 查看调用堆栈

 查看汇编信息

查看寄存器信息 

一些调试的实例 

实例一

实例二


什么是bug?

在计算机编程中,"bug"(中文通常翻译为"错误"或"缺陷")是指程序中存在的错误或问题。

当程序无法按照预期的方式工作时,我们就可以说程序中出现了 bug。

调试是什么?有多重要?

调试是什么?

调试(Debugging)是指在软件开发过程中识别、定位和解决程序中的错误或缺陷的过程。调试是一种通过逐步执行代码、观察和分析程序行为来找出程序中的问题的方法。

在软件开发中,调试是一个非常重要的环节,它允许开发人员检查和修复错误,以确保程序的正确性和稳定性。调试工具通常提供了以下功能来帮助开发人员进行调试:

  1. 断点(Breakpoints):在代码中设置断点,程序执行到断点处时会暂停,开发人员可以查看变量值、执行状态等信息。

  2. 单步执行(Step Execution):逐行执行程序,观察每一步的结果,以便定位错误。

  3. 变量监视(Variable Watch):监视变量的值并及时更新,以便观察变量在不同执行阶段的变化。

  4. 栈追踪(Stack Trace):跟踪函数调用的层次和顺序,以便了解程序的执行流程。

  5. 日志输出(Logging):将程序运行时的信息输出到日志文件中。

调试的基本步骤

发现程序错误的存在

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

确定错误产生的原因

提出纠正错误的解决办法

对程序错误予以改正,重新测试

Debug和Release的介绍

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

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

 需求 ——> 设计和开发 ——> 测试 ——> 产生验收 ——> 发布

  1. Debug 模式:

    • 主要用于开发和调试阶段。
    • 生成的代码通常包含了调试信息,以便在出现错误时能够更容易地进行调试和定位问题。
    • 编译器会进行更多的优化,以提供更好的调试体验。
    • 生成的可执行文件通常较大,占用更多的内存。
    • 可以使用断言(assertions)来验证代码的正确性。
  2. Release 模式:

    • 主要用于最终发布和部署阶段。
    • 生成的代码通常经过了更多的优化,以提供更好的性能和较小的文件尺寸
    • 调试信息被剥离,使得代码更难以被逆向工程或调试。
    • 通常会关闭断言,以提高执行效率。
    • 生成的可执行文件通常较小,占用较少的内存。

总的来说,Debug 模式主要用于开发和调试阶段,提供更好的调试能力和错误定位;而 Release 模式主要用于最终发布和部署阶段,追求更好的性能和较小的文件尺寸。

Windows环境调试介绍 

注:linux开发环境调试工具是gdb,后期会介绍

调试环境的准备

在环境中选择debug选项,才能使代码正常调试。

学会快捷键

在 Windows 环境下,调试程序时可以使用一些常用的快捷键来提高效率。以下是一些常见的调试快捷键:

  • F5:开始调试(继续执行程序)
  • F9:在当前行设置或取消断点

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

  • F10:逐过程执行,跳过函数内部的调用
  • F11:逐语句执行,进入函数内部的调用
  • Shift + F11:从当前函数返回到调用该函数的地方
  • F12:跳转到函数定义或变量声明处
  • Ctrl + F5:无调试方式运行程序
  • Ctrl + Shift + F5:停止运行程序
  • Ctrl + B:打开或关闭断点窗口
  • Ctrl + Alt + C:显示/隐藏自动窗口
  • Ctrl + Alt + E:显示/隐藏异常窗口
  • Ctrl + Alt + T:显示/隐藏线程窗口
  • Ctrl + Alt + I:显示/隐藏快速监视窗口
  • Ctrl + Alt + D:显示/隐藏内存窗口
  • Ctrl + Alt + L:显示/隐藏本地变量窗口

这些快捷键可以根据不同的集成开发环境(IDE)或调试工具进行配置和扩展。

条件断点(Conditional Breakpoint)是在调试过程中设置的一种断点,它允许程序在满足特定条件时暂停执行。当程序执行到带有条件断点的代码行时,会先计算断点条件,如果条件为真,则程序会暂停执行,允许开发者检查和调试代码。

条件断点在调试复杂的程序时非常有用,可以帮助开发者在特定的条件下追踪代码的执行,以便更好地理解程序的行为和问题所在。

在不同的集成开发环境(IDE)或调试器中,设置条件断点的方法可能会有所不同。一般来说,你可以在设置断点的地方右键单击,并选择设置条件或类似的选项。然后,你可以编写一个表达式作为条件,只有当该表达式的值为真时,程序才会在该断点处暂停。

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

查看临时变量的值

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

调试窗口:

查看内存信息 

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

 

 查看调用堆栈

反应的函数的调用逻辑

调用堆栈(Call Stack)是计算机程序执行过程中用来跟踪函数调用的一种数据结构。它以栈(Stack)的形式组织函数调用的顺序和相关信息

当一个函数被调用时,该函数的相关信息(如返回地址、局部变量等)会被压入堆栈。当函数执行完毕或遇到返回语句时,相关信息会从堆栈中弹出,程序继续执行上一个函数的代码。

调用堆栈的主要作用是为了管理函数的调用顺序局部变量的生命周期。它允许程序在函数调用的过程中进行嵌套调用,并能够正确地返回到调用点。

 查看汇编信息

查看寄存器信息 

在计算机体系结构中,寄存器(register)是位于CPU内部的一种高速存储器,用于存储和处理指令和数据。寄存器在计算机执行指令时起到了至关重要的作用。

不同的计算机体系结构和处理器架构会有不同的寄存器组织和使用方式。以下是一些常见的寄存器类型:

  1. 通用寄存器(General Purpose Registers):用于存放操作数和中间结果,在程序执行过程中可以被任意使用。通常用于存储整数类型数据。

    • 在x86架构中,常见的通用寄存器有EAX、EBX、ECX、EDX等。
    • 在ARM架构中,常见的通用寄存器有R0、R1、R2、R3等。
  2. 程序计数器(Program Counter):也称为指令指针(Instruction Pointer),用于存放当前正在执行的指令的地址。

    • 在x86架构中,程序计数器通常称为EIP(Extended Instruction Pointer)。
    • 在ARM架构中,程序计数器通常称为PC(Program Counter)。
  3. 栈指针(Stack Pointer):用于指向栈顶的地址,用于处理函数调用、局部变量等。

    • 在x86架构中,栈指针通常称为ESP(Extended Stack Pointer)。
    • 在ARM架构中,栈指针通常称为SP(Stack Pointer)。
  4. 状态寄存器(Status Registers):用于存放处理器的状态信息,例如条件码、溢出标志、零标志等。

    • 在x86架构中,常见的状态寄存器有FLAGS寄存器。
    • 在ARM架构中,常见的状态寄存器有CPSR(Current Program Status Register)。

除了上述寄存器外,不同的体系结构还可能包含其他特定功能的寄存器,用于浮点运算、向量计算、特殊功能等。

需要注意的是,具体的寄存器信息和使用方式会根据不同的CPU架构和操作系统而有所差异

一些调试的实例 

实例一

实现代码:求1!+2!+3!+……+n! ;不考虑溢出。

int main() {
int i = 0;
int sum = 0;//保存最终结果 
int n = 0;
int ret = 1;//保存n的阶乘 
scanf("%d", &n); 
for(i=1; i<=n; i++)
{
   int j = 0;
   for(j=1; j<=i; j++)
        {
          ret *= j; 
        }
   sum += ret; 
}
    printf("%d\n", sum);
    return 0; 
}

这时候我们如果3,期待输出9,但实际输出的是15。 why?

这里我们就得找我们问题

最后发现是ret值的问题 (在每次循环前初始化值)

实例二

#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; 
}

这时候死循环打印hehe

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

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

相关文章

HCIP 重发布+路由策略总结

重发布 在同一个网络拓结构中&#xff0c;如果存在多种不同的路由协议&#xff0c;由于不同路由协议的机制各有不同&#xff0c;对路由的处理也不相同&#xff0c;这就在网络中造成了路由信息的隔离&#xff0c;在路由器的边界路由器上&#xff0c;将某种路由协议的路由信息引…

[网络工程师]-网络规划与设计-网络故障分析与处理

网络环境越复杂,发生故障的可能性越大,引发故障的原因也就越难确定。网络故障往往具有特定的故障现象。这些现象可能比较笼统,也可能比较特殊。利用特定的故障排查工具及技巧,在具体的网络环境下观察故障现象,细致分析,最终必然可以查出一个或多个引发故障的原因。一旦能…

gitlab上传代码

输入 git clone https地址&#xff0c;此地址可以在&#xff0c;gitlab项目上拷贝到本地&#xff0c;看本地电脑会出现在gitlab上新建的项目&#xff0c;并进入该目录下 将要上传的代码拷贝到该目录 依次输入一下代码 git init &#xff08;用于在目录中创建新的 Git 仓库。…

打造独一无二的花店小程序,轻松搭建步骤详解

随着移动互联网的快速发展&#xff0c;花店也开始意识到拥有一个专属的小程序能够提升用户体验、增加销售额。那么&#xff0c;如何快速搭建一个漂亮、实用的花店小程序呢&#xff1f;下面就为大家介绍一下具体的步骤。 第一步&#xff0c;使用第三方制作平台。如乔拓云网是一个…

setEagerlyType字段理解

官方文档介绍&#xff1a;V5.0.4版本开始一对一关联预载入支持两种方式&#xff1a;JOIN方式&#xff08;一次查询&#xff09;和IN方式&#xff08;两次查询&#xff09;&#xff0c;如果要使用IN方式关联预载入&#xff0c;在关联定义方法中添加。 这句话的意思是jion方式关联…

阿里云服务器免费试用及搭建WordPress网站

文章目录 前言一、免费试用1、选择使用产品2、进行产品配置3、远程连接阿里云服务器①、重置实例密码②、SecureCRT 远程链接③、Workbench 远程链接二、搭建 WordPress 网站1、开放搭建 WordPress 需要的端口2、搭建 LAMP 环境①、Linux 系统升级和更新源②、安装 Apache2③、…

【Excel】记录Match和Index函数的用法

最近一直用到的两个处理EXCEL表格数据的函数向大家介绍一下&#xff0c;写这篇博文的目的也是为了记录免得自己忘记了&#xff0c;嘻嘻。 先上百度的链接 Match函数的用法介绍&#xff1a;https://jingyan.baidu.com/article/2fb0ba40b4933941f3ec5f71.html 小结&#xff1a;…

Java从入门到精通(二)· 基本语法

Java从入门到精通&#xff08;二&#xff09; 基本语法 一 变量 1.字面量 计算机是用来处理数据的&#xff0c;字面量就是告诉程序员&#xff1a;数据在程序中的书写格式。 特殊的字符&#xff1a; \n 表示换行&#xff0c; \t 表示一个制表符&#xff0c;即一个tab 2.变量…

【JVM】什么是双亲委派机制

文章目录 1、类加载机制2、双亲委派模型2.1、介绍2.2、为什么需要双亲委派2.3、源码解析 3、破坏双亲委派3.1、介绍3.2、破坏实现3.3、破坏双亲委派的例子 4、线程上下文类加载器 1、类加载机制 类加载阶段分为加载、连接、初始化三个阶段&#xff0c;而加载阶段需要通过类的全…

【Ansible】Ansible自动化运维工具之playbook剧本搭建LNMP架构

LNMP 一、playbooks 分布式部署 LNMP1. 环境配置2. 安装 ansble3. 安装 nginx3.1 准备 nginx 相关文件3.2 编写 lnmp.yaml 的 nginx 部分3.3 测试 nginx4. 安装 mysql4.1 准备 mysql 相关文件4.2 编写 lnmp.yaml 的 mysql 部分4.3 测试 mysql5. 安装 php5.1 编写 lnmp.yaml 的 …

健身时戴什么耳机比较好、健身用的运动耳机推荐

运动健身已经成为一种潮流&#xff0c;有的人为了追求马甲线和八大块腹肌&#xff0c;还有的人为了缓解学习和工作的压力。但你在运动健身的时候难免会有烦躁、疲惫的时候&#xff0c;如果这时有音乐的加入那就完美了&#xff0c;因为美妙的歌声能冲淡这种疲惫感&#xff0c;让…

面向金融科技方向选手!一级学会背书,AI选股与可视分析大赛来啦

金融量化领域邂逅人工智能&#xff0c;将会迸发出怎样的火花&#xff1f; 在深度学习、强化学习和自然语言处理等技术取得不断突破和创新的今天&#xff0c;AI如何赋能量化投资领域&#xff0c;助力开发者打造表现优异&#xff0c;更加安全可靠的量化模型&#xff1f; 第四届CS…

回收站清空的文件怎么恢复?文件恢复,就靠这3个方法!

“不小心把回收站清空了怎么办&#xff1f;之前在回收站里的文件还能恢复吗&#xff1f;诚心发问&#xff0c;希望大家给我出出主意。” 文件被删除之后通常在电脑的回收站中还可以还原。但实际使用电脑时&#xff0c;很多朋友为了释放电脑内存&#xff0c;都会有定期清空回收站…

【Redis】内存数据库 Redis 进阶

目录 分布式缓存 RedisRedis 持久化RDB (Redis DataBase)RDB执行时机RDB启动方式——save指令save指令相关配置save指令工作原理save配置自动执行 RDB启动方式——bgsave指令bgsave指令相关配置bgsave指令工作原理 RDB三种启动方式对比RDB特殊启动形式RDB优点与缺点 AOF (Appen…

租赁固定资产管理

智能租赁资产管理系统可以为企业单位提供RFID资产管理系统。移动APP资产管理&#xff0c;准确总结易损耗品和固定资金&#xff0c;从入库到仓库库存实时跟踪&#xff0c;控制出库和入库的全过程。同时&#xff0c;备件和耗材与所属资产设备有关&#xff0c;便于备件的申请和管理…

指针进阶详解续---C语言

❤博主CSDN:啊苏要学习 ▶专栏分类&#xff1a;C语言◀ C语言的学习&#xff0c;是为我们今后学习其它语言打好基础&#xff0c;C生万物&#xff01; 开始我们的C语言之旅吧&#xff01;✈ 目录 前言&#xff1a; 一.函数指针数组 二.指向函数指针数组的指针 三.回调函数 …

3D WEB轻量化渲染引擎Communicator发布冲突检测库!增加客户端和服务器端冲突检测功能

​HOOPS Communicator是Tech Soft 3D旗下的主流产品之一&#xff0c;具有强大的、专用的高性能图形内核&#xff0c;专注于基于Web的高级3D工程应用程序。其由HOOPS Server和HOOPS Web Viewer两大部分组成&#xff0c;提供了HOOPS Convertrer、Data Authoring的模型转换和编辑工…

【Java练习题汇总】《第一行代码JAVA》综合测试二,汇总Java练习题

Java练习题 综合测试二 1️⃣ 综合测试二 1️⃣ 综合测试二 下面( )不属于面向对象的特点。 A. 封装 B. 转型 C. 继承 D. 多态 下面关于类与对象的描述正确的是( )。 A. 任何情况下必须先有类再有对象&#xff0c;对象只能够调用类中定义的方法&#xff0c;不能够调用属性 B.…

大家知道AI智能绘画是什么吗?我将为你解答

最近&#xff0c;我经常看到朋友在朋友圈上一直发美女图&#xff0c;我在想“这小子现在怎么回事&#xff0c;天天发女孩子的图片”。 便去询问了一下&#xff0c;他却笑着对我说&#xff1b;“这些都不是真人&#xff0c;是我ai智能绘画出图的”。 顿时&#xff0c;我就有点懵…

详细谈谈AIO、BIO、NIO 的区别

目录 一、什么是AIO 二、什么是BIO 三、什么是NIO 四、NIO 在 Netty 中的使用 一、什么是AIO AIO&#xff08;Asynchronous I/O&#xff0c;异步输入输出&#xff09;是一种处理输入输出的编程模型&#xff0c;它允许同时处理多个输入输出操作&#xff0c;而不需要等待每个…