VS调试技巧

                    Hi~!这里是奋斗的小羊,很荣幸各位能阅读我的文章,诚请评论指点,关注+收藏,欢迎欢迎~~     

                        💥个人主页:小羊在奋斗

                        💥所属专栏:C语言   

        本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为同样是初学者的学友展示一些我的学习过程及心得。文笔、排版拙劣,望见谅。

                                1、调试

                                2、Debug 和 Release

                                3、VS调试快捷键

                                4、监视和内存观察

                ​​​​​​​        ​​​​​​​        5、调试举例

                ​​​​​​​        ​​​​​​​        6、编程常见错误

1、调试

        当我们发现写的程序中存在问题(bug)的时候,接下来就要找到问题并修复,这个过程就叫调试(debug)。调试一个程序,首先要承认出现了问题,然后通过手段定位问题的位置,可以是逐过程的调试,也可以屏蔽部分代码等,找到问题所在的位置,然后确定产生问题的原因,再修改代码重新测试。

        调试是一个强大的功能,有时候我们百思不得其解的问题,通过调试就能一目了然,很快的找出问题所在。另外,有些问题就算我们想破脑袋都想不出个所以然来,只能通过调试来知道其内部原因。

2、Debug 和 Release

        

        在VS上,能看到有 Debug 和 Release 两个选项,分别是什么意思呢?

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

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

3、VS调试快捷键

        在VS中,有很多的调试快捷键便于程序员调试代码,很大提高了调试效率。

        3.1环境准备

        首先,我们得设在 Debug 环境下。

        3.2调试快捷键

        F9:创建断点和取消断点;

        断点的作用是:在程序的任意位置设置断点使得程序执行到想要的位置暂停执行,再使用F10和F11快捷键观察代码的执行细节;

        条件断点:断点还可以设置条件,满足这个条件才会出发断点;

        F5:启动调试,经常用来直接跳到下一个断点处,一般是和F9配合使用;

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

        F11:逐语句,就是每次都只执行一条语句,在函数调用的地方可以进入函数内部;

        CTRL + F5: 开始执行不调试。

4、监视和内存观察

​​​​​​​        我们在调试的过程中,如果想要观察代码执行过程中变量值的变化,有哪些办法呢?这些观察的前提条件是在开始调试后观察。

        4.1监视

        

 

        开始调试后,在菜单栏中【调试】—> 【窗口】—> 【监视】,打开任意一个监视窗口,输入想要观察的对象即可,加上取地址符还可以看到地址。 

        4.2内存

        如果监视窗口看的不够仔细,还可以观察变量在内存中的存储情况,还是在【调试】—> 【窗口】—> 【内存】打开内存窗口:

         

5、调试举例

        5.1示例一

         在VS2022、x86、Debug 环境下,执行下面代码,结果会是什么呢?

        我们可以看到,数组是越界非法访问的,那么这一小段代码的执行结果是打印10个“加油”呢?还是13个“加油”呢?还是其他不可预测的结果? 

                                                                                                                         

        事实上当我们运行起来后屏幕上会一直打印“加油”,好像跟我们的猜测有很大的差别。那么为什么会发生这样的现象呢?像这种情况我们光靠脑子想是想不出来个所以然的,我们需要借助强大的调试功能。

         

        当我们按F10逐过程一直到 i 的值为10的时候,我们把 arr[10]、arr[11]、arr[12] 添加到监视,再按F10(此时已经是非法访问)的时候我们看到,arr[12] 的值一直跟着 i 的值在变化,这是为什么呢?我们把 i 的地址和 arr[12] 的地址添加到监视看一下:

         i 的地址跟 arr[12] 的地址是一样的,所以说 i 跟 arr[12] 是等价的。当我们继续按F10给 arr[12] 赋0值后,i 的值也跟着变为0。如此循环下去,程序就陷入了死循环。

         在之前的文章中我们已经简单了解过内存中的数据存储(数据和变量),我们这里再补充一下。

        (1)局部变量存储在内存中的栈区,而栈区的使用习惯是从高地址向低地址使用的,所以我们先创建的变量 i 的地址是比较大的,arr 数组的地址整体是小于 i 的地址的;

        (2)一维数组中我们知道,数组在内存中的存储规则是:随着下标的增大地址由低到高变化。再结合下面的图我们就能很好的理解。

         当数组 arr 的下标逐渐增大,地址越来越接近变量 i ,当下标为12的时候,arr[12] 就跟变量 i 的地址重合了,这时 arr[12] 就跟变量 i 是一个值,操作 arr[12] 就是操作变量 i 。

        至于为什么 arr 数组和变量 i 之间恰好是2个 int 型的空间,这纯属是巧合,在不同的编译器中两者之间空出来的大小是不一样的。

        注意:栈区的默认使用习惯是先使用高地址再使用低地址,但是这个具体还要看编译器的实现,比如:在VS上切换x64,这个使用的顺序就是相反的,在 Release 版本中,这个使用顺序也是相反的。

        上面的程序是在x64环境下的,我们可以看到 arr[0] 的地址都比变量 i 的地址大。 

                5.2示例二

        看下面的代码:

//【编写一个函数实现n的k次方,使用递归实现。】#include <stdio.h>int fun(int x, int y)
{if (1 == x || 0 == y){return 1;}else if (0 == x && 0 != y){return 0;}else{return x * fun(x, y--);}
}int main()
{int n = 0;int k = 0;scanf("%d %d", &n, &k);int m = fun(n, k);printf("%d\n", m);return 0;
}

        像我一样的新手乍一看可能觉得没什么问题(如果你已经看出了问题所在,还请不要声张),但是运行起来才发现有问题,程序陷入了死循环。我们来调试一下哪里出了问题:

        第一步:F10开始调试;

        第二步:输入我们想要观察的变量;

 

        第三步:通过不断F10来观察变量值的变化,当变量的值与我们想要的不一样的时候,我们就找到了问题所在;

             假如我们要求2的4次方: 

   

         

        当我们不断F10,执行了 return x * fun(x,y--);这条语句后,突然弹出了栈溢出的提示(栈溢出简单说是因为函数调用层级过深引起的,这里我们不作过多介绍,后面会有相关文章),那么问题应该就在这条语句中。

        第四步:在知道问题所在后,就要分析其原因。

        我们的想法是通过让形参 y 的值自减,来实现 x 自乘的次数。但我们知道,y-- 和 --y 确实能实现自减的效果,但两者是有很大区别的(如果你还不知道,罚你去看这篇文章 —> C语言基础),我们改正过来继续调试。

        可以看到,在我们修改了错误后就实现了 y 不断自减的效果,现在我们写的程序就能执行我们想要的任务了。 

        总结:通过上面两个示例,只是想告诉大家调试是一个很强大的功能,就算是编程高手也不见得总是一次就能写成正确的代码,在不断地修改中才能解决所有的问题,而调试无疑是最好的助手。作为程序员,不使用调试或不会调试是万万不可的。同时,调试还可以让开发者深入了解程序的运行机制,提高编程技能和经验。

6、编程常见错误

        6.1编译型错误        

        编译型错误一般是语法错误,这类错误一般看错误信息就能找到一些蛛丝马迹,双击错误信息也能初步跳转到代码错误的地方或附近。编译型错误,随着语句的熟练,会越来越少,也容易解决。例如缺少分号、使用未定义的变量等:

         6.2链接型错误

        看错误提示信息,主要在代码中找到错误信息中的标识符,然后定位问题所在。一般是因为标识符名不存在、拼写错误、头文件没包含、引用的库不存在等。

         6.3运行时错误

        运行时错误,是千变万化的,也是最难解决最令我们头疼的,需要借助调试,逐步定位问题。调试解决的是运行时问题,也就是说调试的前提是你的程序得先能运行起来,没有简单的语法和链接错误,然后才能调试。

                                   点击跳转主页—> 💥个人主页小羊在奋斗

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

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

相关文章

GaN HEMT中短沟道效应的建模

来源&#xff1a;Modeling of Short-Channel Effects in GaN HEMTs&#xff08;TED 20年&#xff09; 摘要 在本文中&#xff0c;我们提出了一种用于估算GaN高电子迁移率晶体管&#xff08;HEMT&#xff09;器件中短沟道效应&#xff08;SCEs&#xff09;的显式和解析的基于电…

node.js egg.js

Egg 是 Node.js 社区广泛使用的框架&#xff0c;简洁且扩展性强&#xff0c;按照固定约定进行开发&#xff0c;低协作成本。 在Egg.js框架中&#xff0c;ctx 是一个非常核心且常用的对象&#xff0c;全称为 Context&#xff0c;它代表了当前 HTTP 请求的上下文。ctx 对象封装了…

Golang内存、指针逃逸、垃圾回收机制概览

最近看到了一篇文章是关于go的内存、指针逃逸和垃圾回收机制的&#xff0c;发现自己并未很细致的了解过这方面的内容&#xff0c;于是在翻阅各种文章的情况下&#xff0c;写出了这篇总结&#xff0c;参考文章放在文末&#xff0c;可自取 内存 Go 语言使用一个自带的垃圾收集器…

YOLOV5 TensorRT部署 BatchedNMS(engine模型推理)(下)

主要是在王新宇代码的基础上改进,引入对BatchedNMS的解码 文章目录 1. 修改yolov5.cpp2.修改yololayer.h1. 修改yolov5.cpp 首先增加全局变量,名字根据转onnx时修改的节点名字来,查看onnx文件可以看到,顺序不要弄错。 const char *INPUT_NAME = “images”; const char …

Aigtek:介电弹性体高压放大器在软体机器人研究中的应用

近年来软体机器人的研究成为目前机器人研究领域的热点&#xff0c;由于软体材料的自由度可以根据需求自由变化&#xff0c;因此软体机器人有着极高的灵活性&#xff0c;而且软体机器人因其材料的柔软性有着很好的人机交互性能和安全性。它的出现成功解决了传统的刚性机器人人机…

ArcGIS Pro专题地图系列教程

专题地图系列是ArcGIS Pro3.2的新功能。之前&#xff0c;如果要做8张相同区域的专题图&#xff0c;可能需要新建8个布局&#xff0c;分别进行排版&#xff0c;再导出。现在&#xff0c;一幅地图&#xff0c;一个布局&#xff0c;就可以完成这个流程。 原理是&#xff0c;根据单…

AI预测福彩3D第9套算法实战化测试第4弹2024年4月26日第4次测试

今天继续进行新算法的测试&#xff0c;今天是第4次测试。好了&#xff0c;废话不多说了&#xff0c;直接上图上结果。 2024年4月26日福彩3D预测结果 6码定位方案如下&#xff1a; 百位&#xff1a;4、5、7、8、3、9 十位&#xff1a;6、9、5、4、1、2 个位&#xff1a;7、8、5、…

PostgreSql-Install

PostgreSql源码安装 一、源代码下载二、操作系统配置三、编译安装四、启动数据库五、相关命令 PostgreSQL是一个强大的 开源对象关系数据库系统&#xff0c;它使用并扩展了SQL语言&#xff0c;并结合了许多功能&#xff0c;可以安全地存储和扩展最复杂的数据工作负载。 一、源…

npm install 卡在still idealTree buildDeps不动

前言 再使用npm install 安装包依赖时 发现一直卡住 停留在 观察node_cache下的_logs文件 发现一直在拉取包 37 silly idealTree buildDeps 38 silly fetch manifest riophae/vue-treeselect0.4.0尝试解决 尝试设置了taobao镜像源 依然如此 获取已经设置的镜像源 确实是ta…

高级数据结构—线段树(一)

学线段树的原因是因为cf的一道题目始终想不出来怎么优化&#xff0c;后来知道区间查询和修改要用到线段树。。。 原题&#xff1a;Iva & Pav 线段树的作用 区间最值查询&#xff1a;可以高效地找到给定区间内的最大值、最小值等。 区间和查询&#xff1a;可以高效地计算…

关于MCU核心板的一些常见问题

BGA植球与焊接&#xff08;多涂焊油&#xff09;&#xff1a; 【BGA芯片是真麻烦&#xff0c;主要是植锡珠太麻烦了&#xff0c;拆一次就得重新植】https://www.bilibili.com/video/BV1vW4y1w7oNvd_source3cc3c07b09206097d0d8b0aefdf07958 / NC电容一般有两种含义&#xff1…

Python爱心代码

爱心效果图&#xff1a; 完整代码&#xff1a; import random from math import sin, cos, pi, log from tkinter import *# 定义画布尺寸和颜色 CANVAS_WIDTH 640 CANVAS_HEIGHT 480 CANVAS_CENTER_X CANVAS_WIDTH / 2 CANVAS_CENTER_Y CANVAS_HEIGHT / 2 IMAGE_ENLARG…

AI容器化部署开发尝试 (一)(Pycharm连接docker,并部署django测试)

目标&#xff1a;使用容器化技术快速部署AI应用进行开发。 注意&#xff1a;从 Docker 19.03 开始&#xff0c;Docker 引入了对 NVIDIA GPU 的原生支持&#xff0c;因此若AI要调用GPU算力的话docker版本也是有要求的&#xff0c;后面博客测试。 当然本篇博客还没设计到GPU的调…

微服务两种方式登录

目录 1.restTemplate方式 1.1页面 1.2消费者 1.3生产者 1.4效果 2.Feign方式 2.1Service 2.2生产者 三个生产者 一个消费者&#xff0c;三个生产者需要用mysqlmybatis 三个不同的数据库。 页面输入用户名和密码&#xff0c;提交到后端消费者&#xff0c;消费者传到生产…

vLLM-prefix浅析(System Prompt,大模型推理加速)

原文&#xff1a;vLLM-prefix浅析&#xff08;System Prompt&#xff0c;大模型推理加速&#xff09; 简介 本文浅析了在大模型推理加速方面一个非常优秀的项目 vLLM 的一个新特性 Prefix。在 Prompt 中有相同前缀时可以提高吞吐量降低延迟&#xff0c;换句话说可以省去这部分…

【C++】:构造函数和析构函数

目录 前言一&#xff0c;构造函数1.1 什么是构造函数1.2 构造函数的特性1.3 总结 二&#xff0c;析构函数2.1 什么是析构函数2.2 析构函数的特性2.3 总结 前言 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何…

JVM学习笔记(五)内存模型

目录 1、原子性 1.1 问题分析 1.2 解决方法 2、可见性 2.1 退不出的循环 2.2 解决办法 3、有序性 3.1 诡异的结果 3.2 解决办法 3.3 有序性理解 3.4 happens-before 4、CAS与原子类 4.1 CAS 4.2 乐观锁与悲观锁 4.3 原子操作类 5、synchronized 优化 5.1 轻量…

华为认证云计算前景如何

互联网/移动互联网经历了高速发展的二十年&#xff0c;我们有幸一起见证了华为、阿里、腾讯、百度、字节跳动、京东、滴滴、拼多多等互联网公司的崛起&#xff0c;让普通技术人实现逆袭拿到高薪&#xff0c;也让小镇做题家们有了阶层跨越的机会。 但机会都是留给有准备的人&…

记录一个hive中因没启yarn导致的spark引擎跑insert语句的报错

【背景说明】 刚在hive中配置了Spark引擎&#xff0c;在进行Hive on Spark测试时报错&#xff0c; 报错截图如下&#xff1a; [atguiguhadoop102 conf]$ hive which: no hbase in (/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/opt/module/jdk1.8.0_212/bin:/opt/mod…

分享三个转换速度快、准确率高的视频转文字工具

想要直接将视频转换成文字&#xff0c;转换工具很重要&#xff01;给大家分享三个转换速度快、准确率高的视频转文字工具&#xff0c;轻松完成转换。 1.网易见外 https://sight.youdao.com/ 网易家的智能转写翻译服务工作站&#xff0c;网页端就可以直接使用&#xff0c;支持视…