调试-一些奇怪的现象-以及const的作用

news2024/11/23 13:25:21

今天给大家看一些奇怪的例子,我们用调试来看看这到底是什么情况,本次选取环境为vs2019

话不多说,我们直接来看例子

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

大家先猜猜这段代码的运行结果吧。

正常情况,这个代码是错误的,产生了越界,但也是可以运行起来的,它会打印13个hehe,那是不是这样呢?我们来看结果

 ???大家肯定会很疑惑,这是什么情况?为什么会陷入死循环呢?别急,我们来一步一步看

我们先调试走到arr[10],然后接着往下看

 

 

我们看到,这个代码是非常危险的,它直接把arr[11]的内容给修改为0了,刚才的arr[10]也是同理,那么是不是下面的也是这样呢?

 

诶?为什么arr[12]里的值是12呢?是不是arr[12]里的随机值刚好是12?我们接着走一步

  

走完一步后发现,arr[12]的值变为了0,但是这个调试例子让我们发现此时的i也变成了0,很明显这不是巧合,刚才arr[12]里的12,就是i的值,这究竟是怎么一回事?我们来到内存看看

我们可以看到,这是数组在内存里的情况,此时的代码已经完成了arr[11]=0的赋值,我们仔细一数会发现有12个0,我们再来看看i的内存情况吧

 

是0c000000 ,刚好是12,说明此时i的值还是12,我们再结合上面的内存图来看会发现,在arr数组下面刚好也有个12,仔细看会发现地址是相同的,这是怎么回事?

我们知道,这些数组都是放在栈里面的,而栈的使用习惯是先使用高地址,再使用低地址,也就是说,这段代码会先给i放在高地址的空间里,然后把数组arr放在i前面的低地址空间里,而我们每次给数组+1后,随着数组下标的增长,会不断向高地址前进,越界后到达一定程度,会使得arr[i]到达i所在空间,此时赋值为0会修改i的值,导致循环出现问题,从而导致死循环,所以我们平时都要注意不要越界访问,否则是很危险的。

而且这段代码仅仅是在vs2019的情况下才会出现这种情况,我调换一下代码位置,比如说先创建arr,再创建变量i,也不会出现死循环,这段代码是设置好的,是特定的

 经过这段代码我们发现,i和arr之间刚好有2个整形空间,这是在vs2019的环境下,编译器的不同,也会导致结果的不同,经过测试,在vc6.0里,arr和i之间是没有空余空间的,在gcc里,i和arr之间有一个整形的空余空间。

这段代码是希望告诉我们,在我们遇到不明白的情况,要勇于调试自己解决问题,而不是遇到困难就放弃,或者之间去网上查,一定要先尝试自己解决,自己解决不了,再去寻求帮助,只有这样,才能成为一个好的程序员

知道了这些,我们接着来看一看const的作用

我们知道,变量加了const后会使变量无法修改

 但是我们学习了指针后就可以绕过const

这样就被人钻了空子,const不就没用了吗?

我们可以这样做

 

给指针也加上const,这样就无法通过指针修改变量a了 

或者这样,我们发现,const和int的位置并不影响,只要const在*左边就可以

const放在*的左边,const修饰的是指针指向的内容,表示指针指向的内容,不能通过指针来改变了,但是指针变量本身可以修改 

就像这样,a的值此时是不可修改,并且不可以通过修改指针p所指向a而直接修改a,但是指针本身是可以修改的,我们可以让它指向别的变量

 

但是指向别的变量后也是无法修改变量的

另外重新创建指针变量指向a,也是可以修改a的值的

知道了const在*左边的作用后,我们来看看const在*右边又是什么作用

 

 

根据这两段代码我们发现

const放在*的右边,const修饰的指针变量本身,表示指针变量本身的内容不能被修改,但是指针指向的内容,可以通过指针来改变。 

知道了const在左边和右边的区别后,我们可以这样写

 很有趣吧?

加入const,可以使代码变得更加安全,所以我们在看c语言库函数是怎么实现的时候,会发现很多都是加了const的,我们要多看源码,看优秀的代码,吸收他人的优点,站在巨人的肩膀上,才能看的更远

最后再补充一个知识

编程常见错误以及如何解决

1.编译型错误:直接看错误提示信息(双击),解决问题。或者凭借经验就可以搞定。相对来说简单。

2.链接型错误: 

看错误提示信息,主要在代码中找到错误信息中的标识符,然后定位问题所在。一般是标识符名不存在或者拼写错误 

3. 运行时错误:
借助调试,逐步定位问题。最难搞。

以上就是全部内容,希望大家可以有所收获。

如有错误,还请指正。

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

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

相关文章

压缩包加密、解密

压缩包文件大家都经常使用&#xff0c;经常用来压缩文件之后再转发给别人&#xff0c;网上下载的软件&#xff0c;有时候也是压缩包形式下载下来&#xff0c;解压之后才是软件。相信大家一定也遇到过加密的压缩包文件。今天和大家分享如何加密压缩包&#xff0c;以及如何解密压…

114.(leaflet篇)leaflet空间判断-点与圆的空间关系

听老人家说:多看美女会长寿 地图之家总目录(订阅之前建议先查看该博客) 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <!DOCTYPE html> <html>

【SpringBoot】对于yaml的详细学习和三种属性赋值的实战详解

一.yaml详细讲解 1.1 什么是yaml&#xff1f; YAML是一种数据序列化语言&#xff0c;通常用于编写配置文件。业界对YAML有不同的看法。有些人会说YAML代表另一种标记语言。其他人认为“YAML不是标记语言”&#xff08;“YAML并非标记语言”&#xff09;。“YAML”只是这句话的…

CentOS中使用Docker部署带postgis的postgresql

场景 CentOS中使用Docker来部署Postgresql&#xff1a; CentOS中使用Docker来部署Postgresql_霸道流氓气质的博客-CSDN博客 上面安装的postgresql还需自行安装postgis插件&#xff0c;是否可以直接安装带postgis插件的postgresql。 注&#xff1a; 博客&#xff1a;https:…

RKMEDIA使用简介

瑞芯微&#xff08;rockchip&#xff09;芯片现在嵌入式行业使用的逐渐多了&#xff0c;本栏主要介绍rv1126/rv1109上的媒体框架 rkmedia的使用以及常遇到的问题。 希望可以给各位使用rkmedia的小伙伴一些帮助&#xff0c;同时也是自己工作的记录。 rkmedia的手册在sdk目录下/…

windows10系统安装nvm切换电脑node版本

介绍 nvm 是 node version manager&#xff08;node 版本管理工具&#xff09;的缩写&#xff0c;是一个命令行工具&#xff0c;用于管理和切换到不同版本的 node.js。 不同的项目可能需要不同版本的 node.js 和 npm&#xff08;node 包管理器&#xff09;&#xff0c;例如&a…

(二)devops持续集成开发——jenkins的权限管理配置

前言 jenkins作为目前主流的devops工具&#xff0c;受到了广大开发用户的追捧。由于其丰富的插件库&#xff0c;其可插拔的功能使得其功能和生态都十分强大。本节内容是关于jenkins的权限管理组件Role-based Authorization Strategy的安装及使用。 正文 下载安装Role-based A…

极验--一键通过模式逆向分析

内容仅供参考学习 目标 网址&#xff1a;https://www.geetest.com/demo/fullpage.html 这次只是简单的进行一次分析&#xff0c;如果有需要可以直接看最后 流程分析 打开调试工具&#xff0c;刷新一下页面&#xff0c;获取初始的交互信息&#xff1a; 先看第一个&#x…

3.RabbitMQ工作模式介绍

3.RabbitMQ工作模式介绍.md 文章目录3.RabbitMQ工作模式介绍.md1.简单模式1.1总结2.Work Queues 工作队列模式2.1 模式说明2.2 代码编写2.3 总结3.Pub/Sub 订阅模式3.1 模式说明3.2 使用场景3.3 代码实现3.4 总结&#xff1a;4.Routing 路由模式4.1 模式说明4.2 代码编写4.3 总…

CAS:304014-13-9,淬灭剂QSY21 NHS ,QSY 21NHS 试剂供应

一&#xff1a;产品描述 1、名称 QSY 21NHS 淬灭剂QSY21 NHS 淬灭剂QSY21 NHS ester 2、CAS编号&#xff1a;304014-13-9 3、分子式&#xff1a;C45H39ClN4O7S 4、分子量&#xff1a;815.34 5、外观&#xff1a; 紫色固体 &#xff08;具体由其分子量大小决定外观&am…

ORB-SLAM2 ---- KeyFrameDatabase::DetectRelocalizationCandidates函数

目录 1.函数作用 2.步骤 3.code 4.函数解析 4.1 找出和当前帧具有公共单词(word)的所有关键帧 4.2 统计上述关键帧中与当前帧F具有共同单词最多的单词数maxCommonWords&#xff0c;用来设定阈值1 4.3 遍历上述关键帧&#xff0c;挑选出共有单词数大于阈值1的及其和当…

JUC并发编程第五篇,如何优雅的使用线程中断机制和线程等待唤醒机制?

JUC并发编程第五篇&#xff0c;如何优雅的使用线程中断机制和线程等待唤醒机制&#xff1f;一、线程中断机制1. 什么是线程中断&#xff1f;2. 你知道 interrupt() 方法的含义吗&#xff1f;3. 如何使用中断标识优雅的停止线程&#xff1f;第一种&#xff1a;通过volatile变量实…

元年智答|数据洞察功能介绍

什么是数据洞察 随着企业积累数据量增多&#xff0c;数据分析师常常需要处理“长且宽”的数据集。依靠人的经验处理海量数据&#xff0c;从海量数据中发掘出有用的信息无异于大海捞针。虽然人工智能技术的普及和单位算力价格的下降大大降低了数据挖掘的门槛&#xff0c;但是面…

消息队列概述与扩展

一、消息队列的特性 与业务解藕&#xff1a;一个具有普适性质的消息队列组件不需要考虑上层的业务模型&#xff0c;只做好消息的分发就可以了&#xff0c;上层业务的不同模块反而需要依赖消息队列所定义的规范进行通信。FIFO&#xff1a;先投递先到达的保证是一个消息队列和一…

【HTML】猜拳小游戏

博主&#xff1a;&#x1f44d;不许代码码上红 欢迎&#xff1a;&#x1f40b;点赞、收藏、关注、评论。 格言&#xff1a; 大鹏一日同风起&#xff0c;扶摇直上九万里。 文章目录一、HTML完整源码二、效果三、完整资源文件一、HTML完整源码 <!DOCTYPE html PUBLIC "…

文本分类方案,飞浆PaddleNLP涵盖了所有

文章目录1.前言2.核心技术2.1 文本分类方案全覆盖2.1.1 分类场景齐全2.1.2 多方案满足定制需求方案一&#xff1a;预训练模型微调方案二&#xff1a;提示学习方案三&#xff1a;语义索引2.2 更懂中文的训练基座2.3 高效模型调优方案2.4 产业级全流程方案3. 快速开始4. 常用中文…

Photoshop、Illustrator、Sketch哪个更好

以前在交流组经常能看到大家争论哪个设计软件好&#xff1f;到底是你的吗&#xff1f;Illustrator好还是我的CorelDRAW或者他的Photoshop强大&#xff1f;但是跟着UI流行的设计&#xff0c;Sketch软件也加入了争论&#xff01;让我们和你分享一下这篇文章。让我们来看看平面设计…

云原生周刊 | AWS 开源 macOS 容器开发工具 Finch | 2022-11-28

今年的北美 KubeCon 大会结束后&#xff0c;来自 uptime.build 的 Jan Mundin 给会场的所有展台都拍了照&#xff0c;详细分析展台上的每一个单词&#xff0c;并汇总成了词云&#xff0c;其中热门词汇只有“安全”和“平台”&#xff0c;并不包含“自动化”和 DevOps。整个会场…

第四章 数字逻辑电路设计方法【Verilog】

第四章 数字逻辑电路设计方法【Verilog】前言推荐第四章 数字逻辑电路设计方法概览4.2 组合逻辑设计裁判表决电路方法1&#xff1a;真值表方式方法2&#xff1a;逻辑代数方式方法3&#xff1a;结构描述方式方法4&#xff1a;抽象描述方式测试结果4.2.1数字加法器2输入1 bit信号…

ATJ2157ATJ2127音乐按文件名拼音排序---标案是按内码进行排序

音乐按文件名拼音进行排序参考网站ATJ2157&ATJ2127 排序是按照内码(汉字为GBK即GBK936)排序的按拼音排序unicode与拼音的对比表(U2P.DAT)&#xff0c;需要打包到固件中U2P.DAT数据结构U2P.DAT生成代码是使用DEV-C生成其他说明U2P.DAT与ATJ2127平台代码参考网站 各种字符对…