通过指针引用数组元素
前面我们说变量有指针,那么数组元素有没有指针呢?数组元素也有指针,并且我们也可以通过指针来引用数组元素。
数组元素的指针
我们说一个变量是有地址的,数组包含了很多的元素,每个元素都在内存中占用存储单元,这些数组元素也都有相对应的地址,指针可以指向变量也可以指向数组。所谓数组元素的指针,就是数组元素的地址。
使用数组指针
1 | int a[5]={1,2,3,4,5}; //定义了包含5个元素的数组 |
我们看到,其实和变量指针类似,只不过我们这里给指针变量的地址是数组元素的地址
。平时,我们引用数组元素采用的都是下标法
即通过数组名+元素下标
的方式表示数组。现在,我们也可以使用指针法
,即通过指向数组元素的指针来找到所需要的元素。
使用指针法调用数组元素,可以提升目标程序质量,占用内存少,运行速度快。
在 C 语言中,数组名代表的(不包括形参的,因为那就是个摆设)都是该数组中首元素的地址。所以:
1 | int a[5]={1,2,3,4,5}; |
最后给 p 赋值的两个语句,其实是等价的,因为数组名 a 表示的就是数组 a 的 0 号元素的地址。
注意
数组名不代表整个数组,只代表该数组的 0 号元素的起始地址。
引用数组元素指针的运算
我们知道,指针就是地址,对地址进行算术运算有什么意义呢?其实乘除运算是没有意义的,但是加减运算就非常有意义了。
从上面我们知道,数组名称表示的是该数组首元素的地址,那么我们如果需要让指针只想第二个元素呢?
1 | int a[5]={1,2,3,4,5}; |
上面的 p=p+1 和 p=&a[1] 其实是等价的,都是把数组的第二个元素地址赋值给 p,但是区别是,我们使用指针的加减法更加简约和易懂。
指向数组元素的指针运算法则
1 | int a[5]={1,2,3,4,5}; |
指针地址的加减运算
如果指针变量 p 已经指向数组中的一个元素,则:
p+1 指向同一数组中的下一个元素;
p-1 指向同意数组中的上一个元素;
这里的 p 的加减1,并不是指 p 的值(地址)加减 1 ,而是加上一个数组元素所占用的字节数。
实际上,p+1 代表的是 (p+1) x d ,d 是一个数组元素所占用的字节数,对 int 、float 、long 类型时,d=4, 对于 char 类型是,d=1, 具体系统怎么知道 d 代表的字节数,是因为在定义指针变量的时候,声明了基类型,根据基类型,编译器会自动给 d 赋值。
指针跳转到指定元素
我们可以直接给指针赋值某一元素的地址,但是我们如果想从首元素直接跳到3号元素该怎么办呢?
1 |
|
没错,我们可以在首元素的基础上,直接加上想要跳转到的元素下标,比如上面,我们想把指针跳转到 3 号元素,那么我们就在首元素的基础上+3即可。当然,我们也可以在3的基础上 -1 将指针指向 2 号元素。
用指针输出数组元素
我们知道了如何调用指针和如何跳转到我们需要的指针位置,现在,和普通指针变量相同,我们在指针变量前加 * 号,就可以表示当前指向数组元素的指针所指向的值了。
1 |
|
我们看到,可以表示数组元素的方式有三种:
- 指针调用,通过指针变量前加*,表示数组元素。
- 因为 a 表示的是首元素地址,所以 a 也可以进行指针的运算
- 直接使用下标法引用数组元素。
两个指针地址相减
既然不同元素之间的指针地址,都只差4个字节的倍数,那么我们如果将指向 a[3] 的地址减去指向 a[1] 的地址会得到什么结果呢?
1 |
|
结果是:『得到的是:2』
上面我们用3号元素的地址减去了1号元素的地址,得到的就是两个地址之间的差除以类型的字节数。如果:
a[3] 的地址为:2022;
a[1] 的地址为:2014;
最后的得到的是:(2022-2014)/4
上面的4是字节数,是数组的数据类型决定的。
所以上面的例子中,我们得到的结果是2,也就是3号元素和1号元素之间差2个元素,这样我们就能知道两个元素的相对位置了。
尾巴
这是我的个人学习笔记,主要是应付考研复习使用,充斥着一些吐槽和个人观点,并不严谨,欢迎大家参考、指正。