你真的知道怎么使用vs吗?把把手教你实用调试小技巧

news2025/1/10 11:21:27

实用调试小技巧

  • 1.什么是bug?
  • 2.调试是什么?有多重要?
  • 3.debug和release的介绍。
  • 4.windows环境调试介绍。
    • 4.1常见调试快捷键
    • 4.2 调试的时候查看程序当前信息
      • 4.2.1监视:
      • 4.2.2内存
      • 4.2.3调用堆栈
      • 4.2.4反汇编
      • 4.2.5寄存器
  • 5.一些调试的实例。
  • 6.如何写出好(易于调试)的代码。
  • 7.编程常见的错误。

1.什么是bug?

谈到bug,我们知道bug的中文意思是虫子,飞蛾的意思。至于为什么bug一词会用到计算机领域的话得追溯到第一台计算机的诞生。
在这里插入图片描述
上面个你看到的就是世界上第一个bug的诞生。它的来源也是非常的有意思,当时世界上的第一台计算机出了故障不能正常的工作,于是工作人员就进入计算机内部检查(当时的计算机非常的大,达到人可以进去),这个时候发现计算机的一个晶体管内有个飞蛾死在了里面于是把飞蛾清理干净,换了零件之后,计算机就可以正常的工作了。于是科学家们就把此次事件记录了下来,一直延伸到现在,我们就把计算机成程序出问题说成是bug。

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

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

简单点说调试就是一个发现错误,并且精准的找到错误地点,找到合理的解决方案的一个纠错过程。

在程序员界里有这样一句话:一个优秀的程序员同时也是一个优秀的侦探。

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

3.debug和release的介绍。

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

当然两个版本还是有一些的不同之处的,就比如生成的可执行文件的大小是不一样的(.exe文件后缀名的文件);
在这里插入图片描述
在这里插入图片描述
我们先看Debug版本的:
在这里插入图片描述
再看Release版本的:
在这里插入图片描述

  • 这样一对比就可以看出了Release版本的可执行文件的大小是比Debug版本的小的,这是因为Release版本是对代码做了一些优化的,而我们的Debug版本是没有做优化的,所以在Release版本下的文件所占内存大小是更小的。

  • 那问题来了,既然有两个版本我们应该选择哪个版本呢?
    首先我们知道这两个版本的区别就是一个做了优化一个没有做优化。
    那既然我们要检查我们编写的代码哪里出问题了,是不是应该我们写的什么代码就调试什么代码,也就是说没有做任何的优化效果,这样的话及时是一点小错误我们也可以即使的发现并作出及时的改进。所以我们调试首选的就是Debug版本的。

  • 相反的,如果我们调试用的是Release版本的话,我们知道Release版本是对我们写的代码进行了优化作用的,如果我们用这个版本进行调试的话,有些错误的代码时被优化过的,那就说明一些较小的错误是不能被发现的,那么日积月累把这些小错误累计起来就会出大错误的。这么讲的话那Release版本到底在什么时候用到呢。我们要知道一点的时我们编写出来的文件终归是要给客户使用的,既然时给别人用的我们就要保证我们编写的程序不能出现错误,这个时候Release版本就有用出来,当我们调试的时候一些小的错误没有及时的发现就直接给用户使用,这个时候我么Release版本就会帮我们优化代码弥补那些小错误,这个时候客户就能正常的时候了。

4.windows环境调试介绍。

4.1常见调试快捷键

使用一些常用调试快捷键:快捷键作用
F5启动调试,经常用来直接跳到下一个断点处。
F9创建断点和取消断点断点的重要作用,可以在程序的任意位置设置断点。这样就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。
F10逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句。
F11逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部(这是最长用的)。
CTRL+F5开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。
  1. CTRL+F5 直接执行
    我们代码后,想要直接看到我们编写的结果,就用这个组合键,就能在终端看到我们的编写结果了。这个是可以跳过断点的。
  2. F10逐步调试
    万一我们代码编写的时候出现了错误,我们也很难看出哪里出错了,这个时候就需要对我们的代码逐行的进行检验,这个时候我们就可以按F10
  3. F5 时执行键
    这个一般和F9断点搭配的使用,当我们设置好了断点之后,只需要按F5便会跳到断点处。
  4. F9 设计断点
    但我们编写的代码又几百行甚至更多的时候,而我们又知道他在那个部分出错了,如果我们还按F10逐行的进行检验的话就会浪费大量的时间和精力,这个时候我们可以设计断点。设计断点的方法有两种:1.选中一行按F9 。2.用鼠标左键点击改行最左边。当我们设置好了断点之后再按F5就可以直接跳到我们的断点处了。
    在这里插入图片描述

4.2 调试的时候查看程序当前信息

一般我们使用到的有:
在这里插入图片描述
注意这些都是在进行调试的时候才能使用的

4.2.1监视:

在这里插入图片描述
这个监视窗口我们可以自主输入想要看到结果,在按F10的过程最左边有一个箭头,这个箭头就是我们执行到哪一行的标志。
同时除了手动的,还用自动的。
在这里插入图片描述
自动窗口会根据你调试到哪里自动生成可监视的变量,但是他的局限性就是不能一直监视,一点过来变量的作用域就不能在监视了。

4.2.2内存

监视内存的方法和上面是一样的:
在这里插入图片描述

它可以显示处变量子内存的分布。

4.2.3调用堆栈

在这里插入图片描述

4.2.4反汇编

调用堆栈的方法有两种:1.鼠标右键点击转到反汇编。2.窗口打开
在这里插入图片描述
在这里插入图片描述

4.2.5寄存器

在这里插入图片描述

5.一些调试的实例。

实例一:

#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;
}

按我们的分析,这是一个数组访问越界问题。
我们先看Debug版本的:
在这里插入图片描述
这里发现程序进入死循环了(这里提示以下要改成x86状态下才能看到死循环的效果,如果时x64的话就会直接报错)这是为什么呢?
这个时候我我们就要明白有关内存问题了:
我们的内存分为栈区,堆区,静态区(后面都会详细的讲解),而我们主函数调用时在栈区的。
栈区的特点是:1.先使用高地址的空间,在使用低地址的处的空间。2.先进的后出,后进的先出。
我们看一下他们的汇编:
在这里插入图片描述
这里我们可以看到i的内存和arr[12]的内存地址重合了,也就说明当我们遍历到arr[12]并把arr[12]初始化为0的时候使用过地址改变arr[12]的,恰好我们i的地址也是arr[12]的地址,所以i就别改成了0,所以一旦i遍历到12的时候就有被改成了0,所以i又再次遍历,一直这样重复所以就会死循环。

那我们再看一下Release版本的:
在这里插入图片描述
会发现它就整整齐齐的打印了13个hehe,这就是Release版本的优化作用。

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

优秀的代码:

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

常见的coding技巧:

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

注意:

  1. 分析参数的设计(命名,类型),返回值类型的设计
  2. 这里讲解野指针,空指针的危害。
  3. assert的使用,这里介绍assert的作用
  4. 参数部分 const 的使用,这里讲解const修饰指针的作用
  5. 注释的添加

7.编程常见的错误。

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

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

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

相关文章

HNU-计算机系统-实验4-ShellLab

ShellLab 计科2102 梅炳寅 202108010206 写在前面 作为一份实验报告,我希望阅读者能够比较好地看到这份报告有价值的部分。私以为更为有价值的部分体现在: 报告中打★的部分,最后的代码中,我在代码中加入了大量的中文注释、函数原型、参数解读、以及个人对代码的推断与理…

网易云音乐开发--音乐播放暂停切换上下首功能实现

音乐播放暂停功能实现 封装一个控制音乐播放/暂停的功能函数 看一下文档&#xff0c;我需要用的api 这个接口好像没有音频的url&#xff0c;查看一下&#xff0c;换个api 这样就能拿到id&#xff0c;并可以播放了 但是音乐并没有播放 我们少了这个 现在可以播放了&#xff…

[CTF/网络安全] 攻防世界 view_source 解题详析

[CTF/网络安全] 攻防世界 view_source 解题详析 查看页面源代码方式归类总结 题目描述&#xff1a;X老师让小宁同学查看一个网页的源代码&#xff0c;但小宁同学发现鼠标右键好像不管用了。 查看页面源代码方式归类 单击鼠标右键&#xff0c;点击查看页面源代码&#xff1a; …

Linux 指令(三)+完整思维导图+实图例子+深入细节+通俗易懂建议收藏

绪论 涓滴之水终可磨损大石&#xff0c;不是由于它的力量强大&#xff0c;而是由于昼夜不舍的滴坠。今天我们继续学习Linux指令。 话不多说安全带系好&#xff0c;发车啦&#xff08;建议电脑观看&#xff09;。 附&#xff1a;红色&#xff0c;部分为重点部分&#xff1b;蓝颜…

由斯坦福、Nautilus Chain等联合主办的 Hackathon 活动,现已接受报名

由 Stanford Blockchain Accelerator、Zebec Protocol、 Nautilus Chain、Rootz Lab 共同主办的黑客松活动&#xff0c;现已接受优秀项目提交参赛申请。 在加密行业发展早期&#xff0c;密码极客们就始终在对区块链世界基础设施&#xff0c;在发展方向的无限可能性进行探索。而…

四、easyUI中的tabs(选项卡)组件

1.tabs&#xff08;选项卡&#xff09;组件的概述 选项卡会显示一批面板&#xff0c;但在同一个时间只会显示一个面板。每个选项卡面板都有头标题和一些小的按钮工具菜单&#xff0c;包括关闭按钮和其他自定义按钮。 2.tabs&#xff08;选项卡&#xff09;组件的使用 在项目新…

【C++】——内存管理(new和delete)

文章目录 1. 前言2. C/C内存分布3. C语言动态内存管理方式4. C内存管理方式4.1 内置类型4.2 自定义类型 5. operator new与operator delete函数6. new和delete的实现原理7. 定位new表达式(placement-new)8. 结尾 1. 前言 在学习C语言的时候&#xff0c;我们学习了动态内存管理…

物联网协议之MQTT

MQTT 简介 MQTT 可以简单看做一个网络协议&#xff0c;用于机器对机器的通信&#xff08;与客户端到服务器的传输有点区别&#xff09;。智能传感器、可穿戴设备和其他物联网&#xff08;IoT&#xff09;设备通常必须通过带宽有限的资源受限网络传输和接收数据。这些物联网设…

更新cuda和 pytorch==1.12.1版本,更新到cuda11.3.1

nvidia-smi 查看gpu支持的最高cuda版本 nvcc -V 查看当前cuda版本 卸载旧版本cuda 除了NVIDIA Geforce、NVIDIA PhysX、NVIDIA图形驱动程序&#xff0c;将电脑中其他NVIDIA开头的全部卸载 安装cuda 下载适合的cuda版本 https://developer.nvidia.com/cuda-toolkit-ar…

基于QT开发的使用OPC_UA与西门子1200,1500系列PLC通信的工业监控Demo

目录 一&#xff0c;总体介绍 二&#xff0c;需要的软件 三&#xff0c;需要的硬件 四&#xff0c;QT程序代码 五&#xff0c;西门子PLC代码 一&#xff0c;总体介绍 先看一下图1-1的QT运行界面图&#xff0c;界面中服务器地址就是OPC_UA服务器地址&#xff0c;整个项目作…

图解LeetCode——19. 删除链表的倒数第 N 个结点

一、题目 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 二、示例 2.1> 示例 1&#xff1a; 【输入】head [1,2,3,4,5], n 2 【输出】[1,2,3,5] 2.2> 示例 2&#xff1a; 【输入】head [1], n 1 【输出】[] 2.3> 示例…

数值计算 - 误差的来源

误差的来源是多方面的&#xff0c;但主要来源为&#xff1a;过失误差&#xff0c;描述误差&#xff0c;观测误差&#xff0c;截断误差和舍入误差。 过失误差 过失误差是由设备故障和人为的错误所产生的误差&#xff0c;在由于每个人都有“权利”利用机器进行数值计算,所以在计算…

#include <archive.h>报错

#include <archive.h>报错 archive配置 Linux环境下&#xff0c;在C项目.cpp文件中存在如下语句&#xff0c;导致无法运行~ #include <archive.h> #include <archive_entry.h>由于C编译器默认不包含archive&#xff0c;所以我们需要自行配置。 Libarchiv…

Java 基础--interview经典(个人认为)题目

1&#xff09;多线程中 synchronized 锁升级的原理是什么&#xff1f; synchronized 锁升级原理&#xff1a;在锁对象的对象头里面有一个 threadid 字段&#xff0c;在第一次访问的时候 threadid 为空&#xff0c;jvm 让其持有偏向锁&#xff0c;并将 threadid 设置为其线程 i…

终の序章(一)

前言 写在我大三的最后一次省赛 &#xff0c;也是最后一次比赛 从半年前区域赛的大失利&#xff0c;导致我曾一度放弃算法竞赛和算法训练 新路历程 考虑到前几次的省赛&#xff0c;我们这次采取 稳 的一种方式&#xff0c;因为前几次省赛难度跨度较 大&#xff0c;对于大部…

【牛客网面试必刷TOP101】链表篇(二)

【牛客网面试必刷TOP101】链表篇&#xff08;二&#xff09; 前言刷题网站刷题&#xff01;BM4 合并两个排序的链表思路一&#xff1a;双指针思路二&#xff1a;递归&#xff08;扩展思路&#xff09; BM5 合并k个已排序的链表思路一&#xff1a;归并排序思想 BM6 判断链表中是…

内网渗透(七十九)之 CVE-2021-42287 权限提升漏洞

CVE-2021-42287 权限提升漏洞 漏洞背景 2021年11月9日,微软发布11月份安全补丁更新。在该安全补丁更新中,修复了两个域内权限提升漏洞CVE-2021-42287 、CVE-2021-42278。当时这两个漏洞的利用详情和POC并未公布,因此并未受到太多人关注。 一个月后,国外安全研究员公布了…

[CTF/网络安全] 攻防世界 ics-06 解题详析

[CTF/网络安全] 攻防世界 ics-06 解题详析 姿势&#xff08;Burp爆破&#xff09; 题目描述&#xff1a;云平台报表中心收集了设备管理基础服务的数据&#xff0c;但是数据被删除了&#xff0c;只有一处留下了入侵者的痕迹。 可知&#xff1a;报表中心含有部分数据 仅报表中心…

C++内存管理/函数模板/类模板

一、C内存管理 C中内存基本形式与C语言类似&#xff0c;可以参考下图。 X64环境下总共大小为8G,X86环境下为4G。 1、内核空间&#xff1a;用户不能读写&#xff0c;但要占用一定空间。 2、栈区&#xff1a;以开辟、销毁栈帧形式运行&#xff0c;主要应用于局部变量和函数栈帧…

chatgpt赋能Python-python3_choice

Python3中的choice()函数&#xff1a;一种简单而有趣的随机选择方式 在Python3中&#xff0c;choice()函数是一个常见的随机模块。它允许我们从一个序列中随机选择一个元素。这在程序中经常用于生成一些需要随机展示的数据。本文将介绍Python3中的choice()函数&#xff0c;并探…