C语言——指针全讲

1、指针是什么:数据存于内存中,CPU如果要对数据进行处理首先就要找到相对应的数据,就是通过地址来找到的。就像你所在的公寓,你如果要找到你的房间就需要根据门牌号寻找。

      在CPU和内存之间有地址线连接,其中在x86环境下是32根地址线,在64位环境下有64根地址线。每根地址线有两种情况,可以反映2个地址,那么32根能反映2^32种,64根能反映2^64种。

2、指针的内存大小:我们如果要存储指针数据,就需需要足够的内存。在x86环境下要存放2^32次方个数据刚好就是要32bit大小也就是4个字节。在x64环境下要存放2^64种数据所以需要64个bit位,也就是8个字节。

       综上32位4字节,64位8字节。

3、如何得到内存的地址和使用内存的地址:这里有两个符号分别是 &取地址符号 *解引用符号

取地址符号顾名思义就是得到其地址,解引用符号是通过地址找到其对应的地址所存储的数据。

   两个操作符是进行相反的操作的,所以&*可以相互抵消。图中的*p就等价于*&a=a;

4、指针内存都是一样大的问什么还要区分指针类型?

      原因出在解引用的环节上,因为每种类型的数据会有不同的大小,需要1个或多个字节来存储全部。计算机读取这些数据不是一下全部读取的,是一个字节一个字节的进读取的。那么读取多少就决定的数据的准确性。所以指针类型是来决定解引用的时候计算机读取字节的长度的

       典型的例子可以看我上篇博客,冒泡排序通过指针类型强制转换来交换两个内存的数据https://blog.csdn.net/2301_80772499/article/details/136420805?spm=1001.2014.3001.5502

5、通过指针来进行内存操作:这里我们从第三点最下面得出的结论:&*可以相互抵消就可以理解到了。

6、指针的作用:我们为什么还要另外搞个指针呢?直接改变量不就完了。

      原因一:在函数的传参这部分。通过我前面讲的函数栈帧的创建和销毁这一篇博客可以知道,新函数的开辟会创建临时变量。如果直接想要对我们main函数里面的数据进行更改的化,通过改掉形参的数据是不可能实现的。形参和main函数传过去的实参完全不是一个东西。因此我们需要用到指针,通过指针的解引用来找到我们main函数里面的所以需要处理的变量。

总之就是让各个函数里面的非临时变量够通过临时的指针变量相互联系起来,而我们直接传参是不可能的。

      可能有人会说arr为什么不是的,其实我们传入的arr[]实际就是arr的地址。arr本身可以表示其地址,函数也是。

     原因二是:有时候我们和计算机对话的时候,例如要求它创建内存,计算机不可能自己创建一个变量给你然后你自己使用,你只能将它的地址储存起来从而找到所要创建的内存对象。

7、指针的加减: 

      指针加减数字:指针加减数字从内存角度来看:就是指针地址增一个类型单位或者减少一个类型单位,这里的类型单位就是只类型的大小,int 4字节 ,char 1字节等。我们让char类型指针加1就是在原来的地址上加1(char)个字节。如果从变量来看就是跳到它相邻的那个变量的地址去。

      指针减指针  :指针减指针就得到了两个变量之间的距离。可以用来求数组长度等。

8、指针存储的对象和对应的解引用:我们容易想到的就是各种类型的变量float int double long short char,结构体等,解引用也就直接加*就行。

      其实还有常数组、常变量也是可以的,例如"1234"就会存储它第一个字符的地址。

      还有数组这里有多种存储的方式

      首先我们看一维数组,这里我们要理解到 如果有一个数组为arr  ,用指针接收arr是接收它的地址,我们令arr=&parr,parr才是最内层级别的。

      

        这里的p实际上指的是(arr[0]) &parr[0]也就是第一个元素的地址,我们如果对地址进行++,那么通过数组内存连续存放的原理可以遍历所有的元素。

      存储数组的地址,p指向整个数组

     

      这里我们可以这样理解,单个类型我们是*p来接收的,如果是单个类型组成的数组,我们也可以用一个类似数组的样式来接收 int(*)[] 这里加()的缘由就是防止*和int结合,这样就是有一个地址(*p)指向[4]。

      我们转换一下,&arr=&&parr,所以p是二级指针。p因为是指向的&arr,那么我们进行一次解引用只会得到&parr,还有一层需要解引用一次才正确。因为&arr是指向整个数组的,那么p+1就是跳过整个数组,跳过之后还是二级的我们依然需要两次解引用。

       我们如何通过这个二级指针p来遍历数组呢

      这里我们先进行了一次解引用,这次解引用等价于*(p+0),就是不跳过数组,也就是arr首元素的地址。然后我们下面的操作就和普通数组指针解引用一个意思了。也可这样理解,*p等价于*&arr也就是arr。

      这里有点二维数组的韵味

      再看二维数组:

首先是要清除二维数组名指的是什么:

 

        由上面可知,arr=&&pparr;这样更容易理解一点。

二维指针的解引用:

        图中arr首先加一,就是跳到第二行的1234,然后解引用,然后再加2就是访问第三个数据。

这个等价于arr[1][2]。

指向整个二维数组的指针:因为arr=&&pparr所以类比于上面的数组指针,这里要三次解引用。

        

        还有指针存储函数的地址:那么我们怎么定义指针类型呢?

        由我举出的例子可以看出,我们只要把函数的返回值和传入值类型弄上就行了。

        函数指针数组:

指针的指针:这里我们用图来解释

指针的指针就是存储指针的地址。

指针数组:就是将指针用数组储存起来。类比int arr[],指针数组的命名为int *arr[]。那么同理二级指针数组就是int**arr[] 。

        有什么用呢?我们知道只要有数组首元素的地址和长度我们就得到了整个数组的数据,那么我们把多个一维数组的首元素地址用指针数组存起来,那么变相的就形成了二维数组。同理,我们把各个二维数组的首元素的地址存起来,就可以形成三维数组

 指针来实现动态数组:具体看我这篇博客-->动态内存<--

如果有错误请提出宝贵建议!

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

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

相关文章

Socket通信Demo(Unity客户端和C#)

Socket通信基本流程 首先要启动服务器创建Socket&#xff0c;然后要绑定服务器的一个端口这样客户端通过服务器IP端口号就能连接到服务器了服务器接下来会设置监听队列&#xff0c;监听并等待要连接到它的客户端客户端在服务器启动之后也建立自己的Socket&#xff0c;然后使用…

2 月 Web3 游戏行业动态

作者&#xff1a;stellafootprint.network 数据来源&#xff1a;区块链游戏研究页面 - Footprint Analytics 2024 年 2 月&#xff0c;区块链游戏领域在加密货币价格上涨和活跃用户激增的推动下&#xff0c;实现了显著增长。然而&#xff0c;行业在维持用户参与度和留存率方面…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:NavRouter)

导航组件&#xff0c;默认提供点击响应处理&#xff0c;不需要开发者自定义点击事件逻辑。 说明&#xff1a; 该组件从API Version 9开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 必须包含两个子组件&#xff0c;其中第二个子组…

搭建交换机模拟环境及SSH连接,华为NSP软件入门使用教程

搭建交换机模拟环境及SSH连接&#xff0c;华为NSP软件入门使用教程 如果你是通过搜索搜到了这篇文章&#xff0c;那么一定是工作或者学习中需要用交换机&#xff0c;但是又没物理机测试学习&#xff0c;所以需要搭建本地的虚拟环境学习。 这篇文章是我进行交换机命令入门学习写…

在 windows 下安装并调试 CMake

一、前言 CMake是一个跨平台的开源工具&#xff0c;用于管理软件项目的构建过程。它不直接构建软件&#xff0c;而是生成用于特定平台或编译器的构建文件&#xff08;如Makefile或Visual Studio项目文件&#xff09;&#xff0c;然后利用这些文件来实际构建软件。 二、初次尝…

026—pandas 根据文本数据提取特征

前言 在数据处理中&#xff0c;源数据可能具有一定便于记录但又复杂的结构&#xff0c;我们在后续使用数据时还需要进一步进行处理。在本例中&#xff0c;要根据一列数据提取出数据中的相关特征&#xff0c;我们来看看 pandas 是如何完成的。 需求&#xff1a; 以上数据的 a …

【NR 定位】3GPP NR Positioning 5G定位标准解读(七)- GNSS定位方法

前言 3GPP NR Positioning 5G定位标准&#xff1a;3GPP TS 38.305 V18 3GPP 标准网址&#xff1a;Directory Listing /ftp/ 【NR 定位】3GPP NR Positioning 5G定位标准解读&#xff08;一&#xff09;-CSDN博客 【NR 定位】3GPP NR Positioning 5G定位标准解读&#xff08;…

安全信息化管理平台——数据分析与可视化

在当今的信息化时代&#xff0c;数据分析与可视化已经成为各个领域中不可或缺的组成部分。对于企业而言&#xff0c;如何将安全信息进行整合、分析并直观地呈现出来&#xff0c;成为了一项至关重要的任务。这就催生了一种新型的管理平台——安全信息化管理平台。 数据分析&…

【恒源智享云】conda虚拟环境的操作指令

conda虚拟环境的操作指令 由于虚拟环境经常会用到&#xff0c;但是我总忘记&#xff0c;所以写个博客&#xff0c;留作自用。 在恒源智享云上&#xff0c;可以直接在终端界面输入指令&#xff0c;例如&#xff1a; 查看已经存在的虚拟环境列表 conda env list查看当前虚拟…

【C++精简版回顾】21.迭代器,实现迭代器

1.什么是迭代器&#xff1f; 用来遍历容器&#xff0c;访问容器数据。 2.迭代器使用 1.初始化 //初始化 list<int> mylist;//list的整数对象 list<int>::iterator iter;//list内部类&#xff0c;迭代器对象(正向输出) list<int>::reverse_iterator riter;//…

华为配置ISP选路实现报文按运营商转发

Web举例&#xff1a;配置ISP选路实现报文按运营商转发 介绍通过配置ISP选路实现报文按运营商转发的配置举例。 组网需求 如图1所示&#xff0c;FW作为安全网关部署在网络出口&#xff0c;企业分别从ISP1和ISP2租用一条链路。 企业希望访问Server 1的报文从ISP1链路转发&#…

把 Windows 装进 Docker 容器里

本篇文章聊聊如何在 Docker 里运行 Windows 操作系统&#xff0c; Windows in Docker Container&#xff08;WinD&#xff09;。 写在前面 我日常使用 macOS 和 Ubuntu 来学习和工作&#xff0c;但是时不时会有 Windows 使用的场景&#xff0c;不论是运行某个指定的软件&…

记录一下某外资的面试

文章目录 标题English introduction标题What did u do in this gap time标题What’S the big challenge in your work experience标题 4、介绍一个自己熟悉的项目或最近的项目&#xff0c;包括项目的背景&#xff0c;使用的技术&#xff0c;在里面的角色标题5、项目中有多少个微…

Java中 常见的开源图库介绍

阅读本文之前请参阅------Java中 图的基础知识介绍 在 Java 中&#xff0c;有几种流行的开源图库&#xff0c;它们提供了丰富的图算法和高级操作&#xff0c;可以帮助开发者更高效地处理图相关的问题。以下是几种常见的 Java 图库及其特点和区别&#xff1a; JGraphT …

Github 2024-03-11 开源项目周报 Top15

根据Github Trendings的统计,本周(2024-03-11统计)共有15个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目4TypeScript项目3Jupyter Notebook项目3C#项目1HTML项目1CSS项目1Dart项目1Lua项目1Shell项目1Rust项目1Java项目1C++项目1屏幕截图转…

使用 JCommander 解析命令行参数

前言 如果你想构建一个支持命令行参数的程序&#xff0c;那么 jcommander 非常适合你&#xff0c;jcommander 是一个只有几十 kb 的 Java 命令行参数解析工具&#xff0c;可以通过注解的方式快速实现命令行参数解析。 这篇教程会通过介绍 jcommadner &#xff0c;快速的创建一…

TransNeXt实战:使用TransNeXt实现图像分类任务(一)

文章目录 摘要安装包安装timm 数据增强Cutout和MixupEMA项目结构计算mean和std生成数据集 摘要 https://arxiv.org/pdf/2311.17132.pdf TransNeXt是一种视觉骨干网络&#xff0c;它集成了聚合注意力作为令牌混合器和卷积GLU作为通道混合器。通过图像分类、目标检测和分割任务…

使用nexus3搭建npm私有仓库

一、下载解压安装包 下载地址&#xff1a;nexus-3.66.0-02-win.zip 二、安装并运行私服 在cmd中进入到文件夹中的bin目录下运行一下命令 nexus.exe /run等几分钟启动后&#xff0c;浏览器访问&#xff1a;默认端口8081 http://127.0.0.1:8081/ #修改端口在etc文件下 nexus-…

ORACLE Linux(OEL) - Primavera P6EPPM 安装及分享

引言 继上一期发布的CentOS版环境发布之后&#xff0c;近日我制作了基于ORACLE Linux的P6虚拟机环境&#xff0c;同样里面包含了全套P6 最新版应用服务 此虚拟机仅用于演示、培训和测试目的。如您在生产环境中使用此虚拟机&#xff0c;请先与Oracle Primavera销售代表取得联系…

凌鲨本地接口架构

本地API通过监听本地端口&#xff0c;提供http服务&#xff0c;让本地应用可以获取信息和操作凌鲨客户端。 本地API架构 #mermaid-svg-seodZa6VsI4Qc8Cj {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-seodZa6VsI4…