C语言实用调试详解

目录

什么是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.mzph.cn/news/17288.shtml

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

相关文章

控制反转ioc理解,配置说明

先写个例子吧 配置文件&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"h…

CSS 高频按钮样式

CSS 高频按钮样式 矩形与圆角按钮 正常而言&#xff0c;我们遇到的按钮就这两种 -- 矩形和圆角&#xff1a; 它们非常的简单&#xff0c;宽高和圆角和背景色。 <div classbtn rect>rect</div><div classbtn circle>circle</div>.btn {margin: 8px aut…

【Linux命令200例】rm用来删除文件或目录(谨慎使用)

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;本文已收录于专栏&#xff1a;Linux命令大全。 &#x1f3c6;本专栏我们会通过具体的系统的命令讲解加上鲜…

MongDB文档--架构体系

阿丹&#xff1a; 在开始学习先了解以及目标知识的架构体系。就能事半功倍。 架构体系 MongoDB的架构体系由以下几部分组成&#xff1a; 存储结构&#xff1a;MongoDB采用文档型存储结构&#xff0c;一个数据库包含多个集合&#xff0c;一个集合包含多个文档。存储形式&#…

前端Vue入门-day06-路由进阶

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 路由的封装抽离 声明式导航 导航链接 两个类名 自定义高亮类名 跳转传参 1. 查询参数传参 2. 动态…

Socket 前端项目结构搭建

npm install socket.io-client --savenpm install element-plus --savenpm install vue-router4.0.12 --save简单的页面搭建 聊天系统登录前端实现 登录模板 <template><div class"login-container"><el-form ref"form" :model"fo…

Maven 打包项目后,接口识别中文乱码

背景 项目在Idea里面运行&#xff0c;调用接口发送中文消息正常&#xff0c;用Maven打包项目后&#xff0c;运行jar包&#xff0c;调用接口发送中文出现乱码。 解决方法 1.Idea编译配置 2.如果更改了上述配置之后还是没有效果&#xff0c;则在运行jar包的前面加上 -Dfile.en…

100天精通Python(可视化篇)——第96天:Pyecharts绘制多种炫酷箱形图参数说明+代码实战

文章目录 专栏导读1. 箱形图介绍1&#xff09;箱形图介绍2&#xff09;怎么看箱型图&#xff1f;3&#xff09;解释说明 2. 普通箱型图3. 水平箱型图4. 群组箱型图5. 带异常点的箱型图书籍推荐 专栏导读 &#x1f525;&#x1f525;本文已收录于《100天精通Python从入门到就业…

适配器模式与装饰器模式对比分析:优雅解决软件设计中的复杂性

适配器模式与装饰器模式对比分析&#xff1a;优雅解决软件设计中的复杂性 在软件设计中&#xff0c;我们常常面临着需要将不同接口或类协调工作的情况&#xff0c;同时还要满足灵活性和可扩展性的需求。为了应对这些挑战&#xff0c;适配器模式和装饰器模式应运而生&#xff0c…

IDEA Debug小技巧 添加减少所查看变量、查看不同线程

问题 IDEA的Debug肯定都用过。它下面显示的变量&#xff0c;有什么门道&#xff1f;可以增加变量、查看线程吗&#xff1f; 答案是&#xff1a;可以。 演示代码 代码如下&#xff1a; package cn.itcast.attempt.threadAttempt.attempt2;public class Test {public static …

GFS分布式文件系统

目录 一、GlusterFS简介 二、GlusterFS特点 1.扩展性和高性能 2.高可用性 3.全局统一命名空间 4.弹性卷管理 5.基于标准协议 三、GlusterFS 术语 1.Brick&#xff08;存储块&#xff09; 2.Volume&#xff08;逻辑卷&#xff09; 3.FUSE 4.VFS 5.Glusterd&#xf…

day48-ajax+SSM分页

AjaxSSM分页 非分页版controller及html&#xff1a; 分页模糊查询controller&#xff1a; Postman测试&#xff08;无网页&#xff09;&#xff1a; 分页网页&#xff1a; 分页网页中添加模糊查询&#xff1a; 分页网页中实现添加功能&#xff1a; &#xff08;1&am…

RabbitMQ 教程 | 第4章 RabbitMQ 进阶

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 DevO…

【深度学习Week3】ResNet+ResNeXt

ResNetResNeXt 一、ResNetⅠ.视频学习Ⅱ.论文阅读 二、ResNeXtⅠ.视频学习Ⅱ.论文阅读 三、猫狗大战Lenet网络Resnet网络 四、思考题 一、ResNet Ⅰ.视频学习 ResNet在2015年由微软实验室提出&#xff0c;该网络的亮点&#xff1a; 1.超深的网络结构&#xff08;突破1000层&…

b 树和 b+树的理解

项目场景&#xff1a; 图灵奖获得者&#xff08;Niklaus Wirth &#xff09;说过&#xff1a; 程序 数据结构 算法&#xff0c; 也就说我们无时无刻 都在和数据结构打交道。 只是作为 Java 开发&#xff0c;由于技术体系的成熟度较高&#xff0c;使得大部分人认为&#xff1…

留存测试数据,Apipost接口用例详解

接口用例可以在不影响源接口数据的情况下对接口添加多个用例&#xff0c;方便测试并保存测试数据。 创建用例 左侧目录选择接口后进入接口用例页面&#xff0c;点击添加用例 在弹出窗口中修改各种参数。如登录接口&#xff0c;可修改用户名为空&#xff0c;并添加断言。 执行…

css滤镜:drop-shadow

一、用法 drop-shadow( offset-x offset-y blur-radius spread-radius color ) offset-x&#xff1a;此参数设置图像的水平偏移。正值将创建右侧的偏移量&#xff0c;负值将创建左侧的偏移量。offset-y&#xff1a;此参数设置图像的垂直偏移。正值创建到底部的偏移量&#xff…

简单版本视频播放服务器V4,layui界面

简单版本视频播放服务器V4 前一个版本内容&#xff0c;可以查看 https://blog.csdn.net/wtt234/article/details/131759154 优化内容&#xff1a; 1.返回列表的优化&#xff0c;优化了原来返回空列表名称的问题 2.前端才有layui优化内容 后端&#xff1a; package mainim…

安科瑞AMC200多回路智能电量采集监控装置在隧道中的应用-安科瑞黄安南

1项目背景 河南安阳林州市某高速公路项目是河南省政府主要打造的一项公路建设项目&#xff0c;该项目全长约70公里&#xff0c;起点位于安阳市内&#xff0c;终点位于林州市县。该项目总投资约60亿元人民币&#xff0c;建设工期预计为3年。 该项目的建设旨在缓解当地交通压力…

为高性能计算构建,由亚马逊云科技Amazon Graviton3E驱动的最新实例正式可用

亚马逊云科技宣布两款基于最新一代自研芯片Amazon Graviton3E的新实例Amazon Elastic Compute Cloud&#xff08;Amazon EC2&#xff09;Hpc7g和Amazon EC2 C7gn正式可用。 其中&#xff0c;Hpc7g实例专为计算和网络密集型高性能计算&#xff08;HPC&#xff09;工作负载而构建…