Visual Studio 的调试(一)

最近事儿很多昂,更新速度相较以往慢了许多,备考六月份的四级,还有学校的期末等等,事儿真的太多啦,所以后面的更新速度也会放慢一点,实在是抽不开身啊诸位,相当抱歉,还望诸君见谅

言归正传,咱们今天来聊一聊有关VS的调试技巧。调试是相当重要的一点,熟练地运用调试可以帮助我们自身检验代码的可行性,并快速地找出问题所在

一 . Bug

不知道大家第一次认识bug是什么时候昂,我第一次听到这个词还是在小学看陈子豪打CF说的,这也算是他的一个口头禅吧,当时我就只知道bug就是一种类似程序意料之外的漏洞的意思

什么是bug呢?其英文的本意是指“ 虫子 ”,“ 昆虫 ”,而在现在的网络中逐渐被演变成了在我们的电脑系统或程序中,隐藏着一些未被发现的问题,也就是“ 缺陷 ”,“ 漏洞 ”的意思

那么这个时候就有小伙伴要问了,这一演变从何而来呢?Good question!查资料可得:

“Bug” 的创始人是 格蕾丝·赫柏 (Grace Murray Hopper),她是一位为美国海军工作的电脑专家,在1947年9月9日,格蕾丝·赫柏对 Harvard Mark II设置好17000个继电器进行编程后,技术人员正在进行整机运行时,它突然停止了工作。于是他们爬上去找原因,发现这台巨⼤的计算机内部⼀组继电器的触点之间有一只飞蛾,这显然是由于飞蛾受光和热的吸引,飞到了触点上,然后被高电压击死。所以在报告中,赫柏用胶条贴上飞蛾,并把 “ bug ”来表示“ 一个在电脑程序里的错误 ” ,从此以后,“ Bug ”这个说法就一直沿用至今

历史上的第一个“ bug ”(图源网络) 

 

二 . Debug 和 Release

Debug就是我们常说的调试,顾名思义调试也就是我们找程序漏洞的一个过程,Debug也就是消灭bug的意思。大家调试一个程序,我们首先是要承认出现了问题,然后我们通过一些手段去定位到问题,可以是逐过程的调试,也可以是隔离和屏蔽代码的方式,当我们找到问题的所在,再确定了问题产生的原因,我们就可以去修复代码了

之前我们就有提到过,在VS中,我们可以选择不同的编译环境,如:Debug 和 Release

Debug 称为调试版本 :它 包含调试信息,并且不作任何优化 ,便于程序员调试程序; 程序员在写代码的时候,需要经常性的调试代码,就将这里设置为 debug ,这样编译产生的是debug 版本的可执行程序,其中包含调试信息,是可以直接调试的
Release 称为发布版本 :它往往是 进行了各种优化,使得程序在代码大小和运行速度上都是最优的 ,以便用户很好地使用。当程序员写完代码,测试员再对程序进行测试,直到程序的质量符合交付给用户使用的标准,这个时候就会设置为 release ,编译产生的就是 release 版本  的可执行程序, 这个版本是用户使用的,所以无需包含调试信息等 (如果大家感兴趣的话,可以试着将一个文件分别用 Debug 和 Release保存,我们会发现 Debug版本的所占内存会大一些,这就是因为Debug版本包含了调试信息等

 

三 . VS的调试快捷键

在VS中有着各式各样的快捷键,我这里给大家列举几个常用的、有代表性的:

F10:逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句
F11:逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部
在函数调用的地方,想进入函数观察细节,必须使用F11,如果使用F10,直接完成函数调用
F9:创建断点和取消断点
断点的作用 :可以在程序的任意位置设置断点,打上断点就可以使得程序执行到想要的位置暂停执执行,接下来我们就可以使用F10,F11这些快捷键,观察代码的执行细节
条件断点 :满足这个条件,才触发断点
F5:启动调试,经常用来直接跳到下一个断点处,一般是和F9配合使用
CTRL + F5:开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用
(一般我们运行代码都用这个快捷键)
VS更多快捷键了解:http://blog.csdn.net/mrlisky/article/details/72622009

四 . 监视和内存观察

在我们开始调试后,在菜单栏中,调试——>窗口——>监视,我们任意打开一个监视窗口,输入我们想要监视的对象,如:

在监视窗口中观察各项数据:

我们按F10,输入想要监视的对象,然后我们再按一次F10,即可进行到下一条语句,以此类推,直到程序结束跳出

 若是大家觉得我们在监视窗口中观察的还不够细致时,我们可以进入内存中去观察变量在内存中的储存情况,如:

在我们的内存窗口中就可以观察到:

在这里的自动的选项我们可以设置一行显示几列(我们一般会设置为4列):

除此之外,在我们的调试的窗口中还有:自动窗口,局部变量,反汇编、寄存器等窗口,我这里就不一 一为大家赘述, 诸君感兴趣的话可以自行去搜集影视资料学习。

 五 . 有关调试的举例

为了让大家加深对调试概念的理解,咱们在这里用一个经典例题练练手:

大家可以试着想想运行结果是什么?

这个程序运行起来很显然是会死循环的,这一点相信诸君都能看得出来,这题的关键是我们怎么去理解它为什么死循环,用官方的话术解释清楚问题的根本

当我们调试运行到第十个 hehe 的时候还一切正常,但当我们继续的时候,程序可以无休止的打印hehe,大家自己去运行可以发现,最下面的光标是在一直闪烁的,这就证明程序一直在进行,在无休止的打印,像这样:


这个时候就有小伙伴要问了,这也没有报错啊,代码怎么就有问题了呢?

大家要注意,这个代码肯定是错误的,我们数组arr中只能存10个整型,也就是说,当我们 i 变成10的时候,就已经越界访问了,再向后越界访问,我们就有可能覆盖到 i 的地址,从而导致程序的死循环。至于为什么没有报错呢?那是因为程序死循环了嘛,它一直忙着打印 hehe 呢,吃了炫迈一样,根本停不下来,所以来不及报错

此题其内存布局如图:

(1)栈区内存的使用习惯是从高地址向低地址使用的,所以变量i的地址是较大的,及arr数组的地址整体是小于 i 的地址

注意:在VS上切换到X64版本,这个使用的顺序是相反的,在Release版本的程序中,这个使用的顺序也是相反

(2)数组在内存中的存放是:随着下标的增长,地址是由低到高变化

由此可见,在此题中, 随着数组下标的增长,往后越界就有可能覆盖到 i 的地址 ,这样就可能造成死循环

 

这里可能有小伙伴要问了:为什么 i 和 arr 数组之间恰好空出来2个整型的空间呢?这里确实是巧合,在不同的编译器下可能中间的空出的空间大小是不一样的,代码中这些变量内存的分配和地址分配是编译器指定的,所以的不同的编译器之间就有差异了,这也就是为什么题目在一开始就会告诉我们是在Debug 、x86环境下进行

这个理解我们就能够清楚的体会到调试的重要性,只有调试才能观察到程序内部执行的细节,就像医生给病人做B超,CT一样
总结:调试是需要反复去动手练习的,诸君一定要自己动手多调试,从中汲取经验。调试是可以增加程序员对代码的理解和掌控的,掌握了调试的能力,就能看到本质,对程序内部一览无余。熟练的掌握调试技巧是一个优秀的程序员的必备技能

OKK,有关VS中调试的相关知识就给大家聊到这里了。 程序运行时的错误,是千变万化的,这个时候我们可以借助调试,去逐步定位每条语句的问题,调试观察并解决我们程序在运行时出现的问题。当然了,这肯定不是一日之功嘛,而是一个日积月累的过程,无他唯手熟尔。无需多言,诸君记得勤练手,咱们共勉!!!下期再见,886!

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

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

相关文章

【LLM多模态】多模态LLM在图表处理的应用

note 在真实场景下,我们进行测试,多模态大模型在处理显著文本时表现尚可,但在处理细粒度文本时往往效果并不太好,why? ​具体原因如下: 首先,视觉编码器的分辨率对于多模态大模型的性能影响较大&#x…

树莓派4B 有电但无法启动

试过多个SD卡,反复烧系统镜像都无法启动。接HDMI显示器没有信号输出,上电后PWR红灯长亮,ACT绿灯闪一下就不亮了,GPIO几个电源脚有电,芯片会发热,测量多个TP点电压好像都正常。 ……

Java面试题--JVM大厂篇(1-10)

引言: 在这个信息时代,对于准备进入大厂工作的朋友们来说,对于JVM(Java虚拟机)的掌握是面试中的一项重要内容。下面是一些精选的JVM面试题,希望对大家能有所帮助。 正文: 1. JVM有哪几种垃圾收…

用Python一键生成PNG图片的PowerPoint幻灯片

在当今的商业环境中,PowerPoint演示是展示和传递信息的常用方式。然而,手动将大量图像插入到幻灯片中往往是一项乏味且耗时的工作。但是,通过Python编程,我们可以轻松自动化这个过程,节省时间和精力。 C:\pythoncode\new\folderTOppt.py 在本文中,我将介绍如何使用Python、wx…

C/C++ vector详解

要想了解STL,就必须会看: cplusplus.comhttps://legacy.cplusplus.com/ 官方内容全都是英文的,可以参考: C/C初始识https://blog.csdn.net/2301_77087344/article/details/138596294?spm1001.2014.3001.5501 vector&#xff…

redisson的使用及LUA脚本实现分布式秒杀

1.redisson实现分布式锁(推荐) redisson官网:Redisson: Easy Redis Java client and Real-Time Data Platform Redisson是一个基于Redis的Java客户端,它不仅提供了对Redis基本操作的支持,而且是一个功能丰富的分布式协调服务客户端。Rediss…

知识分享:隔多久查询一次网贷大数据信用报告比较好?

随着互联网金融的快速发展,越来越多的人开始接触和使用网络贷款。而在这个过程中,网贷大数据信用报告成为了评估借款人信用状况的重要依据。那么,隔多久查询一次网贷大数据信用报告比较好呢?接下来随小易大数据平台小编去看看吧。 首先&…

Pandas 多层索引中的索引和切片操作你学会了吗

1. Series的索引操作 对于Series来说,直接中括号[]与使用 .loc() 完全一样 显式索引 # 导包import numpy as npimport pandas as pd data np.random.randint(0,100,size6) index [ ["1班","1班","1班","2班","…

C++——list的实现以及源码

前言: 最近学习了clist的实现,这让我对迭代器的理解又上升了一个新的高度,注意:代码里的list是放在一个叫zgw的命名空间里边,但是在实现list的代码中没有加namespace,这里给个注意,以后复习时能…

颜色值进制转换

颜色值进制转换 专业的和非专业程序员在编程时都碰到过颜色值的表达式。特别是在编制网页和设计界面时,都要选择颜色。各语言的颜色值表达式就两种,十六进制的颜色值hex$和十进制的RGB格式。现成的调色板颜色表也是这两种格式。写代码时会遇到写颜色值码…

Linux-组管理和权限管理

1 Liunx组的基本介绍: 在Linux中的每个用户必须属于一个组,不能独立于组外。在Linux中每个文件都有所有者、所在组、其他组的概念 所有者所在组其它组改变用户所在的组 2 文件/目录的所有者 一般文件的创建者,谁创建了该文件,就…

垃圾回收机制及算法

文章目录 概要对象存活判断引用计数算法可达性分析算法对象是否存活各种引用 垃圾收集算法分代收集理论复制算法标记清除算法标记-整理算法 概要 垃圾收集(Garbage Collection, 下文简称GC),其优缺点如下: 优点&#…

Shell

Linux中shell是Linux内核的一个外层保护工具,负责用户与内核互交。是一直命令行解析器,是指一直应用程序,且提供一个界面 还是一种编程语言. 查看当前系统的Shell 查看有哪些shell,用cat /etc/shells 查看当前系统默认的shell&…

二十八篇:嵌入式系统实战指南:案例研究与未来挑战

嵌入式系统实战指南:案例研究与未来挑战 1. 引言 1.1 嵌入式系统的重要性及其应用广度 在当今快速发展的技术领域中,嵌入式系统扮演着至关重要的角色。这些系统是专门设计的计算机硬件和软件的组合,旨在执行特定任务,如控制、监…

牛马真的沉默了,入职第一天就干活

入职第一天就干活的,就问还有谁,搬来一台N手电脑,第一分钟开机,第二分钟派活,第三分钟干活,巴适。。。。。。 打开代码发现问题不断 读取配置文件居然读取两个配置文件,一个读一点,…

Leetcode算法题笔记(3)

目录 矩阵101. 生命游戏解法一解法二 栈102. 移掉 K 位数字解法一 103. 去除重复字母解法一 矩阵 101. 生命游戏 根据 百度百科 , 生命游戏 ,简称为 生命 ,是英国数学家约翰何顿康威在 1970 年发明的细胞自动机。 给定一个包含 m n 个格子…

计算机网络——TCP 协议的三次握手 / 四次挥手

简述 TCP / UDP 协议都是传输层的协议。 UDP 是面向无连接的协议,就是说发送端不在乎消息数据是否传输到接收端了,所以会出现数据丢失的情况,所以可靠性也不高。 TCP 是面向连接的、可靠的、基于字节流的传输层协议。所谓面向连接的&#…

机器学习算法手撕(一):KD树

import math import matplotlib.pyplot as pltclass Node:def __init__(self, data, leftNone, rightNone):self.data dataself.left leftself.right right# 创建KDTree类 class KDTree:def __init__(self, k):self.k kdef create_tree(self,dataset,depth):if not dataset…

SpringBoot使用rsa-encrypt-body-spring-boot实现接口加解密

废话不多说&#xff0c;直接上代码 引入依赖 <dependency><groupId>cn.shuibo</groupId><artifactId>rsa-encrypt-body-spring-boot</artifactId><version>1.0.1.RELEASE</version> </dependency>配置文件 rsa:encrypt:# 是…

电表远传抄表是什么?

1.电表远传抄表&#xff1a;简述 电表远传抄表&#xff0c;又称为远程控制自动抄表系统&#xff0c;是电力行业的智能化技术运用&#xff0c;它通过无线或通信网络技术&#xff0c;完成对电表数据信息的远程收集解决。此项技术不仅提升了抄水表高效率&#xff0c;降低了人工偏…