Visual Studio的实用调试技巧总结

        对于很多学习编程的老铁们来说,是不是也像下面这张图一样写代码呢?

        那当我们这样编写代码的时候遇到了问题?大家又是怎么排查问题的呢?是不是也像下面这张图一样,毫无目的的一遍遍尝试呢?

        这篇文章我就以 Visual Studio 2022编译器为例,带大家了解在Visual Studio2022编译器上是 如何进行调试C语言代码的。

1. 调试是什么?有多重要

1.1 调试的概念

        调试是什么:调试(英文:Debugging / Debug),又称除错,是发现和减少计算机程序或电子仪器设备中程序错误的一个过程。

1.2 调试的基本步骤

        1.发现程序错误的存在。
         2.以隔离、消除等方式对错误进行定位。
        3.确定错误产生的原因。
        4.提出纠正错误的解决办法。
        5.对程序错误予以改正,重新测试。

1.3 Debug和Release的介绍

        Debug: 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。
        Release: 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。(该版本不方便程序员调试)。

1.4 Debug和Release版本的对比

        因此,我们平常在编译器中写代码时,都是用的Debug版本。并且我们说调试就是在Debug版本的环境中,找代码中潜伏的问题的一个过程。

        对于如下同一份代码,我们来看看在 Debug环境 和 Release环境 中的结果展示:

#include<stdio.h>int main()
{int arr[] = { 1,2,3,4,5,6 };int* p = arr;printf("%d\n", *(p + 2));return 0;
}

        Debug环境中:

        Release环境中:

        由结果中可以看出,Release环境下的执行文件(即 .exe文件)会比 Debug环境下的执行文件小好几倍,这是因为Release版本会对代码进行各种优化,因此这种版本也并不适合我们进行调试。

        那编译器进行了哪些优化呢?再来看看下面这段代码在两种环境下的结果展示:

#include<stdio.h>int main()
{int i = 0;int arr[10] = { 0 };for (i = 0; i <= 12; i++){arr[i] = 0;printf("hahaha\n");}return 0;
}

        同样的代码,在Debug环境中死循环,在Release环境下却能正常运行。这时我们通过调试看看这段代码在两种环境下的反汇编展示对比:

        观察两种环境下的汇编指令可以看出,Release版本会删除一些不必要的指令,从而使得编译器在运行代码时速度上是最优的。

        这时候也许有老铁会疑惑为什么这段代码在Debug环境下死循环报错(依赖于编译器的环境,在x86环境下会死循环,x64环境下会报错)呢?下面我就给大家仔细讲讲。

        首先要知道的是,局部变量在内存中的栈区上开辟空间的,而栈区内存空间的使用习惯:先使用高地址处的空间,再使用低地址的空间 (在不同的编译器上有所区别),如下图所示

        而数组,随着下标的增长,地址是由低到高变化的,且数组内存是连续存储的。因此上述代码中通过for循环对数组进行越界访问,并对数组元素重新赋值为0,这样就可能会导致arr[10] —— arr[12]中所开辟的内存空间 与 局部变量i 所开辟的内存空间重叠,从而导致 变量i 的值被修改为0,进而陷入死循环。

        这也提醒我们在对数组进行访问时千万不能越界访问呀!!

2. Windows环境调试介绍

        在对代码进行调试前,一定要将编译器的环境设置为 Debug版本,这样才能正常调试!

2.1 Visual Studio中常用的一些快捷键

        F5 —— 启动调试,经常用来直接跳到下一个断点处(切换断点)
        F9 —— 创建断点和取消断点。断点的重要作用,可以在程序的任意位置设置断点。这样就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。
        F10 —— 逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句。(逐过程简单的说,就是当遇到函数调用时,直接就执行完成了,而不会进入到函数内部。)
        F11 —— 逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部(这是最常用的)。(逐语句简单点说,就是当遇到调用函数时,会进入函数内部逐一执行每条语句。)
        CTRL + F5 —— 开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。

如果直接按 F5 没用,就试试 Fn+F5,其他快捷键也是一样的。如果忘记这些快捷键了,Visual Studio上也有提示的。

        当进行调试后,就能看到以下窗口,记住一定要调试启动后才能看到

3. 如何写出好(易于调试)的代码

        对于一份优秀的代码,通常会有以下几个特性:

                1. 代码运行正常。
                2. bug很少。
                3. 效率高。
                4. 可读性高。
                5. 可维护性高。
                6. 注释清晰。
                7. 文档齐全。

4. 常见的coding技巧

        1. 使用assert 。
        2. 尽量使用const。
        3. 养成良好的编码风格。
        4. 添加必要的注释。
        5. 避免编码的陷阱。

这里给大家讲解一下第一点assert。

        assert是一个库函数(调用是需要包含头文件:#include<assert.h>),又为 断言 —— 只要不符合assert内的判断则会报错,反之则代码正常运行。

        举例如下:

        当我们用 assert 来判断所传的地址是否为空地址时,如果不为空,则代码正常运行,反之则报错(Assertion failed: p != NULL),这样通过assert函数就能很好的指出代码的问题。

5. 常见的编译错误

        1. 编译型错误:直接看错误提示信息(双击),解决问题。或者凭借经验就可以搞定。相对来说简单。(一般找到的都是语法问题)
        2. 链接型错误:看错误提示信息,主要在代码中找到错误信息中的标识符,然后定位问题所在。一般是标识符名不存在或者拼写错误。
        3. 运行时错误:借助调试,逐步定位问题。最难搞。

 

        最后就是如果我们想要在将来写出一份优秀的代码,一定要熟练掌握调试技巧,并且多使用快捷键,提升效率。只有多动手,尝试调试,我们才能有进步!!

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

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

相关文章

k8s的微服务

ipvs模式 Service 是由 kube-proxy 组件&#xff0c;加上 iptables 来共同实现的 kube-proxy 通过 iptables 处理 Service 的过程&#xff0c;需要在宿主机上设置相当多的 iptables 规则&#xff0c;如果宿主机有大量的Pod&#xff0c;不断刷新iptables规则&#xff0c;会消耗…

QT:计算点到线段的垂线段的距离

描述 在Qt中&#xff0c;要计算一个点到一条线段的垂线段的长度&#xff08;即点到线段上最近点的距离&#xff0c;且这个点是垂直于线段的&#xff09;&#xff0c;你不能直接使用QVector2D::distanceToLine&#xff0c;因为这个方法计算的是点到直线的垂直距离&#xff0c;而…

2024-09-22 进程优先级,进程切换

一、僵尸状态 & 孤儿进程 进程退出&#xff1a;内核数据结构&#xff08;task_struct 维护&#xff09; 代码和数据&#xff08;直接释放&#xff09; 代码不会执行了首先可以立即释放的就是进程对应的程序信息数据。进程退出要有退出信息&#xff08;进程的退出码&#…

六西格玛设计DFSS方法论在消费级无人机设计中的应用——张驰咨询

本文基于六西格玛设计方法论&#xff0c;对消费级无人机的设计流程进行系统化研究&#xff0c;探讨如何通过六西格玛设计的理念、工具和方法提升无人机产品的设计质量和市场竞争力。文章从市场定位、客户需求分析出发&#xff0c;深入到关键KPI指标的制定&#xff0c;并逐步阐述…

【网络安全】漏洞案例:提升 Self-XSS 危害

未经许可,不得转载。 文章目录 Self-XSS-1Self-XSS-2Self-XSS-1 目标应用程序为某在线商店,在其注册页面的First Name字段中注入XSS Payload: 注册成功,但当我尝试登录我的帐户时,我得到了403 Forbidden,即无法登录我的帐户。 我很好奇为什么我无法登录我的帐户,所以我…

前端高频面试题2024/9/22(偏项目问题--通用后台管理系统)

文章目录 一.前端项目概述1.系统登录注册模块1.对注册的密码进行加密 &#xff08;使用加密中间件bcrypt.js&#xff09;2.登录成功后返回token3.前端登录页面有用到弹性布局&#xff0c;ref和reactive4.登录头像&#xff1a;文件上传 2.系统设置模块2.系统首页模块&#xff08…

使用electron+vue开发桌面应用

electron是什么 electron由Node.jsChromiumNative APIs构成。你可以理解成&#xff0c;它是一个得到了Node.js和基于不同平台的Native APIs加强的Chromium浏览器&#xff0c;可以用来开发跨平台的桌面级应用。 它的开发主要涉及到两个进程的协作——Main&#xff08;主&#x…

Java通过RAG构建专属知识问答机器人_超详细

RAG&#xff1a;融合检索与生成的文本精准生成技术 检索增强生成&#xff08;RAG&#xff09;是一种技术&#xff0c;它通过结合检索模型和生成模型来提高文本生成的准确性。具体来说&#xff0c;RAG首先利用检索模型从私有或专有的数据源中搜索相关信息&#xff0c;然后将这些…

编程练习7 5G网络建设

需要用到并查集的相关知识&#xff1a;可以参考如下链接 并查集详解&#xff08;原理代码实现应用优化&#xff09;-CSDN博客 #include<iostream> #include<algorithm> #include<vector>using namespace std;vector<int> split(string params_str) {…

ICT产业新征程:深度融合与高质量发展

在信息时代的浪潮中&#xff0c;每一场关于技术革新与产业融合的盛会都闪耀着智慧的光芒&#xff0c;引领着未来的方向。9月25日&#xff0c;北京国家会议中心内&#xff0c;一场聚焦全球信息通信业的顶级盛事——第32届“国际信息通信展”&#xff08;PT展&#xff09;隆重拉开…

【LwIP源码学习3】TCP协议栈分析——数据接收流程

前言 本文介绍代码在lwip的tcp_in.c文件中&#xff0c;主要介绍TCP协议栈中数据的接收流程。 正文 1、一个正常的TCP数据&#xff0c;首先会传入到 tcp_input(struct pbuf *p, struct netif *inp)函数&#xff0c;其中指针p指向传入的数据流。 2、从数据流中获取TCP头部 …

通过Express + Vue3从零构建一个用户认证与授权系统(二)数据库与后端项目搭建与实现

前言 上一篇完成了系统的相关设计文档的编写&#xff0c;本文将详细介绍如何一步步使用 TypeScript 和 Express 搭建一个模块化、类型安全的用户认证与授权系统&#xff0c;包括数据库设计、后端项目搭建、用户认证、角色与权限管理、错误处理以及 Swagger 文档集成。 项目准…

【ubuntu】ubuntu20.04安装cuda12.6与显卡驱动

目录 1.安装cuda12.6 2.安装显卡驱动 1.安装cuda12.6 https://developer.nvidia.com/cuda-toolkit-archive https://developer.nvidia.com/cuda-12-6-0-download-archive?target_osLinux&target_archx86_64&DistributionUbuntu&target_version20.04&target_…

DART: Implicit Doppler Tomography for Radar Novel View Synthesis 笔记

Link&#xff1a;https://wiselabcmu.github.io/dart/ Publish&#xff1a; 2024CVPR Abstract DART主要任务就是用来合成雷达距离多普勒图像range-droppler&#xff0c;可用于生成高质量的断层扫描图像。 Related Work 1 Radar Simulation 基于模型的方法 任务&#xff…

XGBoost回归预测 | MATLAB实现XGBoost极限梯度提升树多输入单输出

回归预测 | MATLAB实现XGBoost极限梯度提升树多输入单输出 目录 回归预测 | MATLAB实现XGBoost极限梯度提升树多输入单输出预测效果基本介绍模型描述程序设计参考资料预测效果 基本介绍 XGBoost的全称是eXtreme Gradient Boosting,它是经过优化的分布式梯度提升库,旨在高效、…

医学和生信web APP 平台- Appmatrix

医学&#xff08;和生信&#xff09;web APP 平台- Appmatrix 最近使用shinyproxy将平时所构建的shiny和streamlit医学类应用汇集在一起&#xff0c;实现一站式访问&#xff0c;另外&#xff0c;使用了自己电脑内网穿透&#xff0c;一定程度上缓解了数据分析类APP消耗计算资源…

关闭线程池的API介绍

线程池关闭主要涉及以下几个API: shutdown:关闭线程池&#xff0c;此方法执行后&#xff0c;线程池不会立即关闭&#xff0c;1、等待正在执行的线程任务执行完毕 2、等待任务队列中的任务执行完毕&#xff0c;步骤1和2执行后&#xff0c;线程池才完全中止isShutdown:判断线程池…

PostgreSQL学习笔记六:模式SCHEMA

模式&#xff08;Schema&#xff09; PostgreSQL中的模式&#xff08;Schema&#xff09;是一个命名的数据库对象集合&#xff0c;包括表、视图、索引、数据类型、函数、存储过程和操作符等。模式的主要作用是组织和命名空间数据库对象&#xff0c;使得同一个数据库中可以包含…

C/C++语言基础--C++异常看这一篇就够了

本专栏目的 更新C/C的基础语法&#xff0c;包括C的一些新特性 前言 通过前面几节课&#xff0c;我们学习了抽象、封装、继承、多态等相关的概念&#xff0c;接下来我们将讲解异常&#xff0c;异常是专门处理错误的&#xff1b;这一次加了不少图标&#xff0c;希望大家喜欢;C语…

牛客周赛 Round 63(构造、组合数、线性基)

文章目录 牛客周赛 Round 63(构造、组合数、线性基)A. 小红的好数B. 小红的好数组C. 小红的矩阵行走(简单思维题)D. 小红的行列式构造(构造、数学题)E. 小红的 red 计数(组合数)F. 小红开灯(线性基) 牛客周赛 Round 63(构造、组合数、线性基) A. 小红的好数 按照题意判断即可…