深入理解指针1

目录

如对您有帮助,还望三连支持,谢谢!!!

1.内存和地址

计算机中常⻅的单位(补充):

如何理解编址

2.指针变量和地址

2.1取地址操作符(&)

2.2指针变量和解引用操作符(*)

2.2-1指针变量

2.2-2如何理解指针变量

2.2-3解引用操作符

2.3指针变量的大小

3.指针变量类型的意义

3.1指针的解引用:

3.2指针+-整数:

4.const修饰指针

4.1const指针变量:

4.2const修饰指针变量:

5.指针运算

5.1指针+-整数

5.2指针-指针

5.3指针关系运算

6.野指针

指针未初始化:

指针越界访问:

指针指向已经释放了的空间:


如对您有帮助,还望三连支持,谢谢!!!

前言:指针通常被认为是c语言中比较难的知识,今天我们就来用大致5篇文章来带领大家深入理解指针,使读者对指针有更加深刻的认识。

1.内存和地址

在讲解指针之前,我们要先了解一下内存和地址,由于指针知识相对有点小抽象,所以我们尽量以举例子的形式给大家讲解,就比如我们生活中的例子:

我们上大学时为了管理学生,把学生分配到了一个个的宿舍房间中,每个房间都有固定的人数:比如6人寝,4人寝。

我们姑且认为是八人寝(有点夸张了哈哈):

一个寝室由八个人组成,而这个寝室就相当于一个内存单元;寝室里面的每个学生就相当于组成内存单元的一个比特位。

计算机内存就是由一个个内存单元(寝室)组成的,单位为字节。

了解了这个后,我么再来想一个问题:如果我要找二楼一个特定的房间,怎么找?

为了更好的管理寝室,每个寝室都有一个寝室号,也就是门牌号:

就如上图所示,有了门牌号,就能更加方便的找到我们想要的寝室了。

而门牌号就相当于地址,有了地址(门牌号),就能更快的找到特定的寝室(内存单元)。

通过这个例子,我们就对内存单元和地址的关系有了一个初步的了解。

放在计算机中来说:

我们知道计算上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数
据也会放回内存中,那我们买电脑的时候,电脑上内存是8GB/16GB/32GB等,那这些内存空间如何⾼效的管理呢?

其实也是把内存划分为⼀个个的内存单元,每个内存单元的⼤⼩取1个字节。

计算机中常⻅的单位(补充):


在生活中我们把门牌号叫做地址,在计算机中我们把内存单元的编号也成为地址,c语言给地址起了一个新的名字:指针

所以我们可以理解为:
内存单元的编号==地址==指针

如何理解编址

有读者会问,为什么地址是0XFFFFFFFF这个长度呢?长度不能是别的数了吗?这就涉及到计算机组成原理的知识了:

CPU访问内存中的某个字节空间,必须知道这个字节空间在内存的什么位置,⽽因为内存中字很多,所以需要给内存进⾏编址(就如同宿舍很多,需要给宿舍编号⼀样)。

计算机中的编址,并是把每个字节的地址记录下来,⽽是通过硬件设计完成的。

地址总线32位环境下有32根,所以地址长度为32,表示成16进制,所以才会是8个数字表示一个地址。

这里了解一下即可。

2.指针变量和地址

2.1取地址操作符(&)

理解了内存和地址的关系,我们再回到C语⾔,在C语⾔中创建变量其实就是向内存申请空间,⽐如:

⽐如,上述的代码就是创建了整型变量a,内存中申请4个字节,⽤于存放整数10,其中每个字节都有地址,我们通过调试可得到:

如上图所示,我们通过调试获取了整型变量a的地址,那么我们想要得到a的地址,又该怎么做呢?这时候就得用&操作符,代码如下:

如上图所示,我们就成功的取出了a的地址并将结果打印了出来,假设我们的打印结果006FFD70,则a在内存中的储存大致如下图所示:

我们取出了a的4个字节中最小的地址。虽然整型变量占⽤4个字节,我们只要知道了第⼀个字节地址,顺藤摸⽠访问到4个字节的数据也是可⾏的。

2.2指针变量和解引用操作符(*)

2.2-1指针变量

上面讲了如何取出a的地址,但是我们取出a的地址,要把他存放起来,以便以后使用,这时我们应该把它存放在哪里呢?

答案:指针变量

指针变量也是一个变量,用来存放地址,存在指针变量中的值会被认为是地址。

2.2-2如何理解指针变量

如上图,int*pa=&a,其中*说明pa是一个指针变量,int说明pa指向的是int类型的对象

那如果char b='w',这时候又该用什么类型的指针来接受呢?

char*pb=&b;

用char类型的指针接收char类型的数据地址。

2.2-3解引用操作符

们将地址保存起来,未来是要使⽤的,那怎么使⽤呢?
在现实⽣活中,我们使⽤地址要找到⼀个房间,在房间⾥可以拿去或者存放物品。
C语⾔中其实也是⼀样的,我们只要拿到了地址(指针),就可以通过地址(指针)找到地址(指针)

指向的对象,这⾥必须学习⼀个操作符叫解引⽤操作符(*)。

    上面的代码我们创建了一个整形a和一个int类型的指针pa指向a,

然后我们通过解引用操作符(*)找到a并将a的值修改为了1。

有同学肯定在想,这⾥如果⽬的就是把a改成0的话,写成 a = 0; 不就完了,为啥⾮要使⽤指针呢?
其实这⾥是把a的修改交给了pa来操作,这样对a的修改,就多了⼀种的途径,写代码就会更加灵活,后期慢慢就能理解了。 

2.3指针变量的大小

我们上面讲了指针变量存放的是地址,所以指针变量的大小取决于地址的大小。

而在X64环境中,有64根地址线,所以地址大小为8个字节。

在X86环境中,有32根地址线,所以地址大小为4个字节。

3.指针变量类型的意义

既然我们上面讲了不管什么类型的指针变量,大小都为4/8个字节,那么不同类型的指针变量又有什么意义呢?

3.1指针的解引用:

通过调试我们可以看到,代码一对pi解引用会把n的四个字节全部修改为0;

而代码二对pc解引用只会把n的第一个字节修改为0

由此我们可以得出以下结论:

指针的类型决定了:对指针解引用时有多大的访问权限(一次能访问操作几个字节)

比如:char*的指针解引用能访问一个字节,int*解引用能访问4个字节。

3.2指针+-整数:

代码运行结果如下:

我们通过上面的代码发现:pc指针加1跳过了一个字节(地址加了一),而pi指针加一跳过了四个字节(地址加了4)。这就是不同类型指针所带来的变化。

结论:指针的类型决定了指针向前或者向后走一步的距离有多大

4.const修饰指针

4.1const指针变量:

变量是可以被修改的,可以直接修改,也可以通过指针的方式修改,那么如果我们想要一个变量加上一些限制,使其不能被修改,该怎么做呢?这时就要用到const

那么,此时问题来了,被const修饰的变量的值一定能被修改吗?

答案:可以。

我们虽然不能直接修改,但是我们可以通过指针来访问改变量,从而修改该变量的值。

4.2const修饰指针变量:

这段代码,我们运行可以初步看出:const在*左边,影响的是指针指向的内容,是指针指向的内容不能被修改;const在*右边,影响的是指针本身,指针本身的值不能被修改。

结论:const修饰指针变量的时候
• const如果放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。
但是指针变量本⾝的内容可变。
• const如果放在*的右边,修饰的是指针变量本⾝,保证了指针变量的内容不能修改,但是指针指
向的内容,可以通过指针改变。

5.指针运算

指针运算大致可分为以下三种:

5.1指针+-整数

我们都知道数组在内存中是连续存放的,所以我们可以通过指针顺藤摸瓜打印出数组内容:

5.2指针-指针

strlen的模拟实现,这种方式就是指针减去指针,我们以前再讲字符串函数的时候讲过,不再赘述。

5.3指针关系运算

arr+sz指针跳过了整个数组,指向紧挨数组后面的地址;p初始时是数组首元素的地址,通过比较这两个指针,打印出来了数组的内容。

6.野指针

概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

指针未初始化:

指针越界访问:

指针指向已经释放了的空间:

所以我们在写代码时,要尽量的避开野指针。

避开野指针,我们就要养成良好的代码风格:指针变量不再使⽤时,及时置NULL,指针使⽤之前检查有效性;避免返回局部变量的地址等等

至此,我们已经初步认识了解了指针。下篇文章我们将更深层次的讲解指针的知识。

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

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

相关文章

多个开源的js补环境框架测试

原文链接:https://mp.weixin.qq.com/s/uEMFGpE5bqmTvzSgX2twvA 前言 在做js逆向时肯定会遇到补环境的情况,看到github开源了好几个补环境用的框架,这篇文章做个测试,看看哪个比较好用。 https://github.com/pysunday/sdenvhttp…

Spring Boot3.x集成Disruptor4.0

Disruptor介绍 Disruptor是一个高性能内存队列,研发的初衷是解决内存队列的延迟问题(在性能测试中发现竟然与I/O操作处于同样的数量级)。基于Disruptor开发的系统单线程能支撑每秒600万订单,2010年在QCon演讲后,获得了业界关注。2011年&…

前端学习|第五章

HTML5&CSS3 新特性 前言HTML5 新特性一、语义化标签二、多媒体标签三、新增 input 类型四、新增表单属性 CSS3 新特性一、新增选择器二、盒子模型三、图片模糊处理四、calc 函数五、过渡 - transition六、2D 转换 - transform七、动画 - animation八、3D 转换 - translate3…

数据库被Elbie勒索病毒加密可以恢复吗?

一、Elbie勒索病毒简介 Elbie勒索病毒是一种严重的网络安全威胁,它通过加密用户文件并索要高额赎金来获取解密密钥。该病毒通常通过电子邮件附件、恶意网站、社交媒体平台以及利用用户网站服务器上的漏洞进行传播。一旦感染,用户的文件将被加密&#xff…

我独自升级崛起下载方法分享 下载教程

《我独自升级:崛起》这款精彩绝伦的动作角色扮演游戏,灵感来源于大热网络漫画,让玩家亲自踏上主角程肖宇的征途,从觉醒初阶到实力飞跃,每一步成长都扣人心弦。值得注意的是,尽管全球正式发布日期定在了五月…

RT-DETR-20240507周更说明|更新Inner-IoU、Focal-IoU、Focaler-IoU等数十种IoU计算方式

RT-DETR改进专栏|包含主干、模块、注意力、损失函数等改进 专栏介绍 本专栏包含模块、卷积、检测头、损失等深度学习前沿改进,目前已有改进点70!每周更新。 20240507更新说明: ⭐⭐ 更新CIoU、DIoU、MDPIoU、GIoU、EIoU、SIoU、ShapeIou、PowerfulIoU、…

分析错误ValueError: could not determine the shape of object type ‘Series‘

这个错误提示 ValueError: could not determine the shape of object type Series 通常发生在尝试将 pandas 的 Series 直接转换为 PyTorch 的 tensor 时,尤其是当 Series 的数据类型不明确或者包含非数值类型的数据时。为了修正这个问题,确保在转换之前…

酷得智能电子方案 早教学习机

早教学习机是用户友好的,易于操作,同时要确保内容的科学性和适宜性,以促进儿童的健康成长和智力发展。 通常包括以下几个方面: 1.年龄分级内容:软件会根据儿童的不同年龄段提供相应的教育内容,从新生儿到…

FastDFS-单机扩容

描述 周一上班收到用户反馈系统异常,紧急排查日志发现报错:FdfsServerException:错误:28,错误信息:没有足够的存储空间。 解决 根据异常信息判断是文件服务器可用内存不够了,首先登录文件服务器,使用df -h命令查看一…

AIGC-3D数字人技术:高效助推各行业数字化水平升级

从“互联网”到“人工智能”,数字员工作为一种全新的交互形式,对企业有着重要的作用,企业、品牌通过数字人的AI语音交互、AI播报等核心功能,可以有效推动企业提升数字水平。 作为3D、AI虚拟数字人技术服务商及方案提供商&#xff…

Cargo - 构建 rust项目、管理依赖包

文章目录 关于 Cargo构建项目创建工程编译运行buildclean 管理依赖添加依赖updatecheck计时 manual rust 安装可参考:https://blog.csdn.net/lovechris00/article/details/124808034 关于 Cargo Cargo 官方文档 : https://doc.rust-lang.org/cargo/crat…

我写了一套几乎无敌的参数校验组件!基于 SpEL 的参数校验组件「SpEL Validator」

前言 大家好,我是阿杆,不是阿轩。 参数校验这个东西,很多情况下都是比较简单的,用 NotNull、Size 等注解就可以解决绝大多数场景,但也有一些场景是这些基本注解解决不了的,只能用一些其他的方式处理&…

OpenCV 入门(三)—— 车牌筛选

OpenCV 入门系列: OpenCV 入门(一)—— OpenCV 基础 OpenCV 入门(二)—— 车牌定位 OpenCV 入门(三)—— 车牌筛选 OpenCV 入门(四)—— 车牌号识别 OpenCV 入门&#xf…

批量将GOID转成GO term名并添加BP,MF,CC分类信息

基因本体论(Gene Ontology,GO,https://www.geneontology.org)是一个广泛应用于生物信息学领域的知识库,它提供了一套标准化的词汇和分类体系,用于描述基因功能、细胞组分和生物过程。GO旨在统一科研人员对基…

LeetCode刷题记(五):121~150题

121. 买卖股票的最佳时机 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从…

代码审计之某高校通用系统getRequsetURI函数的三次鉴权绕过

前言: 写个随笔,写个代码审计的漏洞案例,该系统为大量高校使用的一个系统。 三次绕过。 正文: 如图所见,系统厂商采用的是利用过滤器的写法进行鉴权 第一次的校验代码: 即requestURI转为小写后&#x…

SpringBoot中HandlerInterceptor拦截器的构建详细教程

作用范围:拦截器主要作用于Spring MVC的DispatcherServlet处理流程中,针对进入Controller层的请求进行拦截处理。它基于Java的反射机制,通过AOP(面向切面编程)的思想实现,因此它能够访问Spring容器中的Bean…

机器学习笔记-22

终章 至此吴恩达老师的机器学习课程已经完成啦,总结一下: 1.监督学习的算法:线性回归、逻辑回归、神经网络和向量机 2.无监督学习的算法:K-Means、PCA、异常检测 3.推荐系统、大规模数据处理、正则化、如何评估算法 4.上限分析、…

贪吃蛇大作战(C语言--实战项目)

朋友们!好久不见。经过一段时间的沉淀,我这篇文章来和大家分享贪吃蛇大作战这个游戏是怎么实现的。 (一).贪吃蛇背景了解及效果展示 首先相信贪吃蛇游戏绝对称的上是我们00后的童年,不仅是贪吃蛇还有俄罗斯⽅块&…