C++多维数组引用机制及指定代码运行原理咨询
没问题,我来给你拆解这段代码的运行逻辑,顺便把C++多维数组的核心引用机制讲得明明白白~
先看这段代码为什么输出86
首先看你的数组定义:
int a[3][2] = {{3, 6}, {8, 4}, {7, 1}};
这是一个3行2列的二维数组,在内存里是连续存储的,顺序是3, 6, 8, 4, 7, 1,这个内存布局后面会用到。
接下来拆解两个输出部分:
*a[1]的计算
要注意运算符优先级:[]的优先级比*高,所以先执行a[1]。a[1]是二维数组的第2个元素(下标从0开始),也就是第二行的一维数组{8,4}。- 在表达式中,一维数组名会自动退化为指向它首元素的指针,所以
a[1]等价于&a[1][0](指向8的指针)。 - 然后
*a[1]就是解引用这个指针,得到值8。
*(*a + 1)的计算
这里要一步步来:a是二维数组名,在表达式中会退化为指向第一个一维数组(a[0],也就是{3,6})的指针,类型是int (*)[2](指向包含2个int的数组的指针)。*a是解引用这个指针,得到a[0]这个一维数组名,而它又会退化为指向a[0][0]的指针(也就是&3),类型是int*。*a + 1就是把这个指针往后移动1个int的位置,指向a[0][1](也就是6)。- 最后
*(*a + 1)解引用这个指针,得到值6。
把这两个结果连起来输出,就是86啦。
C++多维数组的核心引用机制
其实C++里没有真正的“多维数组”,本质上是数组的数组——比如int a[M][N],其实是一个包含M个元素的数组,每个元素又是一个包含N个int的一维数组。理解这个本质,就能搞懂所有引用逻辑:
数组名的退化规则:在大多数表达式中(除了
sizeof、&、decltype这些特殊场景),数组名会自动退化为指向其首元素的指针:- 二维数组名
a退化为指向第一个一维数组(a[0])的指针,类型是int (*)[N]。 - 一维数组名
a[i]退化为指向a[i][0]的指针,类型是int*。
- 二维数组名
常见的引用方式等价关系:
a[i][j]等价于*(a[i] + j),也等价于*(*(a + i) + j)。
解释一下:a + i是指向第i个一维数组的指针,*(a+i)就是a[i](退化为int*),a[i]+j指向第i行第j个元素,解引用就是对应的值。*a[i]因为[]优先级高,所以是*(a[i]),也就是a[i][0](第i行的第一个元素)。(*a)[j]这里必须加括号,因为*优先级比[]低,*a是a[0]的退化指针,(*a)[j]就是a[0][j](第一行的第j个元素)。
内存布局的影响:
二维数组在内存里是行优先连续存储的,比如你的a[3][2],内存顺序是a[0][0], a[0][1], a[1][0], a[1][1], a[2][0], a[2][1]。所以如果用指针跨行访问也是可行的,比如*(a[0] + 2)其实就是a[1][0],因为a[0]是int*,加2会移动2个int的字节数,刚好跳到下一行的第一个元素。
内容的提问来源于stack exchange,提问作者Kaushik Nandan
相关产品推荐
相关产品推荐

