指针数组
上一篇文章我们说了
数组和指针是紧密相连的
数组名其实就是一个指向数组第一个元素的指针
那么指针数组是什么呢?
这里我们这样理解
我们将指针理解为一种数据类型,和int啊float啊char啊这种一样
那么我们又int型数组,有char类型数组
所以说也有指针数组
那么理所当然,类比起来
int型数组里放的都是int型数据
char型数组里存放的都是字符型数据
所以说,指针数组里存放的都是指针
关于指针数组的定义:
比如我们要定义一个包含3个int型指针的数组我们就可以像下面这样定义
int *p[3];
所以根据这个规则,总结就如下
类型名 *指针名[数组长度];
这样定义
指针数组有哪些应用呢
其实我们不难发现指针数组其实和二维数组比较像
为什么这么说呢
我们来看下面的例子
#include<stdio.h>
int main(){
int a[2][3] ={{1,2,3},{4,5,6}};
int *p[2] = {{1,2,3},{4,5,6}};
这里我门先后定义了一个2*3的数组和一个两行的指针数组
如果我们将他们输出的话
不难发现他们的结果是一样的也就是
1 2 3
4 5 6
都是这样的,问题是我们知道对于二维数组我们是怎么索引的
比如我们要取出5这个值
那么结果就是a[1][1]
那么如果我们要从p里取出5呢?
那就是*(p[1]+1)
你看懂了吗,可以自己取试一试这个逻辑结构是怎么来的呢
首先我们要明确一点
当式子是这样的时候*p[0]时[]这个符号的优先级是高于*的
索引返回的就是p这个数组里第1个元素,然后再对其取值
那么p里的第一个元素是数组{1,2,3}
那么p[0]就相当于{1,2,3}的数组名,
也是就是说p[0]是指向1的指针
所以说对p[0]取值也就是*p[0]的结果就是1
那么*(p[0]+1)这个又是怎么看呢
都知道()的优先级是比较高的
所以先运算p[0]+1
那么p[0]是指向1的指针,p[0]+1就是指向1的下一个的指针
也就是2的指针,再对其取值就是返回2
所以说*(p[1]+1)
其实就是取数组中第二个指针,然后再往后推一个位置,然后再取值
也就是先取4的地址 然后再变成5的地址 然后再对5的地址进行取值
这样的一个流程
其效果就等同于a[1][1];
}
数组指针
数组指针
其实是一种指针
我们可以这样理解
指针是有类型的
指向整形的指针叫整形指针,也是就是int指针
指向字符的指针叫做字符型指针,也就是char指针
那么顾名思义,数组指针,就是指向数组的指针
如何定义数组指针呢我们看下列代码
#include<stdio.h>
int main(){
int a[] = {1,2,3,4};
int *p = a;
这里两行代码是我们首先定义了一个包含4个元素的数组
然后定义了一个指针,并将数组名赋值给了他
首先我们知道数组名是指向数组第一个元素的指针
其储存的其实是第一个元素的地址
所以这里的a其实是数组中1的地址
再将其赋值给指针p是没问题的
这个时候p里储存的就是1的地址
那么这里p是不是数组指针呢?
没错不是,因为上面已经说了,他是指向1的指针,1是一个整形常量,所以说
p只是一个整形的变量
这一点一定要区分开
那么数组指针应该怎么定义呢? 我门再看下列代码
#include<stdio.h>
int main(){
int a[] = {1,2,3};
int (*p)[3] = &a;
这里我门第一行代码是定义了一个包含三个元素的数组
然后主要是看第二行代码
首先int 规定了指针的类型是整形
然后()的优先级是高于[]所以先定义了一个指针p然后他的长度是3
也就是这个指针指向了一个包含了三个整形的数组的位置,
然后&a是对a数组进行取址,这个取址取的是数组的地址,而不是数组元素的址
所以说再将a的地址赋值给p那么这时候p就是一个数组指针了
那么这里就面临这一个问题,我们如何通过p来获取数组中的数据
比如我们要获取2这个值
首先我门要明确p是数组名a的地址
那么*p就是这个数组名,那数组名a又是指向第一个元素的指针
也就是说*p这里是数组第一个元素的地址也就是1的地址
所以我么要+1也是就*p+1这个时候*p+1指向的就是2
也就是2的地址
我们再对其取值-->*(*p+1)
这个的结果就是2
懂了吗?
我门再回推一下*(*p+1);
首先()是优先级最高的所以先计算*p+1
又因为*比+的优先级高
所以先计算*p,*p是获取p的值
p是指向数组名a的地址的指针
所以*p返回的就是数组名的值
数组名的值其实就是数组第一个元素的地址
所以*p就是指向数组中第一个元素的地址
所以*p+1就是指向第二个元素的地址
再对其进行取值也就是*(*p+1)也就是返回的是第二个元素的值
哇卡达?
}
}
那么今天的学习到此为止了
下次再见
2022/5/1