区分指向数组元素的指针、指向数组的指针、指针数组
指向数组元素的指针
这类指针比较常见,例如
int a[3] = {1, 2, 3};
int *p;
p = a;//将数组的地址(也即数组首元素的地址)赋给指针p,相当于指针p指向数组的首元素
这样,我们就可以用*(p+0)
或*(p+1)
等等访问数组元素了。
同样的,这类指针也适用于二维数组,例如
int a[3][3] = {
{1, 2, 3},{4, 5, 6}, {7, 8, 9}};
int *p;
p = a;
这样我们可以通过*(p+0)
访问a[0][0]
,通过*(p+3)
访问a[1][0]
等等,就相当于把二维数组看作一维数组。当然也可以适用指向数组的指针来表示,见下节。
指向数组的指针
我们首先需要搞清楚二维数组的地址表示。
假设有二维数组int a[3][3] = { {1, 2, 3},{4, 5, 6}, {7, 8, 9}};
,假设数组的起始地址为2000,则
a = 2000;
a[0] = 2000;
a[1] = 2012;
&a[0][0] = 2000;
&a[0][1] = 2004;
即数组名代表数组的首地址,也是行首地址;第一维度的数组名代表了每一行的首地址,如a[1] = 2012
;
在一维数组中有*a=a[0]
*(a+1)=a[1]
;推广到二维数组中一样适用。
即在二维数组中,同样也有*a=a[0]
*(a+1)=a[1]
,因此*(*(a+1)+1)=a[1][1]
。
我们函数中传递二维数组,可以将指向二维数组每一行的指针传入,即指针中存储的是二维数组每一行的行地址。
指向数组的指针是指向一维数组首元素的指针,即p=a[0]
和p+1=a[1]
,表明当指针指向一维数组后,每次+1增长的长度为整个一行的字节长度。
使用int (*p)[3]
来定义这类指针,括号不能去掉,后面的下标3代表指向的一维数组的长度是3,注意不是二维数组的行数。
当把这类指针传进函数后,便可通过*(*(p+i)+j)
访问二维数组中的每一个元素了。
指针数组
指针数组即一个数组内存储的均为同类型的指针。例如
int *p[4];
表示p这个数组内存的都是指向int型的指针。