指针数组
指针数组是一个存放指针的数组,即数组中的元素类型均为指针类型。
如 int* arr1[10];
*和[ ]的优先级,[ ]比 *高,因此arr先与[ ]结合,表示其为一个数组,前面的int*表示该数组中存储的元素类型为int*,即数组中的元素类型为整型指针变量。
数组指针
与指针数组完全不同,数组指针是指向数组的一个指针。
int (*p)[10]就是一个数组指针。这里p和*\结合,说明了p是一个指针变量。其指向的是一个大小为10的整形数组。
1.数组的地址和数组首元素的地址
在讲清楚数组指针之前,我们需要先知道数组的地址和数组首元素的地址。
比如有一个数int a;变量a的地址为多少?答案为&a。即&名称
同理,有一个数组 int arr[10]; 则该数组的地址为&arr。
而该数组首元素的地址为 arr 或者 &arr[0];
我们来看如下代码
int main()
{
int arr[10] = { 0 };
printf("%p\n", arr);
printf("%p\n", &arr[0]);
printf("%p\n", *(&arr));
printf("%p\n", &arr);
return 0;
}
执行结果如下图:
我们发现,四者输出的结果是一样的,其中,前三个都代表arr数组的首元素的地址,第四个代表arr数组的地址,于是,我们就可以得出“数组的地址就是数组首元素的地址”这样的结论吗?
那再看下一段代码:
int main()
{
int arr[10] = { 0 };
printf("arr = %p\n", arr);
printf("arr+1 = %p\n", arr + 1);
printf("&arr[0] = %p\n", &arr[0]);
printf("&arr[0]+1 = %p\n", &arr[0] + 1);
printf("&arr = %p\n", &arr);
printf("&arr+1= %p\n", &arr + 1);
return 0;
}
结果如下
我们那会发现,尽管数组的地址和数组的首地址在数值上相等,但是当他们+1后,地址却不一样。
实际上,arr+1与arr的差值刚好是一个数组元素的大小,在本例子中就是4B,一个整型元素的大小,而&arr+1与&arr的差值,是整个数组的大小,在本例子中就是40B。
这也就说明了,数组的地址和数组首元素的地址的实际意义是不一样的。
2.一维数组中数组指针的应用
知道了数组的地址,我们就可以更好的理解数组指针。
比如有一个数组 int arr[10] = { 0 };
指向该数组的指针应该是 int (*p)[10] = &arr ;
那么,我们怎样用数组指针访问到数组内的元素呢?
请看如下代码:
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
int(*p)[10] = &arr;
for (int i = 0; i < 10; i++)
{
printf("%d ", (*p)[i]);
}
printf("\n");
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
for (int i = 0; i < 10; i++)
{
printf("%d ", *(*p + i));
}
return 0;
}
输出结果为:
上面三者的写法是等价的,输出结果也是一样的。
实际上,对于数组指针的应用,二维数组应用更广。
3.二维数组中数组指针的应用
有一个二维数组int arr[3][5]={1,2,3,4,5,6,7,8,9,0},那么该数组名arr代表什么意思呢?
二维数组的数组名代表的是第一行的地址,上述的二维数组,可以看做三个一维数组拼接。那么,arr+1后,指向的应该是下一个一维数组的地址。也就是说,此时的arr,就是一个数组指针。
如何通过数组指针遍历该数组?
请看如下代码
void print_arr(int (*p)[5], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
printf("%d ", *(*(p + i) + j));
}
}
}
int main()
{
int arr[3][5] = {1,2,3,4,5,6,7,8,9,10};
print_arr(arr, 3, 5);
return 0;
}
在上述代码中,p是一个数组指针,则p+i代表第i行的地址,*(p+i)就代表第i行第一个元素的地址,*(p+i)+j就是第i行第j列元素的地址,则*(*(p+i)+j)就是第i行第j列的元素。
懂了以上关于数组指针的讲述后,我们再看一个例子:int (*arr[10]) [5];
这个是什么意思?
首先括号内的arr [10]先结合,表示arr是一个数组,而arr[10]前面的星号,表示该数组是一个指针数组,数组里面存储的元素为指针,每个指针指向的 ,是一个长度为5的int型数组。