C++二维数组输出疑问:为何最后输出不是地址,如何获取值9?
让我一步步拆解这段代码里的逻辑,帮你搞清楚每个输出的由来,以及最后一行为什么是值而非地址:
首先要明确:在C++中,int a[3][4]这种二维数组本质是包含3个一维数组的数组,每个一维数组有4个int元素。数组名a在表达式中会被隐式转换为一个指向第一个一维数组的指针,类型是int (*)[4](也就是“指向int[4]类型数组的指针”)。
逐行分析输出
cout<< (a+1)<<endl;a是指向第一个int[4]数组的指针,a+1会跳过一个完整的int[4]数组的大小(通常是16字节,因为每个int占4字节),直接指向第二个一维数组的起始地址。所以这里输出的是第二个一维数组的地址,也就是你看到的0x23fe30。cout<<*(a+1)<<endl;*(a+1)是解引用这个指向int[4]的指针,得到的是第二个一维数组本身。但数组名在表达式中又会被隐式转换为指向该数组第一个元素的指针(类型变为int*)。由于数组的起始地址和它第一个元素的地址数值完全相同,所以输出的地址和上一行完全一致,也是0x23fe30。cout<<(*(a+1)+2)<<endl;
前面提到*(a+1)会转换成int*类型的指针,指向第二个一维数组的第一个元素(值为1)。+2会让这个指针跳过2个int的大小(8字节),指向第二个一维数组的第三个元素(也就是值为9的那个元素)。所以这里输出的是这个元素的内存地址,即0x23fe38。cout<< *(*(a+1)+2);
这一步是对上面得到的指针(*(a+1)+2)进行解引用操作(*),直接取出该地址存储的int值——也就是9。这就是为什么最后一行输出的是值而非地址:你通过解引用,拿到了指针指向的具体内容,而不是指针本身的地址。
如何获取值9?
你最后一行的代码已经正确获取到了值9,不过还有几种更直观或者等价的写法:
- 标准下标写法(最推荐):
a[1][2]
这是C++访问二维数组元素的常规方式,和*(*(a+1)+2)完全等价——a[1]等价于*(a+1),a[1][2]等价于*(a[1]+2),也就是*(*(a+1)+2)。 - 混合写法:
*(a[1]+2)或者(*(a+1))[2]
这两种写法只是把下标操作和指针操作混合起来,逻辑和标准写法完全一致。
关键知识点总结
- 二维数组的数组名转换后的指针是指向一维数组的指针,而非指向单个元素的指针;
- 数组名在大多数表达式中会隐式转换为指向首元素的指针,但数组本身和指针是不同的类型;
- 解引用操作(
*)的作用是获取指针指向的具体值,而非输出指针的地址。
内容的提问来源于stack exchange,提问作者xin

