多维数组中*(arr+1)与arr+1为何输出相同地址?
多维数组与指针表示法的疑问解答
你的代码示例:
int arr[2][4] = {{1,2,3,4}, {5,6,7,8}}; printf("%d\n", (arr+1)); printf("%d\n", *(arr+1));
两次输出地址数值相同的原因,核心在于数组名的自动退化规则和指针类型的差异:
- 首先,
arr是int[2][4]类型的二维数组。在表达式中,数组名会自动退化为指向其第一个元素的指针——这里arr的第一个元素是长度为4的int数组,所以arr退化为int (*)[4]类型(指向包含4个int的数组的指针)。 arr+1:该指针加1时,偏移量是整个内层数组的大小(假设int占4字节,就是4*4=16字节),最终指向第二个内层数组{5,6,7,8}的起始地址。*(arr+1):对arr+1解引用后,得到的是第二个内层数组本身(int[4]类型)。但这个数组名在printf的表达式中又会自动退化为指向其第一个元素的指针(int*类型),也就是指向元素5的地址。
关键在于:内层数组的起始地址,和它第一个元素的地址是同一个内存位置——就像一个装着4个数的盒子,盒子的起始位置和第一个数的位置完全重合。所以打印这两个地址的数值时,结果自然一致。
如果要区分它们的类型差异,可以修改打印代码验证:
// 打印arr+1的地址(指向第二个内层数组) printf("%p\n", (void*)(arr+1)); // 打印*(arr+1)的地址(指向第二个内层数组的第一个元素) printf("%p\n", (void*)(*(arr+1))); // 对比*(arr+1)+1:偏移1个int的大小,指向元素6 printf("%p\n", (void*)((*(arr+1))+1)); // 对比arr+2:偏移1个内层数组的大小,指向数组末尾之后的位置 printf("%p\n", (void*)(arr+2));
内容的提问来源于stack exchange,提问作者Filipe Andrade
相关产品推荐
相关产品推荐

