为什么以下具有相同的值:指向数组的指针,指向数组的取消引用指针?

Why do the following have the same value: the pointer to an array, the dereferenced pointer to the array?

例如,

int array[5] = {1}: // array of 5 integers
int (*ptr)[5] = &array; // pointer to an array of 5 integers

以下具有相同的值:

*ptr;
ptr;

如果我调用 printf("%p, %p", *ptr, ptr); 两个输出将完全相同。这是为什么?

如果你查看一维数组的内存布局,例如

int array[5];

这很有意义。

        array
          |
          V 
+---+---+---+---+---+---+
|   |   |   |   |   |   |
+---+---+---+---+---+---+

  array[0]
  |
  V 
+---+---+---+---+---+---+
|   |   |   |   |   |   |
+---+---+---+---+---+---+

Address of array
|
V 
+---+---+---+---+---+---+
|   |   |   |   |   |   |
+---+---+---+---+---+---+

Address of array[0]
|
V 
+---+---+---+---+---+---+
|   |   |   |   |   |   |
+---+---+---+---+---+---+

&array == &array[0] == array decayed to a pointer

指针声明为:

int (*ptr)[5] = &array;

ptr == &array
*ptr == array decayed to a pointer == &array[0] == &array

这就是为什么您在使用时看到打印的相同值:

printf("%p, %p", *ptr, ptr);

在此声明中

int (*ptr)[5] = &array;

指针ptr由数组地址初始化。数组的地址是第一行的第一个元素的地址。

表达式

*ptr;

为您提供对一维数组的第一个元素的引用 - 第一行或更准确地说是原始数组..

依次将表达式数组转换为指向其第一个元素的指针,并且等同于表达式 array*ptr 被转换为指向数组第一个元素的指针类型的右值 *ptr.:) 即表达式 *ptr 的类型为 int * 第一行的地址和第一行第一个元素的地址相同。 现在你有两个指针,ptr*ptr 第一个指针的类型为 int ( * )[5] 而第二个指针的类型为 int * 但两者具有相同的值。

由于 printf 是可变参数函数,因此 ellipsis conversion sequences are applied to the arguments. In particular, arrays are decayed 指向基础类型的指针:IOW,它被隐式转换为指向数组第一个元素的指针。因此,当您调用 printf("%p, %p", *ptr, ptr); 时,类型为 int[5]*ptr 将转换为值为 &array[0].

int*