一维/二维数组指针的基本类型是什么,为什么需要双重解引用?

What are the underlying types of pointers to 1D/2D arrays, and why is double dereferencing needed?

假设我这样初始化数组和变量:

int arr1d[3] = { 1, 2, 3 };
int* arrptr = arr1d;
int (*ptr1d)[3] = &arr1d;

int arr2d[2][3] = { {1, 2, 3}, {4, 5, 6} };
int (*ptr2d)[3] = arr2d;

因此,arr1d 是一个包含 3 个整数的数组。在幕后,arr1d 是指向数组第一个元素的指针,即 &arr1d[0]。因此,我们可以将 arr1d 分配给 int* arrptr.

ptr1d 指向一个包含 3 个整数的数组。 arr1d 是指向 &arr1d[0]int*,但为什么 &arr1dint (*)[3] 类型?天真地,我认为写 &arr1d 只是给了我们一个地址来分配给指针。这是数组指针特有的东西吗?

显然,arr2dint (*)[3] () 类型。 ptr2d*ptr2d 具有相同的值,那么为什么需要第二次取消引用呢?我的想法是,这可能是因为 ptr2dint (*)[3] 类型(指向 3 个整数的数组的指针),*ptr2dint* 类型(指向 int 的指针),因此 **ptr2d 最终为我们提供了第一个数组的第一个值 1。因此,我们并没有像在许多图表中看到的那样在此处取消引用来遍历地址,我们正在取消引用以访问基础类型。这个对吗?这是否解释了为什么 &arr1d 的类型也是 int (*)[3](我们要“更上一层楼”?)

谢谢。

int arr1d[3] = { 1, 2, 3 };

So, arr1d is an array of 3 integers.

正确。

Under the hood, arr1d is a pointer to the first element of the array, i.e. &arr1d[0]

不清楚您所说的“幕后”是什么意思,但在 C++ 语言中,数组就是数组。它不是指针类型。说 arr1d&arr1d[0] 是错误的。如果你的意思是机器代码,那是错误的,因为机器代码既没有类型也没有变量。

Hence, we can assign arr1d to int* arrptr.

我们可以将 arr1d 分配给 int* arrptr,因为数组类型可以隐式转换为指向其元素类型的指针。而这个转换的结果确实与 &arr1d[0] 具有相同的值和类型。这种转换称为衰减。

Naively, I thought that writing &arr1d simply gave us an address to assign to the pointer.

&arr1d 只是给了我们一个可以分配给指针的地址。所以,你想对了。

but why is &arr1d of type int (*)[3]?

arr1d 的类型是 3 个整数的数组,即 int[3]。获取它的地址会给你一个指向 3 个整数数组的指针,即 int (*)[3]).

Is this is something specific to pointers to arrays?

一元 & 总是给出一个指向操作数的指针(除非 class 类型的运算符已被重载,在这种情况下它给出任何重载 returns ; 重载一元 & 是罕见的)。它被称为 addressof 运算符。

当然,只有当操作数是一个数组时,&才会给你一个指向数组的指针。其他时候它会给出一些其他指针类型。

int (*ptr2d)[3] = arr2d;

Apparently, arr2d is of type int (*)[3] (which I learned from this post).

你学错了。 arr2d 的类型是 int[2][3]int[3]arr2d 的元素类型,因此 int (*)[3] 是数组类型衰减到的指针类型;指向该数组元素的指针。

*ptr2d is of type int* (pointer to an int)

错了。 *ptr2dint[3] 类型(3 个整数的数组)。该数组确实隐式转换为指向其第一个元素的指针,其类型为 int*.