C语言二维数组名arr和&arr的类型判定及增量逻辑疑问
你给出的测试代码如下:
#include<stdio.h> int main() { int arr[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; printf("%u ,%u\n",arr, &arr+1); return 0; }
类型差异的核心原因
这是C语言标准定义的数组隐式转换规则决定的,和地址数值无关,只和数组名的使用场景有关:
- 除非数组名是
sizeof、_Alignof或者取地址符&的操作数,否则所有在表达式中出现的数组名,都会自动转换为指向数组第一个元素的指针,指针类型由数组元素的类型决定。
你定义的arr是int [3][4]类型的二维数组,它的每一个元素都是int [4]类型的一维数组。所以arr在printf的参数里出现时,不属于上述三个例外场景,会自动转换为指向首元素(也就是第一个int [4]数组)的指针,类型为int (*)[4](指向4个int组成的数组的指针),也就是你提到的「pointer to an array of 4 integer」。 - 当数组名作为
&的操作数时,不会发生上述隐式转换,&arr取的是整个二维数组的地址,对应的指针类型就是int (*)[3][4](指向3个4int数组组成的二维数组的指针),也就是你提到的「pointer to array of 3 arrays of 4 integer」。
二者地址数值相同只是因为整个数组的起始地址和数组第一个元素的起始地址天然重叠,就像一栋楼的总入口地址和第一层的入口地址数值一致,但「指向整栋楼的指针」和「指向一层楼的指针」完全是两个类型,移动时的步长差异极大:前者加1会跳过整栋楼的大小(这里是48字节),后者加1只会跳过一层的大小(这里是16字节),这就是编译器要区分二者类型的根本原因。
内容的提问来源于stack exchange,提问作者Shyam Prasanna
相关产品推荐
相关产品推荐

