C语言【调试】(个人笔记版)
调试
- 前言
- 一、Bug
- 二、调试工具
- 1.DeBug
- 2.Release
- 三、调试快捷键
- 1、断点
- 四、调试时查看程序的当前信息
- 1、查看临时变量
- 2、查看内存
- 3、查看调用堆栈、汇编、寄存器
- 总结
前言
这篇文章大都是我的个人笔记: 调试在日常程序设计中是很重要的。调试说白了就是为了解决代码的bug问题。但是如何学好调试,成为一名会解决问题的学习者呢?这篇文章我们就来探讨一下调试问题。
一、Bug
平常我们写完代码运行的时候,总会遇到一些出乎你意料的错误。比如,很经典的:
我写完代码啦->运行一下->为什么错误了呢?-这里改改,再运行一下->为什么又错误了呢?->再改改,再运行->这下可以了,但是为什么呢?
以上是不是你的真实写照呢?其实,这种调试的方法叫做迷信式调试,是一种不可取的调试方法,原因也很简单,因为你不知道代码具体哪里有问题,只能靠猜,而且大多数时候,你都不知道改完后正确的代码为什么是这样的。
二、调试工具
1.DeBug
Debug是被称为程序员版本,里面不做任何优化,可以方便程序员检查代码。
(按一下f10就会走一步,并且是一步一步来的)
2.Release
Release版本被称为发布版本,里面进行了各种优化。
(调试的时候就是一步到位)
三、调试快捷键
- F5 — — 启动调试,常用来直接跳到下一个断点处。常以F9配合使用
- F9 — —创建断点和取消断点。(后面我会说明断点点作用)
- F10 — —逐过程。通常用来处理一个过程。一个过程可以是一个函数调用,也可以是一条语句。(一步一步走)
- F11 — —逐语句。每次都执行一个语句,在遇到函数时会进入函数内部。(相对F10会更加细致)
- CTRL F5 — —执行但是不调试,也就是不经历调试而直接执行代码
以上就是常用的快捷键了
1、断点
断点大致意思就是让程序在指定的位置停下。
举个例子
int i = 0;
int arr[10] = {0};
for(i = 0; i < 10; i++){arr[i] = i;
}
for(i = 0; i < 10; i++){printf(“%d”, arr[i]);
}
这里,我们在第二个for循环的地方按一下F9,就会产生一个断点。
正常情况下如果你调试,那么程序就会先进入到第一个循环,然后你按一下键盘他就执行一次。不过你知道第一个循环里的内容是没有问题的,你想去第二个循环的地方进行调试。但是程序要到第二个循环的话就需要先把第一个循环跑完,这就会很繁琐。
有了断点后,程序就会一次跑完断点之前所有的代码,在断点处停下,这样一来,你就可以继续进行你的调试了。
如果还没理解为什么这样的话,我就再举个例子:
现在假设你有5000行代码,你完全不知道代码哪里出了问题,你就得一次一次一行一行一直慢慢调试下去。这样下来,手都要先按断掉了。有了断点,你就可以在你所知道的没有问题的代码前设置断点,跳过这些代码。大大提高你的效率。
不过要注意的是,当出现两个断点时,并不是按一下F5就会跳到下一个断点处。按F5时,他会跳到一个**“逻辑断点”。**
意思是,如果断点假设在第一个循环中,并且我第二个循环的开始(不在循环体内)也设置了一个断点。那么第一次F5是进到第一个断点没错,但是我再按一次F5就不是跳到第二个断点了,而是在第一个循环中在来一次。
四、调试时查看程序的当前信息
1、查看临时变量
int a = 0;
int b = 100;
int c = 200;
printf(“%d”, a);
如果你想看这些临时变量的值时,该怎么办呢?
注意:一定是在启动调试(F10)的时候才能打开
流程:窗口 -> 自动窗口
或:窗口 -> 局部变量
或:窗口 -> 监视 (常用)
这里:
名称这一栏是可以进行输入的,只要输入的合法就可以。
值会显示当前名称的状态
类型顾名思义就是变量的类型了
这里我来说明一下数组在传参时应该怎么查看数组里的内容
我想查看数组arr的成员,那么我只需要在监视窗口内的值这一栏输入arr,4就可以看到前四个值了。
解释一下,因为指针传递的是数组的首元素的地址,所以我输入arr就是查看arr数组的第一个值,同理,我想看四个我就输入arr,4 我想看10个我就输入arr,10。
2、查看内存
创建一个数组并赋予初值,我们可以查看该数组在内存中存放的位置
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
内存窗口比较复杂
首先,我们要把需要看的东西写在地址栏上。
然后这里会有三列,第一列表示地址,第二列表述数据,第三列表示编译器推测的数据信息。
先来看看第一行第二列的数据:
01 00 00 00
再来看看第一列的数据:
0x00 8F FB C8
这俩有什么关联呢?
01 是内存中存储的数据,对应的就是第一列C8的位置,这第一列表示地址,而又因为我们只显示4列。所以01 00 00 00这个数据对应的地址00 8F FB C8+4就是00 8F FB CC。而我们第二行第一列的数据00 8F FB CC末尾处正是CC。所以答案显而易见了,这就是一个连续的地址,数据是存储在连续的内存空间中的
画个图会更好理解:
1.栈区内存的使用习惯是先使用高地址处的空间,再使用低地址处的空间
2.而数组下标的增长地址是由低到高变化的。
所以这里,我们的数据 1 的地址往上+4个字节就是数据 2 的地址,再往上就以此类推。
当然这里还可以补充堆与栈的知识。但是这部分知识与调试无关,我会在下次的文章中详细讲解一下堆栈。
3、查看调用堆栈、汇编、寄存器
这部分用的较少,但是调试窗口是可以查看的
总结
这篇文章全然是我自己的笔记,但是也可以方便大家快速理解一些调试中的术语的解释。好啦,这篇文章先到这里,如果有补充我会重新编辑,那么,下篇文章见!
相关文章:

C语言【调试】(个人笔记版)
调试 前言一、Bug二、调试工具1.DeBug2.Release 三、调试快捷键1、断点 四、调试时查看程序的当前信息1、查看临时变量2、查看内存3、查看调用堆栈、汇编、寄存器 总结 前言 这篇文章大都是我的个人笔记: 调试在日常程序设计中是很重要的。调试说白了就是为了解决代…...

连锁收银系统
商淘云连锁管理系统助力连锁企业实现“人货账”全方位数字化管理,它依托连锁品牌进销存管理实现门店订货、线下收银、线上商城、会员营销等一体化管理。 门店订货补货支持连锁直营、加盟 不同门店不同进货价、不同门店不同商品、不同门店在线或者账期支付、门店PC或…...
5.2024.10.21
2024.10.21 学习和复习 学习QT的流程控制、函数、内联函数复习C语言printf练习 问题及解决方案 C学到函数之后有些吃力代码逻辑能力不大行,需要巩固一下C语言基础再挤多点时间去学习嵌入式写代码前先把大概思路写出来 碎碎念 最近作业比较多,有点静不下…...
前端Socket互动小游戏开发体验分享
随着实时网络通信技术的不断发展,基于WebSocket的前端互动小游戏成为了一种非常流行的选择。WebSocket允许客户端和服务器之间进行双向通信,为游戏互动带来了更快的响应时间和更流畅的体验。本文将通过一个简单的互动小游戏来探讨前端如何利用WebSocket技…...
react项目,通过自定义 separator 属性来修改日期选择器中间的分隔符:
1. 引入必要的依赖 确保你已经引入了 DatePicker 组件和 moment 库。 import React, { Component } from react; import { DatePicker } from antd; import moment from moment; const { RangePicker } DatePicker; const dateFormat "YYYY/MM/DD"; 2. 定义父组…...

双十一有啥好用的家居好物推荐?2024性价比高的超声波清洗机推荐
双十一今天晚上就可以越热开抢了,还不知道购买什么物品的小伙伴们赶紧来看看我这篇文章,在众多家居好物中,超声波清洗机以其高效、便捷的特点,成为了许多家庭的必备神器。2024年,市场上涌现出了不少性价比超高的产品&a…...

比亚迪车机安装第三方应用教程
比亚迪车机安装第三方应用教程 比亚迪车机U盘安装APP, 无论是dlink3.0还是4.0都是安卓系统,因此理论上安卓应用是都可以安装的,主要就是横屏和竖屏的区别。在比亚迪上安装软件我主要推荐两种方法。 第一种,直接从电脑端下载安装布…...

移动零---双指针法
目录 一:题目 二:算法原理讲解 三:代码编写 一:题目 题目链接:https://leetcode.cn/problems/move-zeroes/description/ 二:算法原理讲解 三:代码编写 void moveZeroes2(vector<int>& nums) {for (int d…...

MoeCTF 2024 ---Misc方向WP
安全杂项 signin 题目描述: xdsec的小伙伴们和参赛者来上课,碰巧这一天签到系统坏了,作为老师的你,要帮他们 教师代签。 特殊提醒:luo同学今天好像在宿舍打游戏,不想来上课,这是严重的缺勤行为…...

【我的 RT 学习手札】信息收集
相关笔记整理自B站up主泷羽sec全栈渗透测试教学(免费) 视频链接为泷羽sec的个人空间-泷羽sec个人主页-哔哩哔哩视频 笔记只是方便师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线࿰…...
CMake变量:CMAKE_FIND_LIBRARY_SUFFIXES
CMAKE_FIND_LIBRARY_SUFFIXES是CMake中的一个变量,用于指定在查找库文件时使用的后缀列表。当CMake需要找到库文件时,它会尝试在这些后缀后添加库名来构建库文件的完整路径。例如,如果库名为mylib,并且CMAKE_FIND_LIBRARY_SUFFIXE…...

在使用 RabbitMQ 作为消息代理时,多个 Celery 实例(或应用)可以共享同一个 RabbitMQ 实例
在使用 RabbitMQ 作为消息代理时,多个 Celery 实例(或应用)可以共享同一个 RabbitMQ 实例。这样做可以简化基础设施管理,同时允许不同的 Celery 应用之间进行消息传递和协作。下面是如何配置多个 Celery 实例以使用同一个 RabbitM…...
ARM在嵌入式开发中的作用有哪些?
ARM在嵌入式开发中的作用主要体现在以下几个方面: 架构优势: ARM架构基于RISC(精简指令集计算机),具有精简而高效的指令集,适合资源受限的环境。低功耗设计使得ARM处理器在移动设备和嵌入式系统中非常受欢…...

-webkit-box-orient属性丢失?
在实际项目场景当中,我们经常会遇到需要对超长文本溢出省略的场景: 我们经常会这样写—— 单行省略: overflow: hidden; //文本溢出隐藏text-overflow: ellipsis; //文本溢出显示省略号white-space: nowrap; //不换行 多行省略:…...

openKylin系统SSH服务配置结合cpolar轻松实现开放麒麟远程连接
前言 本文主要介绍如何在openKlyin系统中设置ssh连接,并结合cpolar内网穿透工具实现远程也可以ssh连接本地局域网内部署的openKlyin系统. openKylin是中国首个基于Linux 的桌面操作系统开发者平台,通过开放操作系统源代码的方式,打造具有自…...

我的世界之合成
合成(Crafting)是一种在Minecraft中获得多种方块、工具和其他资源的方法。合成时,玩家必须先把物品从物品栏移入合成方格中。22的简易合成方格可以直接在物品栏中找到,而33的合成方格需要使用工作台或合成器来打开。 目录 1合成系…...

java基于SpringBoot+Vue+uniapp微信小程序的自助点餐系统的详细设计和实现(源码+lw+部署文档+讲解等)
项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念,提供了一套默认的配置,让开发者可以更专注于业务逻辑而不是配置文件。Spring Boot 通过自动化配置和约…...
AI 编译器学习笔记之八 -- Python基础学习
2、正则表达式 re.sub 正则替换:cleaned_text re.sub(r"[^\w\s]", "", text) - CSDN文库 3、在Python中,shape 是一个用于描述数组维度的属性,通常用在NumPy数组对象上,而不是标准的列表。 【Python】解决Py…...

盘点近几年腾讯的精选面试题(c/c++研发岗)
map插入方式有几种? 1)用insert函数插入pair数据, mapStudent.insert(pair<int, string>(1, “student_one”)); 2)用insert函数插入value_type数据 mapStudent.insert(map<int, string>::value_type (1, “student_one”)); 3)在insert函…...
C++详细笔记(四)
1.类和对象 1.1拷贝构造函数(补充) class Date{ public:int _year;int _month;int _day; // 全缺省的构造函数Date(int year 1900, int month 1, int day 1){_year year;_month month;_day day;} } int main() {Date d1(2024, 4, 14);Date d2(d1…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...

【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...