指针?地址?内存?

1.地址和地址上存储的值:

  1. 地址:在计算机内存中,每个字节都有一个唯一的地址,用来标识它在内存中的位置。这个地址通常以十六进制表示,并且在程序运行时是固定的。指针就是用来存储和操作这些地址的变量,它们存储的是内存中某个对象或变量的地址。
  2. :内存地址中存储的实际数据,即在特定地址处存储的内容。这个值可以是任何数据类型,比如整数、字符、浮点数等。

所以当我们说“解引用一个指针”时,我们实际上是在获取该指针所指向地址处存储的值

通俗的讲,内存中的每个字节是实际存在的,我们用地址标识这些字节。而地址本身没有意义,只有解引用地址才能得到该地址对应的字节数据

并不是说一个地址只标识一个字节,
int *P,char *Q,对P保存的地址解引用*P可以得到一个8字节整型,对Q保存的地址解引用*Q可以得到一个4字节字符
。因此,我们可以通过强制转换指针的类型,修改它标识字节的范围!

刚才我们使用了变量P和Q的值也就是他们保存的地址,当然也可以变量P进行修改:P = Q,这时我们修改了内存里一个8字节的数据,但是我们没有使用地址,这是怎么做到的呢?

当我们执行 int *P; 这样的语句时,系统会为变量 P 分配一块内存,然后将其地址与标识符 P 关联起来。所以在实际使用时,我们不需要显式地使用地址,编译器会自动帮你完成地址的管理。

P = Q; 这样的语句中,编译器会知道 P 的地址,并将 Q 的值存储到该地址中。这个过程是由编译器隐式地完成的。你不需要手动获取 PQ 的地址,因为编译器已经知道P和Q的地址,可以直接将值存储到那个地址中。

也就是说我们虽然没有显式地解引用地址,然后对实际的字节进行修改,实际上标识符P已经和若干字节的地址关联起来了,所以我们在使用变量P和Q时,实际上就是通过解引用地址来操作实际的内存字节

只不过指针为我们提供了更灵活更强大的操作内存的方式,感谢指针!

2.二级指针进阶用法深入理解地址和内存的关系

二级指针也是指针,保存的也是地址,不论几级指针,只要是指针,就保存地址

二级指针的类型是确定的,是一个指针,一级指针的类型不确定

我们之前谈到了,改变指针类型,可以修改它标识内存中字节的范围,因此也就修改了这个指针解引用的结果

二级指针解引用的结果是内存中的8个字节,一级指针解引用的结果由它的类型确定,比如int是4字节,char是1字节,等等

说了这么多,将一级指针转换成二级指针有什么用呢?

举一个例子

typedef struct task_s { 
    void *next;  // 指向下一个task
    int a;
}task_t;

这是一个结构体,大小是8+4=12字节

下面我们将一级指针转换成二级指针:

01:  task_t *task = (task_t *)malloc(sizeof(task_t)); // 创建一个task_t对象
02:  task_t *p = (task_t *)malloc(sizeof(task_t)); // 创建另一个task_t对象
03:
04:  task->next = p; // 等价于(*task).next = p;
05:  *(task **)task = p; //将一级指针转换成二级指针,并解引用, 结果是next指针

注意,04行和05行是完全等价的,你看出来二级指针的用法了吗?

一级指针task和二级指针task指向的地址是同一个task_t对象的首地址

而它们的区别在于解引用的结果:

1.一级指针解引用的结果是12个字节也就是整个task_t对象,操作其中的next成员:task->next或(*task).next

2.二级指针解引用的结果不再是整个对象,而是task_t对象的前8个字节,刚好是next在内存中的位置,所以*(task **)task等价于next

为什么会有这样的区别?

答案在前文中提到过两次:改变指针类型,可以修改它标识内存中字节的范围,因此也就修改了这个指针解引用的结果

将一级指针转换成二级指针,指针所标识的内存中的字节的范围从12字节变为8字节,解引用的结果也因此改变

推荐学习https://xxetb.xetslk.com/s/p5Ibb

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

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

相关文章

unity ui 同屏

一共有三个摄像机,上屏,下屏 和 类似照相机的ccamera 类似照相机的ccamera的设置: 下屏摄像机设置: 下屏交互的Canvas设置: 新建一个canvas,下面放上rawimage: 如果下屏不想显示的内容&#xf…

【WEEK11】 【DAY2】Employee Management System Part 3【English Version】

2024.5.7 Tuesday Continuing from 【WEEK11】 【DAY1】Employee Management System Part 2【English Version】 Contents 10.4. Login Functionality10.4.1. Modify index.html10.4.2. Main Page Style Missing After Login Failure10.4.3. Create LoginController.java10.4.4…

【stomp 实战】spring websocket用户消息发送源码分析

这一节,我们学习用户消息是如何发送的。 消息的分类 spring websocket将消息分为两种,一种是给指定的用户发送(用户消息),一种是广播消息,即给所有用户发送消息。那怎么区分这两种消息呢?那就是用前缀了…

通过 Java 操作 redis -- list 列表基本命令

目录 使用命令 lpush,lrange,rpush 使用命令 lpop 和 rpop 使用命令 blpop,brpop 使用命令 llen 关于 redis list 列表类型的相关命令推荐看Redis - list 列表 要想通过 Java 操作 redis,首先要连接上 redis 服务器&#xff…

抽象类基本概念

抽象类及抽象方法 概念:一个类中没有包含足够的信息来描绘一个具体的对象,这种类被定义为抽象类,含有抽象方法的类也被称为抽象类。 用通俗的话来说就是当一个类的某个功能(方法)实现不确定时,我们就将该…

【Hadoop】MapReduce (七)

MapReduce 执行流程 MapTask执行流程 Read:读取阶段 MapTask会调用InputFormat中的getSplits方法来对文件进行切片切片之后,针对每一个Split,产生一个RecordReader流用于读取数据数据是以Key-Value形式来产生,交给map方法来处理…

RAFT:引领 Llama 在 RAG 中发展

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

Java面试八股文(MySQL篇)

数据库三范式 数据库事务介绍 索引介绍 SQL优化手段 mysql union 与 union all 语法及用法 并发事务带来的问题 大表如何优化 索引类型介绍 MYSQL数据库锁介绍

代码审计-PHP模型开发篇MVC层动态调试未授权脆弱鉴权未引用错误逻辑

知识点 1、PHP审计-动态调试-未授权安全 2、PHP审计-文件对比-未授权安全 3、PHP审计-未授权访问-三种形态动态调试优点 1、实时跟踪代码执行流程 2、实时获取变量接受数据 3、实时分析指定文件动态 环境配置:https://blog.csdn.net/m0_60571842/article/details/…

您可以使用WordPress创建的19种网站类型

当人们决定为什么他们应该使用WordPress时,我们经常会被问到“WordPress可以做[空白]吗?答案大多是肯定的。在本文中,我们将向您展示您可以使用WordPress创建的19种不同类型的网站,而无需学习任何编程技巧。 目录 隐藏 1 开始使用…

JS-拖拽元素放大缩小

效果左右布局&#xff0c;拖拽后&#xff0c;宽度放大缩小 其实自己写也可以&#xff0c;不过还是发现了两个好用的js库&#xff0c;既然不需要自己写&#xff0c;当然是能偷懒就偷懒 1、resizerjs 官网地址&#xff1a;https://github.com/eknowles/resizerjs <!doctype …

Milvus Cloud 的RAG 的广泛应用及其独特优势

一个典型的 RAG 框架可以分为检索器(Retriever)和生成器(Generator)两块,检索过程包括为数据(如 Documents)做切分、嵌入向量(Embedding)、并构建索引(Chunks Vectors),再通过向量检索以召回相关结果,而生成过程则是利用基于检索结果(Context)增强的 Prompt 来激…

C语言22行代码,让你的朋友以为中了病毒

1 **C语言介绍 ** C语言是一种计算机编程语言&#xff0c;由丹尼斯里奇&#xff08;Dennis Ritchie&#xff09;在1972年左右为UNIX操作系统设计并开发。它具有高效、可移植、灵活和强大的特点&#xff0c;在计算机科学领域中具有广泛的应用。C语言是一种结构化语言&#xff0…

【原创】不同RTOS中POSIX接口的实现差异

文章目录 前言POSIX简介RTOS对POSIX的实现情况ZephyrFreeRTOS RTOS提供的POSIX接口实时吗&#xff1f;nanosleepTimer-不同linux版本和xenomai的实现差异PREEMPT-RT Timer实现原理Xenomai Timer实现原理 总结参考 前言 在开发实时应用时&#xff0c;我们希望软件具备良好的跨平…

用于密集预测任务的通道知识蒸馏——关键字:蒸馏

摘要 https://arxiv.org/pdf/2011.13256 知识蒸馏(KD)已被证明是训练紧凑密集预测模型的简单有效工具。通过从大型教师网络转移而来的额外监督来训练轻量级学生网络。大多数先前的针对密集预测任务的KD变体都在空间域中对学生网络和教师网络的激活图进行对齐,通常是通过在每…

实验9:WLAN配置管理(课内实验)

实验9&#xff1a;WLAN配置管理 实验目的及要求&#xff1a; 掌握无线局域网络无线路由器和无线网络控制器的配置与应用。能够完成配置SSID隐藏、密码认证&#xff0c;远程站点WLAN配置和WLC配置等无线网络配置&#xff0c;完成网络连通性测试。 实验设备&#xff1a; 无线…

吴恩达2022机器学习专项课程C2(高级学习算法)W1(神经网络):2.5 更复杂的神经网络

目录 示例填写第三层的层数1.问题2.答案 公式&#xff1a;计算任意层的激活值激活函数 示例 层数有4层&#xff0c;不包括输入层。 填写第三层的层数 1.问题 你能把第二个神经元的上标和下标填写出来吗&#xff1f; 2.答案 根据公式g(wxb)&#xff0c;这里的x对应的是上…

C# IO下的文件和目录详解

文章目录 1、文件和目录的基本概念2、文件的操作方法打开文件&#xff1a;读取文件&#xff1a;写入文件&#xff1a;删除文件&#xff1a;文件权限 3、目录的操作方法创建目录&#xff1a;遍历目录&#xff1a;删除目录目录权限 4、文件和目录的属性与信息5、文件和目录的相对…

钟表——蓝桥杯十三届2022国赛大学B组真题

问题分析 这个问题的关键有两点&#xff1a;1.怎么计算时针&#xff0c;分针&#xff0c;秒针之间的夹角&#xff0c;2.时针&#xff0c;分针&#xff0c;秒针都是匀速运动的&#xff0c;并非跳跃性的。问题1很好解决看下面的代码就能明白&#xff0c;我们先考虑问题2&#xf…

数字图像处理知识点

数字图像处理知识点 一、绪论1、数字图像处理相关概念2、数字图像处理流程1.3 数字图像处理主要研究内容二、视觉与色度基础1、图像传感器与二维成像原理2、三基色2.1 三基色原理2.2 亮度方程3、HSI模型3.1 HSI模型优点3.2 RGB到HSI转换三、数字图像处理基础1、图像的数字化及表…
最新文章