C++二维数组a、*a、&a[0][0]输出相同地址的原因求解
现象原因说明
这个问题本质是C++的数组类型隐式转换规则、以及多维数组的内存布局特性共同导致的,具体拆解如下:
- 首先明确二维数组的定义本质:你写的
int a[2][2]不是什么二级指针,它实际是「长度为2的数组,每个元素都是长度为2的int数组」,所有元素在内存中连续紧凑排布,整个二维数组的起始地址、第一个子数组的起始地址、第一个int元素的起始地址天然就是同一个数值。 - 分析
cout << a的输出逻辑:C++中数组名除了&运算、sizeof运算等少数场景外,都会自动隐式转换为指向数组首元素的指针。这里a作为二维数组名,首元素是第一个子数组a[0],所以隐式转换后得到的是类型为int (*)[2]的指针,指向a[0]的起始地址,输出这个指针拿到的就是整个二维数组的起始地址。 - 分析
cout << *a的输出逻辑:对类型为int (*)[2]的指针解引用后,得到的是a[0]本身,也就是类型为int[2]的一维数组。此时把这个一维数组交给cout输出,会再次触发数组名的隐式转换,变成指向a[0]首元素a[0][0]的int*类型指针,而a[0]的起始地址和整个二维数组的起始地址完全重合,所以输出的地址值和前者完全一致。 &a[0][0]就是直接取第一个int元素的地址,自然和前两个输出的地址值相同。
你误以为*a会输出1,是默认把a当成了指向int的指针,但实际上它是指向一维数组的指针,需要两次解引用才能拿到最内层的int值:你可以尝试运行cout << **a << endl;,输出结果就是你预期的1。
内容的提问来源于stack exchange,提问作者Bully Maguire
相关产品推荐
相关产品推荐

