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

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

本文关键字:数组 指针 引用 取消 为什么      更新时间:2023-10-16

例如,

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 (*ptr)[5] = &array;

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

表达

*ptr;

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

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

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

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);

由于 printf 是一个可变参数函数,因此省略号转换序列应用于参数。特别是,数组被衰减为底层类型的指针:IOW,它被隐式转换为指向数组第一个元素的指针。因此,当您调用 printf("%p, %p", *ptr, ptr); 时,*ptr 的类型为 int[5] 将转换为值为 &array[0]int*