关于指向数组的指针的困惑

Confusion about pointer to an array

我有一个关于指针和数组的非常基本但令人困扰的问题:

int main() {

    int a[5] = { 1,2,3,4,5 };
    int(*pa)[5] = &a;

    std::cout << a << std::endl;
    std::cout << &a << std::endl;

    std::cout << pa << std::endl;   
    std::cout << (*pa) << std::endl;

    return 0;
}

令人惊讶的是,所有四个输出都给出相同的地址,类似于 '006AF784',这意味着 a == &apa == *pa。这对我来说没有任何意义!

我当然理解'a'是指向第一个元素的指针,而'&a'是指向整个数组的指针,所以'a+1''&a+1'是不同的。但是一个变量等于它的地址,一个指针等于它指向的内容,这对我来说是无法理解的。我想知道 C 和编译器中到底发生了什么。

你几乎回答了你自己的问题。您想知道为什么 a&a 相同:指定数组的第一个表达式求值为指向第一个元素的指针,而另一个求值为指向整个元素的指针,正如您所注意到的。但两者的地址相同:第一个元素位于数组的基址。那为什么pa一样呢?为什么,因为您在其声明中从 &a 初始化了它;它的值来自 &a。和*pa一样,因为pa是指向数组的指针,所以*pa就是数组。但是数组的计算结果是指向第一个元素的指针:您已经在 a 中看到了这一点。表达式 *pa 指定与 a 相同的对象,具有相同的类型和相同的计算方式。

了解 a 不是指针很重要。在 C 的语义中,数组名称可转换为指针,但除此之外只是数组第一个元素地址的别名。

那么说到pa,你只是说这个指针应该是a的地址,所以你打印它的值当然应该是一样的。 当然,由于 *pa 是一个数组(它的数组名称),它只是为其第一个元素的地址添加了别名——这也是 a 的地址。

隐式转换和 "arrays decaying into pointers" 是其背后的原因。

让我们绘制这个数组。假设它从地址 0x98 开始存储。

 +———————————————————+
 | 1 | 2 | 3 | 4 | 5 |
 +———————————————————+
 ^
 |
0x98

应该清楚数组的地址是0x98
很明显,它的第一个元素的地址也是0x98。

打印时

std::cout << a << std::endl;

a 被转换为指向其第一个元素的指针——它等同于

std::cout << &a[0] << std::endl;

如上所示,这与指向数组的指针具有相同的数值。

同样,当你打印

std::cout << (*pa) << std::endl;

*pa,是一个数组,被转换成指向它第一个元素的指针。