深入理解指针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,指针使⽤之前检查有效性;避免返回局部变量的地址等等

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构学不会?数据结构可视化网站来了

目录 前言 图码网站 算法可视化 算法编辑器 数据结构全书 数据结构课程 总结 前言 数据结构与算法在计算机的学习中应该是许多小白最头疼的东西,明明听的时候那么容易,为什么转换成代码就那么抽象呢? 有没有一个网站可以数据结构与算…

【RabbitMQ 三】Java客户端开发

本文引用的代码源自《RabbitMQ实战指南》 关键的类和接口主要有Channel、Connection、ConnectionFactory、Consumer等,它们主要的作用如下: Channel:实现AMQP协议层的操作Connection:开启信道(Channel)、注…

k8s集群统一设置时间

1 安装时间同步需要软件 yum install -y ntpdate2 设置时间 2.1 手动设置时间 date -s "20190712 18:30:50" hwclock --systohc2.2 在线更新时间 ntpdate 0.asia.pool.ntp.org # 强制把系统时间写入CMOS clock -w3 强制把系统时间写入CMOS hwclock作用与clock相…

【复杂网络】如何用简易通俗的方式快速理解什么是“相对重要节点挖掘”?

什么是相对重要节点? 一、相对重要节点的定义二、如何区分相对重要节点与重要节点?1. 相对重要性与节点相似性2. 识别相对重要节点的两个阶段第一阶段:个体重要性值的计算第二阶段:累积重要性值的计算 三、经典的相对重要节点挖掘…

08 - 条件判断语句

---- 整理自狄泰软件唐佐林老师课程 文章目录 1. 条件判断语句2. 语法说明3. 经验4. 代码 1. 条件判断语句 makefile 中支持条件判断语句 可以根据条件的值来决定 make 的执行可以比较两个不同变量或者变量和常量的值 注:条件判断语句只能用于控制 make 实际执行的…

探索大模型能力--prompt工程

1 prompt工程是什么 1.1 什么是Prompt? LLM大语言模型终究也只是一个工具,我们不可能每个人都去训一个大模型,但是我们可以思考如何利用好大模型,让他提升我们的工作效率。就像计算器工具一样,要你算10的10倍&#x…

今天看到一个有意思的问题:个人网站被恶意大量访问,怎么办(文末附GPT指令优化)

目录 问题描述 一、GPT 3.5 二、通义千问 三、讯飞星火 四、文心一言 五、Kimi 六、智谱清言 个人分析: 问题描述 大家好!我的个人网站每天晚上7点30到11点被固定的十几个IP大量下载exe,造成网站带宽不够,怎么办! 已经把…

大模型系列之解读MoE

Mixtral 8x7B 的推出, 使我们开始更多地关注 基于MoE 的大模型架构, 那么,什么是MoE呢? 1. MoE溯源 MoE的概念起源于 1991 年的论文 Adaptive Mixture of Local Experts(https://www.cs.toronto.edu/~hinton/absps/jjn…

如何在Android设备上恢复丢失的照片

Android手机或平板电脑上的照片丢失了?不要惊慌,您也许可以恢复它们。 由于我们的大量数据和日常生活都存储在一台设备上,有时将所有照片存储在本地的 Android 智能手机或平板电脑上可能是一项冒险的工作。无论是通过事故(损坏、…

python数据分析常用基础语法

Python语言基础——语法基础 前言一、变量的介绍与使用变量的介绍变量命名规则变量的使用拓展 二、标识符标识符命名命名规则注意事项 三、数据类型数据类型的介绍数据类型的查看示例 四、输入与输出输入和输出的介绍format格式化输出占位符 五、代码缩进与注释代码缩进 前言 …

最高20K/月,安全、数通、云计算多个方向急招,可内推!

高级安全工程师【岗位职责及要求】 1、统筹负责行业客户的安全项目交付,能够独自输出技术方案并完成施,并具备指导初中级工程师实施的能力; 2、掌握H3C全系列安全产品功能并对全系列产品原理有深入了解,能够熟练完成安全产品规划及…

如何找到台式电脑的ip地址

在数字时代,每台接入网络的设备都拥有一个独特的标识,这就是IP地址。无论是手机、笔记本电脑还是台式电脑,IP地址都扮演着至关重要的角色,它帮助设备在网络世界中定位并与其他设备进行通信。对于许多电脑用户来说,了解…

RK3576芯片规格,以及与RK3588对比

瑞芯微RK3576是一款高性能、低功耗的SoC(系统级芯片)处理器,适用于基于ARM的PC、边缘计算设备、个人移动互联网设备等多种应用场景。它采用Arm架构的八核心CPU,集成了GPU、MCU、NPU、VPU等多种计算核心,并具有丰富的外…

Python面向对象编程思想的深入学习

魔术方法的使用 案例体验 class Student:def __init__(self, name, age):self.name nameself.age age# __str__魔术方法, 如果不去写这个方法,那么print输出的则是信息存储的内存地址。def __str__(self):return fStudent类对象,name:{self.name}, ag…

SolidWorks进行热力学有限元分析一、模型建立

1.话不多说按照我的操作来 2.这一步鼠标移到中心点直接拉就行 3.这里选单位,继续按照操作来 4.选中这个边,直接拉,输入尺寸后确定,其他边同理 5.鼠标右键设置厚度 6.右键零件,然后编辑材料,给他赋予你需要的…

RapidJSON介绍

1.简介 RapidJSON 是一个 C 的 JSON 解析库,由腾讯开源。 支持 SAX 和 DOM 风格的 API,并且可以解析、生成和查询 JSON 数据。RapidJSON 快。它的性能可与strlen() 相比。可支持 SSE2/SSE4.2 加速。RapidJSON 独立。它不依赖于 BOOST 等外部库。它甚至…

ubuntu20安装colmap

系统环境 ubuntu20 ,cuda11.8 ,也安装了anaconda。因为根据colmap的官方文档说的,如果根据apt-get安装的话,默认是非cuda版本的,而我觉得既然都安装了cuda11.8了,自然也要安装cuda版本的colmap。 安装步骤…

力扣hot100:543. 二叉树的直径/108. 将有序数组转换为二叉搜索树

一、543. 二叉树的直径 LeetCode:543. 二叉树的直径 二叉树的直径 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。 遇到二叉树的问题很容易去直接用求解的目标去定义递归函数。但是仔细考虑,返回树的直径并不能向上传播。因此我们可以拆…

Git同步代码

Git中5个区,和具体操作? 代码提交和同步代码 代码撤销和撤销同步 平时是怎么提交代码的? 第零步: 工作区与仓库保持一致第一步: 文件增删改,变为已修改状态第二步: git add ,变为已暂存状态 $ git status $ git a…

HCIP的学习(OSPF总篇)

HCIA的复习 这边可以与我之前写的HCIA博客结合起来一起看,效果更好 HCIA的学习(6) OSPF状态机 down—关闭-----一旦启动OSPF进程,并发出hello报文,则进入下一个状态init----初始化状态------当收到的hello报文中存在…