当前位置: 首页 > news >正文

实用调试技巧【下篇】

🔴本文章是在 Visual Studio 2022(VS2022)编译环境下进行操作讲解

文章目录

    • 3.2.调试的时候查看程序当前信息
      • 3.2.1.查看临时变量的值
      • 3.2.2.查看内存信息
      • 3.2.3.查看调用堆栈
      • 3.2.4.查看汇编信息
  • 🥳4.调试实例
  • 🥳5.如何写出(易于调试)的代码
    • 5.1.模拟实现库函数: strcpy
    • 5.2. const 修饰指针
  • 🥳6.编程常见的错误

请添加图片描述

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

3.2.1.查看临时变量的值

🔴自动窗口
👉调试–>窗口–>自动窗口
在这里插入图片描述
在这里插入图片描述
它会出现一个自动窗口,它会自动捕获变量的值,让你监视,方便的我们不用手动添加变量,但是如果它不想让你看的时候过了一会就会自动取消了,我们就监视不到了
🔴局部变量
👉在自动窗口的下面
在这里插入图片描述
与自动窗口比较相似,但不同的是放的是局部变量,监视的是程序执行中的局部变量
🔴监视
👉调试–>窗口–>监视
在这里插入图片描述
这才是我们用到最多的调试功能
在这里插入图片描述
我们想监视谁,就输入谁,它不会自己取消,会一直显示,来为我们提供对变量的监视
在这里插入图片描述
在这里插入图片描述
数组也可以观察,变量的地址也都可以观察到
如果有需要,可以同时打开4个监视窗口,每个窗口都可以拖动,放到你想放的位置

3.2.2.查看内存信息

🔴内存
👉调试–>窗口–>内存
在这里插入图片描述
在这里插入图片描述
☝️内存中本放的是二进制的数据,但是为了展示方便,所以是以十六进制来显示的☝️

3.2.3.查看调用堆栈

🔴调用堆栈
👉调试–>窗口–>调用堆栈
在这里插入图片描述
👇简单知道一下 什么是栈👇
在这里插入图片描述

👇看这段代码👇
在这里插入图片描述
👇调用堆栈👇
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
☝️反映的是函数的调用逻辑☝️

3.2.4.查看汇编信息

🔴反汇编
👉在内存的下面
在这里插入图片描述
👇看到的是c语言代码翻译出来的汇编代码👇
在这里插入图片描述

🥳4.调试实例

👇看下面这段代码👇

#include<stdio.h>int main()
{int i = 0;int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };for (i = 0; i <= 12; i++){arr[i] = 0;printf("hehe\n");}return 0;
}

运行起来是什么样呢?
在这里插入图片描述
数组已经越界了,为什么没有崩溃而是死循环了呢?
👇进入调试👇
在这里插入图片描述
i 等于9的时候一切都正常,我们继续👇
在这里插入图片描述
这个代码真的是在越界访问!胆大包天啊,如果我们继续下一步呢👇
在这里插入图片描述
继续一直执行
在这里插入图片描述
再改
在这里插入图片描述
i 到12之后并没有++变成13, i 再一直跟着 arr[12] 改变,陷入了死循环,这是为什么呢?有没有可能它们是在同一个空间呢?我们看一下👇
在这里插入图片描述
地址居然一摸一样,它俩在一个空间😕
那么底层原理什么呢?为什么会这样呢?👇

🔴原理:
1. i 和 arr 是局部变量,局部变量是放在栈区上的
2. 栈区内存的使用习惯是 使用高地址的空间,再使用低地址处的空间
3. 数组随着下标的增长,地址是由低到高变化的

在这里插入图片描述

🥳5.如何写出(易于调试)的代码

🥰优秀的代码:

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

🥰常见的coding技巧:

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

5.1.模拟实现库函数: strcpy

在这里插入图片描述
拷贝一个字符串
示例👇

#include<stdio.h>
#include<string.h>int main()
{char arr1[] = "hello world";char arr2[20] = { 0 };strcpy(arr2, arr1);printf("%s\n", arr2);return 0;
}

在这里插入图片描述

👇模拟实现 strcpy👇

#include<stdio.h>
#include<string.h>
void my_strcpy(char* dest, char* src)
{while (*src != 0){*dest = *src;dest++;src++;}*dest = *src; // \0的拷贝
}
int main()
{char arr1[] = "hello world";char arr2[20] = { 0 };my_strcpy(arr2, arr1);printf("%s\n", arr2);return 0;
}

如果写成这样的代码,这算一个好的代码吗?当然不算一个好的代码,我们可以优化一下👇

void my_strcpy(char* dest, char* src)
{while (*src != 0){*dest++ = *src++;}*dest = *src; // \0的拷贝
}

我们还可以再融合一下👇

void my_strcpy(char* dest, char* src)
{while (*dest++ = *src++){;}
}

可以直接一次搞定
这样改进完好像已经足够好了,但是我们还能再改进👇

void my_strcpy(char* dest, char* src)
{if (dest == NULL || src == NULL){return;}while (*dest++ = *src++){;}
}

防止遇到空指针,但是这样处理遇到问题只是回避掉了,并不做处理👇

#include<stdio.h>
#include<string.h>
#include<assert.h>
void my_strcpy(char* dest, char* src)
{//断言assert(dest != NULL);assert(src != NULL);while (*dest++ = *src++){;}
}
int main()
{char arr1[] = "hello world";char arr2[20] = { 0 };my_strcpy(arr2, NULL);printf("%s\n", arr2);return 0;
} 

在这里插入图片描述
使用断言处理之后,如果有问题它就会报错,把问题抛出来并且告诉你出错在哪里,如果不使用断言执行程序的话代码就崩掉了,不会告诉你哪里有问题👇
在这里插入图片描述
🚨断言是对程序员非常友好的东西,我们使用断言是个很好的编程习惯
🚨使用断言别忘记引用头文件 <assert.h>

void my_strcpy(char* dest, char* src)
{//断言assert(dest && src);while (*dest++ = *src++){;}
}

简便一点可以直接写成这样☝️

5.2. const 修饰指针

在这里插入图片描述
const修饰变量m之后,m的值就更改不了了
但是可以使用一些小聪明把m改掉👇

int main()
{const int m = 10;//m = 20;//errorint* p = &m;*p = 20;printf("%d\n", *p);return 0;
}

在这里插入图片描述
这个代码非常奇葩,因为 const 只是在语法层面限制了m不能改,但是通过地址是可以更改的
我们可以在语法层面把指针p 也进行限制👇
在这里插入图片描述

int main(){int n = 100;const int m = 10;//m = 20;//error//const 修饰指针//1. const放在*的左边,*p不能改了,也就是p指向的内容,不能通过p来改变了。但是p是可以改变的,p可以指向其他变量const int* p = &m;p = &n;printf("%d\n", *p);return 0;} 

在这里插入图片描述

int main(){int n = 100;const int m = 10;//m = 20;//error//const 修饰指针//2. const放在*的右边,限制的是p,p不能改变,但是p指向的内容*p,是可以通过p来改变的int* const p = &m;*p = n;printf("%d\n", *p);return 0;} 

在这里插入图片描述

🤜 1. const放在的左边,p不能改了,也就是p指向的内容,不能通过p来改变了。但是p是可以改变的,p可以指向其他变量
🤜2. const放在的右边,限制的是p,p不能改变,但是p指向的内容p,是可以通过p来改变的

void my_strcpy(char* dest,const char* src)
{//断言assert(dest && src);while (*dest++ = *src++){;}
}

所以上面模拟实现strcpy的代码这样写就更严谨了,加上了 const 来修饰char* src
🥰提高了代码的健壮性(鲁棒性)
因为如果下面的 *dest++ = *src++ 位置要是不小心写反了程序就会报错,所以这样写才是有意义的!

我们再来进行最后一次优化👇

#include<stdio.h>
#include<string.h>
#include<assert.h>//strcpy函数返回的是目标空间的起始位置
char* my_strcpy(char* dest,const char* src)
{//断言-- 保证指针的有效性assert(dest && src);char* ret = dest;//把src指向的字符串拷贝到dest指向的数组空间,包括\0字符while (*dest++ = *src++){;}return ret;
}
int main()
{char arr1[] = "hello world";char arr2[20] = { 0 };//链式访问printf("%s\n", my_strcpy(arr2, arr1));return 0;
} 

🥰这些都是一些技巧,希望大家可以理解🥰

🥳6.编程常见的错误

🥰优秀的代码:

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

🚨做个用心的人!积累排错经验!

总结🥰
本文章是在 Visual Studio 2022(VS2022)编译环境下进行操作讲解
以上就是调试技巧下篇内容啦🥳🥳🥳🥳
希望我们可以做一个用心的人💕💕💕
小的会继续学习,继续努力带来更好的作品😊😊😊
创作写文不易,还多请各位大佬uu们多多支持哦🥰🥰🥰

请添加图片描述

相关文章:

实用调试技巧【下篇】

&#x1f534;本文章是在 Visual Studio 2022&#xff08;VS2022&#xff09;编译环境下进行操作讲解 文章目录3.2.调试的时候查看程序当前信息3.2.1.查看临时变量的值3.2.2.查看内存信息3.2.3.查看调用堆栈3.2.4.查看汇编信息&#x1f973;4.调试实例&#x1f973;5.如何写出&…...

【数据结构期末例题】

前言 本文是博主自己在准备学校数据结构考试时的总结&#xff0c;各个知识点都贴有对应的详细讲解文章以供大家参考&#xff1b;当然文中还有许许多多的截图&#xff0c;这些是博主对主要内容的摘取&#xff0c;对于那些基础较好的同学可以直接看截图&#xff0c;减少跳转对应文…...

管理物理和快照备数据库(Physical and Snapshot Standby Databases)

1&#xff0e;打开物理备数据库 物理备数据库可以打开做只读访问&#xff0c;用于从主数据库卸载查询负载。 如果已经购买Oracle Active Data Guard选项的授权&#xff0c;当数据库打开时Redo Apply可以是激活的&#xff0c;因此允许查询返回与从主数据库返回的完全相同的结果…...

双目立体视觉:SAD算法

算法原理SAD(Sum of absolute differences)是一种图像匹配算法。基本思想&#xff1a;差的绝对值之和。此算法常用于图像块匹配&#xff0c;将每个像素对应数值之差的绝对值求和&#xff0c;据此评估两个图像块的相似度。该算法快速、但并不精确&#xff0c;通常用于多级处理的…...

海外问卷调查答题技巧,纯干货分享,新手小白看过来

海外问卷调查为什么别人赚得盆满钵满而我却连通过都不行&#xff1f;是不是经常有人发出这种疑问&#xff0c;东哥作为一个结交过很多做问卷调查行业的跨境人士&#xff0c;也了解到很多做这一行的去答题的时候都是掌握一定技巧的&#xff0c;而不是去乱答。今天东哥就来说说国…...

【NGINX入门指北】Nginx Web 架构实验

Nginx Web 架构实验 文章目录Nginx Web 架构实验一、动态网站结构二、LNMP 动态网站环境部署三、fastcgi & php-fpm&#xff1a;四、php-fpm初始化配置五、Nginx Location、六、Nginx Rewrite七、CA&HTTPS八、Nginx 的平滑升级一、动态网站结构 资源 资源文件识别——…...

rtt-nano移植

nano其他功能移植 添加finsh组件打开宏实现rt_hw_console_getchar函数添加finsh组件到工程总结问题1. 移植到stm32G0过程中出现Undefined symbol rt_hw_interrupt_disable (referred from clock.o)??2. “implict declaration of function ‘ ‘ is invalid in c99??3. 关于…...

cnn+transformer

好的,下面是使用 Transformer 加 CNN 实现语义分割的代码,使用的数据集是 Semantic Segmentation Drone Dataset。 首先,我们需要导入必要的 Python 库和模块。我们将使用 PyTorch 深度学习框架来实现模型: #python import torch import torch.nn as nn import torch.nn.fu…...

Python fileinput模块:逐行读取多个文件

前面章节中&#xff0c;我们学会了使用 open() 和 read()&#xff08;或者 readline()、readlines() &#xff09;组合&#xff0c;来读取单个文件中的数据。但在某些场景中&#xff0c;可能需要读取多个文件的数据&#xff0c;这种情况下&#xff0c;再使用这个组合&#xff0…...

Vue3路由传参

vue3路由和vue2差别不是很大&#xff0c;不过在传参形式上略有改变 在Vue3中使用路由必须引入 useRouter 和 useRoute import { useRoute, useRouter } from vue-routerconst Router useRouter() //跳转const Route useRoute() //获取到值 同Vue2一样&#xff0c;query使用p…...

用户管理——认证功能JWT和Session

目录用户认证功能的技术选型JWT和Session的区别基于JWT和Session的认证流程基于JWT的认证流程基于Session的认证流程基于JWT和Session的认证的优缺点基于JWT和Session的认证的安全性基于JWT和Session的认证的性能分析基于JWT的一次性和无法废弃基于JWT和Session的认证的续签选择…...

hashlib — 加密哈希算法

hashlib — 加密哈希算法 1.概述 加密可以保护消息的安全&#xff0c;以便验证它们的准确性并且使它们受保护不被拦截。 Python 的加密方式支持包括利用像 MD5 和 SHA 这样的标准算法对消息内容产生签名的 hashlib 和验证消息没有在传输过程中被改变的 hmac hashlib 哈希库模…...

四喜临门选股预警源码指标

{四喜临门选股预警} AP1:CROSS(MA(C,5),MA(C,10)); RSV:(CLOSE-LLV(LOW,9))/(HHV(HIGH,9)-LLV(LOW,9))*100; K:SMA(RSV,3,1); D:SMA(K,3,1); AP2:CROSS(K,D); DIFF:EMA(CLOSE,12) - EMA(CLOSE,26); DEA:EMA(DIFF,9); AP3:CROSS(DIFF,DEA); AP4:CROSS(MA(V,5),MA(V,10)); GYTJ1:…...

Kotlin新手教程五(扩展)

一、扩展 在Kotlin中可以给一个类添加一个新的方法而不用继承该类或者使用设计模式&#xff0c;这样的方法称为扩展。 1.扩展函数 声明一个扩展函数&#xff0c;我们需要用一个 接收者类型 也就是被扩展的类型来作为他的前缀。 下面代码为 MutableList 添加一个swap 函数&am…...

QT入门Containers之Widget、Frame

目录 一、QWidget界面相关 1、布局介绍 2、基本界面属性 3、特殊属性 二、QFrame 三、Demo展示 此文为作者原创&#xff0c;创作不易&#xff0c;转载请标明出处&#xff01; 一、QWidget界面相关 1、布局介绍 为什么将QWidget容器放在第一个&#xff0c;因为目前使用过…...

数据结构与算法基础-学习-12-线性表之顺序队

一、个人理解队列是线性表的衍生之一&#xff0c;具有先进先出的特性&#xff0c;在队尾进行插入操作&#xff0c;在队头进行删除操作。队列的存储结构分为两个大类&#xff0c;一种是顺序队&#xff0c;就是用数组实现。另一种就是链队&#xff0c;使用链表实现。顺序队存在真…...

Python 字典(Dictionary)小窍门

字典是另一种可变容器模型&#xff0c;且可存储任意类型对象。字典的每个键值 key:value 对用冒号 : 分割&#xff0c;每个键值对之间用逗号 , 分割&#xff0c;整个字典包括在花括号 {} 中 ,格式如下所示&#xff1a;d {key1 : value1, key2 : value2 }注意&#xff1a;dict …...

知识图谱构建技术综述

摘要 *知识图谱为实现语义化智能搜索以及知识互联打下了基础&#xff0c;。&#xff0c; *随着知识的发展&#xff0c;传统的基于模板和规则构建的知识图谱已经被深度学习所替代。 知识组织得原则中&#xff1a;知识的充分性、有序性和标准化规则。深度学习的效果在很大程度上…...

环境变量和进程地址空间

目录 环境变量&#xff1a; env&#xff1a;显示所有的环境变量&#xff1a; echo $环境变量名表示查看环境变量的值 理解环境变量&#xff1a; getenv&#xff1a;显示环境变量的值 export set命令&#xff1a;显示所有变量 unset取消变量&#xff1a; pwd&#xff1a;当…...

【数据结构】栈和队列

目录 一、栈 1、栈的定义 2、栈的模拟实现&#xff08;顺序栈&#xff09; 1、创建一个顺序结构的栈 2、实现压栈方法&#xff08;push&#xff09; 3、模拟实现pop方法&#xff08;出栈&#xff09; 4、模拟实现peek(查看) 5、测试上述方法 3、栈的应用场景 1、改变元…...

Jsxer:Adobe ExtendScript JSXBIN反编译终极指南与深度解析

Jsxer&#xff1a;Adobe ExtendScript JSXBIN反编译终极指南与深度解析 【免费下载链接】jsxer A fast and accurate JSXBIN decompiler. 项目地址: https://gitcode.com/gh_mirrors/js/jsxer Jsxer是一款高性能的Adobe ExtendScript二进制格式&#xff08;JSXBIN&#…...

模拟工程师必备:口袋参考指南的实战价值与核心应用

1. 为什么每个硬件工程师都需要一本“口袋参考书”&#xff1f;前几天整理书桌&#xff0c;翻出来一本2016年从TI官网下载打印的《模拟工程师口袋参考指南》&#xff0c;纸张已经有点发黄&#xff0c;边角也卷了。但就是这么一本薄薄的小册子&#xff0c;从毕业到现在&#xff…...

Midjourney v7新功能全维度压测报告(v6 vs v7实测对比:提示词容错率↑47%,构图理解准确率突破92.6%)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Midjourney v7新功能全面解析 Midjourney v7 于2024年第三季度正式发布&#xff0c;标志着AI图像生成在语义理解、构图控制与跨模态一致性方面迈入新阶段。本次升级不再仅依赖提示词&#xff08;prompt…...

百度文库文档免费下载终极指南:3步快速获取纯净PDF

百度文库文档免费下载终极指南&#xff1a;3步快速获取纯净PDF 【免费下载链接】baidu-wenku fetch the document for free 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wenku 你是否曾在百度文库找到心仪的文档&#xff0c;却被烦人的广告、付费提示和杂乱页面…...

C语言-指针二

一. 指针的操作int main() {int a 10 , b 20, c 30;int *p NULL, *q NULL;p &a;//对指针变量p本身进行修改b *p;//*p为右值表示对变量a的读取*p 60;//*p为左值表示通过指向的内存空间对变量a的写入p &c;//p指向的内存空间发生变化b *p;//对c的读取操作*p 70…...

如何解决QQ音乐下载的歌曲在其他设备上无法播放的问题

如何解决QQ音乐下载的歌曲在其他设备上无法播放的问题 【免费下载链接】qmcflac2mp3 直接将qmcflac文件转换成mp3文件&#xff0c;突破QQ音乐的格式限制 项目地址: https://gitcode.com/gh_mirrors/qm/qmcflac2mp3 你是否曾经在QQ音乐下载了喜欢的歌曲&#xff0c;却发现…...

Windows 10/11下MySQL 8.0.28安装失败?‘服务没有响应控制功能’报错保姆级修复指南

Windows平台MySQL安装报错终极解决方案&#xff1a;从"服务无响应"到完美运行 遇到MySQL安装过程中弹出"服务没有响应控制功能"的红色报错窗口时&#xff0c;很多开发者第一反应是重装系统或更换数据库——别急&#xff01;这个看似复杂的错误其实90%以上源…...

企业内如何安全地通过Taotoken管理各部门的AI模型使用权限

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 企业内如何安全地通过Taotoken管理各部门的AI模型使用权限 对于中大型企业而言&#xff0c;引入大模型能力是提升效率的关键一步&a…...

BookGet:一键下载全球50+图书馆古籍资源的智能工具指南

BookGet&#xff1a;一键下载全球50图书馆古籍资源的智能工具指南 【免费下载链接】bookget bookget 数字古籍图书下载工具。 项目地址: https://gitcode.com/gh_mirrors/bo/bookget 你是否曾为查找古籍资料而奔波于各大数字图书馆&#xff1f;是否因为复杂的下载流程而…...

多渠道订单数据处理自动化,落地步骤与ERP打通方案 | 2026企业级智能体实战手册

在2026年的数字化转型深水区&#xff0c;企业面临的不再是“是否要自动化”的问题&#xff0c; 而是如何在高并发、多维度的全渠道业务压力下&#xff0c; 实现订单流、资金流与信息流的绝对同步。 传统的OMS&#xff08;订单管理系统&#xff09;与ERP&#xff08;企业资源计划…...