首先,大家先需知道一个关于基类型的概念
基类型:组成一个新类型的基础类型
这句话是什么意思呢?举个例子:
int a[3] = {1,2,3};
上面是由三个int类型的数组成一个新的类型也就是数组,所以基类型是int
int a[2][2] = {{1,2},{3,4}};
上面是由两个一维数组类型组成一个二维数组,所以基类型是一维数组
有了上面两个例子,相信大家能知道基类型是啥意思。
接下来先说说一维数组和一级指针关系
首先指针说白了就是存放地址,把变量地址赋予指针
取出该变量的数值应该用*号取出指针所指变量地址里面的值,如下
如果我们想把一个数组的地址赋值给指针,如下
程序里的a表达的是数组的首地址,则我们可以得到int *p = a的关系
如果我们想输出数组第二个元素的地址呢,是不是得把指向首地址的指针移到数组第二个数的地址
指针p存储首地址,也就是指向数组的第一个元素,+1后相当于指向数组第二个元素,指针往右移动1个基类型,也就是一个int型长度,所以地址与首地址相差4个字节,因为int数据类型长度为4个字节。
我们用 * 号取后数值为1,说明正是指向数组第二个元素。
突发奇想,指针 p = a,那我可以把p改作a执行上面操作吗?
想法被确定了,在某种情况下,数组的确和指针用法一样。
接下来是二维数组和数组指针关系
数组指针:本质是个指针, 指向 数组的指针
有人可能会问,那可以指向一维数组吗,先不说,看到下面应该就能理解
可以看出,p存放二维数组首地址,如果我们想要到a[1][0]的地址呢
指针p存储首地址,上面我们已经说过二维数组由一维数组构成,基类型为一维数组,+1后相当于指向二维数组第二个元素也就是第二个一维数组,指针往右移动1个基类型,也就是一个一维数组型长度(包含两个int型),所以地址与首地址相差8个字节。
如果想要a[1][0]的数值呢
有人可能会被不知道为什么需要两个 * 号才能取出数值
这是因为我们一开始时p+1只是指针移动一个基类型,也就是移到二维数组的第二个一维数组一整个中,可是别忘记他的元素是一维数组,没有*之前我们还只是在二维数组中,我们 *{p+1}才是进入一维数组里面,然后接下来就和一级指针一样的操作,再多个*就可以把数值取出:*(*(p+1))
如果要取a[1][1]的地址和值呢
为什么在第一个 * 号后+1呢
因为当我们*(p+1)进入二维数组中第二个一维数组里面后,我们如果想取它一维数组第二个元素的int值,是不是和上面一维数组和一级指针一样,+1就可移动到第二个int,这里(*p+1)+1后面+1移动的是int的基类型,前面的+1移动的是一维数组的基类型,则取出a[1][1] 则需要(*(*p+1)+1) 。
看到这里希望大家明白为什么前面说的数组指针不能指向一维数组以及二维数组和数组指针关系
总结:一维数组和一级指针:
int a[5];
int *p = a;
二维数组和数组指针的关系:
int a[2][2];
int (*p)[2]; 注意数组指针和二维数组后面的[2]必须相同。