为何对数组使用&运算符后仍指向其首元素?
这个问题问得特别到位,正好说到了C语言数组与指针概念里最容易让人迷糊的细节——地址值完全相同,但指针类型有着本质区别。
你引用的C标准描述完全正确:当数组作为&运算符的操作数时,它不会被隐式转换为指向首元素的指针。那为什么看起来&array的指向和数组首元素地址一样?其实是因为数组的起始内存地址,本身就是其首元素的内存地址,两者的地址值重合,但&array得到的是一个指向整个数组的指针,而非指向单个元素的指针。
举个具体的代码例子就能看清楚:
#include <stdio.h> int main() { int array[5] = {1,2,3,4,5}; int *elem_ptr = array; // 数组隐式转成指向首元素的指针,类型int* int (*arr_ptr)[5] = &array; // 指向整个数组的指针,类型int (*)[5] // 打印地址值,会发现两者完全相同 printf("array首元素地址: %p\n", elem_ptr); printf("&array的地址值: %p\n", arr_ptr); // 但指针加减的行为完全不同 printf("elem_ptr + 1: %p\n", elem_ptr + 1); // 跳过1个int,地址+4(假设int占4字节) printf("arr_ptr + 1: %p\n", arr_ptr + 1); // 跳过整个数组,地址+20(5*4) return 0; }
从输出就能看出来:虽然elem_ptr和arr_ptr的初始地址值一样,但它们的类型决定了指针运算的逻辑完全不同——指向数组的指针,每次加减操作的步长是整个数组的大小,而指向元素的指针步长是单个元素的大小。
总结一下:&array并没有指向首元素,它指向的是整个数组对象,只是这个数组对象的起始地址恰好和首元素的地址重合,所以从地址值上看好像是同一个位置,但语义和后续操作的行为有天壤之别。
内容的提问来源于stack exchange,提问作者Paralax01
相关产品推荐
相关产品推荐

