c语言-指针与一维数组

1.指针与一维数组的联系

我们知道:(1)指针变量是用来存放别人地址的变量

(2)c语言中,数组的数组名或者数组第一个元素的地址就是数组的首地址

int *p;

p=arr=&arr0

根据这两点,我们是否可以定义一个指针变量来存放数组的首地址?看下图:

很显然,我们可以通过指针变量来存放数组首地址并成功访问出对应元素。

那么我们如何通过指针访问出下一个元素也就是2或者3呢?可以通过指针偏移的方式来访问下一个元素(因为数组的内存是连续的),因为我们知道指针指向的就是地址,也就是进行地址偏移。看下图:

*p指向的是地址,而*p+1你可能疑惑是内存地址这个16进制数加1?

并不是,底层逻辑是这样的:int类型是4个字节,而这里定义的arr数组是int型,因此数组的每个元素都是int型占4个字节,也就是16位,而每+1就是指针偏移一位跨度就是四个字节,看下图:

这里可以看到,元素1、元素2、元素3的地址分别是FE0C、FE10、FE14,是连续的,每隔一位差4,对应一个int(4个字节)的大小。因此就解释了上面可以通过指针偏移的方式来访问数组中下一位元素,因为数组元素内存是连续的,每偏移一位,跨度(增量)都是4个字节。

但是,上面这种访问方式太过粗糙了,要是数组中有n个元素,拿岂不是要*p+n到天荒地老?

带着这个问题往下看:我们是否可以通过循环的方式来解决这个问题?

从这个例子看到可以利用循环结合指针将数组中的元素遍历出来。这里的i就可以理解为数组每个元素的下标,把下标当作每次指针偏移的跨度(增量)。下面这个图中的写法得到的结果也是一致的,因此等价。

这里再紧接着引出一个问题,在做一个同样的循环,是否可以再一次循环遍历出数组的元素?

可以到,虽然遍历出了相同的元素,但是内存地址变了,根据变量四要素(变量名、变量值、变量数据类型、变量内存地址)我们可以知道,他并不是同一个东西。看下面这个图更加直观:

这个结果就是做一次同样的循环并不能访问出对应的元素了。也就对应了上面内存地址不同虽然得到同一个结果,但并不是同一个元素。

那么造成这个结果的原因是什么?怎么解决?

原因就是上一轮循环的指针经过偏移最终停到了下标2也就是对应元素3的地址上,再进行一次同样的循环,那么他就会从元素3的地址继续向后偏移,但是我们这个数组的元素只有1,2,3,就导致它后面并没有地址和对应的元素进行访问。

解决方法很简单,也就是进行一次指针复位

这里p=arr就是做的指针复位,也就是指针初始化。

总结:(1)数组名=数组首地址=数组的第一个元素的地址;也就是arr=&arr0;再结合指针

int *p;p=arr=&arr0;

(2)结合指针在进行数组遍历时:下面这几种写法写法也是等价的:

(3)值得一提的是下面这两种写法编译是错的:指针常量不允许进行++操作改变

指针常量,它的内存空间是已经定了的,不能进行改变,就比如下面这个arr数组,他就是指针常量,内存地址不能进行改变,只能通过内存的地址取值;指针变量,开辟了一个新的内存空间(他有自己的内存的地址),用于存放别人的内存地址,它就像一个火车站,空间是固定的,但是里面的乘客(别人的内存地址)是流动的不固定的,也就是可以改变的

相关推荐
西柚小萌新8 分钟前
【LLM&&AI应用开发 八股文】--4.3.Agent智能体(下)
java·开发语言·数据库
北极有牛11 分钟前
cpp学习笔记--常量指针
java·开发语言·算法
GPU实战笔记11 分钟前
云端 GPU 训练的账户余额提醒:它能说明什么,不能说明什么?
深度学习·算法·成本管理·gpu云计算·云端训练
半杯咖啡半行码32 分钟前
C++ 编程与 STL 模板:从泛型编程到内存安全详解
开发语言·c++
浮链序32 分钟前
怎么证明"你这个模型是偷我的"——把蒸馏变成取证工具
算法·安全·llm
小O的算法实验室33 分钟前
IEEE TMC,面向异构物联网的多目标量子行为拓扑优化算法
算法
caoerzhong44 分钟前
JeeWMS 开源 WMS 部署避坑指南:Java 仓库管理系统的环境基线、四类根因与可复现交付
java·开发语言·开源
时间的拾荒人1 小时前
Qt 界面优化:绘图详解 —— 从基础图形到图片处理
开发语言·qt·面试
MayZork1 小时前
Qt 文件操作:QSaveFile 与 QTemporaryFile(含 QTemporaryDir)实战
开发语言·qt
北冥you鱼1 小时前
Go 语言空接口(interface{})使用场景与最佳实践
开发语言·windows·golang