什么数组指针?
数组指针:指的是指向数组的指针
定义一个数组指针
int (*p) [5] = NULL;
如何分析这个语句?
因为“()”优先级高,所以p与*结合,表示p是一个指针,之后再和[5]结合,表示指针指向一个有5个元素的数组,int表示该数组的元素为int类型。
数组指针指向数组与普通指针指向数组的区别?
// 定义一个int型指针p指向array
int array[5] = {1,2,3,4,5}; // 定义一个int类型数组
int *p; // 定义一个int类型的指针
p = array; // 指针p指向array数组首元素的地址
// 定义一个数值指针p_array指向array
int array[5] = {1,2,3,4,5}; // 定义一个int类型数组
int (*p_array) [5]; // 定义一个数组指针
p_array = &array; // 指针p_array指向array数组的地址
第一部分,定义了一个int型指针变量,数组名作为右值 ,表示数组首元素的地址,这里p指向的是array数组首元素的指针
第二部分,定义了一个int型的数组指针,&array表示数组array的起始地址,类型为int (*) [5],这里p_array为指向int类型的数组的指针
内存分布如下:
指针p和指针p_array虽然在内存中存储的值是相同的,但所代表的意义却不同,p指向的是数组的元素,而p_array指向的是数组。
我们可以通过sizeof运算符查看内用内存大小情况:
对指针p解引用后所占内存的小大为4字位,对指针p_array解引用后所占内存的小大为20字位,从这可以看出,p指向的是一个数组的元素,而p_array指向的是整个数组
// 使用64位Max系统Xcode运行
int main(int argc, const char * argv[]) {
int array[5] = {1,2,3,4,5};
int *p = array;
int (*p_array) [5] = &array;
// 分别打印指针p和指针p_array所占内存的大小
// 结果为8
printf("sizeof(p) = %d\n", (unsigned int)sizeof(p));
// 结果为8
printf("sizeof(p_array) = %d\n\n", (unsigned int)sizeof(p_array));
// 分别打印指针p和指针p_array解引用后所占内存的大小
// 结果为4
printf("sizeof(*p) = %d\n", (unsigned int)sizeof(*p));
// 结果为20
printf("sizeof(*p_array) = %d\n\n", (unsigned int)sizeof(*p_array));
return 0;
}
数组指针与二维数组的应用
// 定义一个二维数组array[2][5],通过数组指针p指向数组array;
int main(int argc, const char * argv[]) {
int array[2][5] = {{1,2,3,4,5},{6,7,8,9,0}};
int (*p) [5] = array;
// 打印地址
printf("p = %p\n", p); // 0x00001000
printf("p+1 = %p\n", p+1); // 0x00001014
// 打印数值
printf("p+1 = %d\n", *(*(p+1)+2)); // 8
printf("array[1][2] = %d\n", array[1][2]); // 8
return 0;
}
内存分布如下:
p指向的为数组array的第0个元素数组,p+1指向的为数组array的第1个元素数组。
因为p为数组指针,为了得到数组中对应的值,我们可以通过解引用得到第0个元素数组的地址,再通过对得到的地址进行操作解引用,可得到对应的值
例子:*(*(p+1)+2)
p在内存中存的值为0x00001000,如果对p解引用(*p)即得到0x00001000,因为p为数组指针,所以对p+1解引用(*(p+1))即得到下一个数组的地址0x00001014
(*(p+1))+2对解引用的地址+2,可得到array的第1个元素数组中的第2个元素的地址,通过解引用(*(*(p+1))+2)即可得到对应的值
(*(*(p+1))+2)得到的值和通过array[1][2]的值是一致的。