关于指向数组的指针的混淆

Confusion about pointer to an array

本文关键字:指针 数组 于指      更新时间:2023-10-16

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

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'不同。但是变量等于它的地址,指针等于指向的内容,这对我来说是不可理解的。

是隐式转换和"数组衰变成指针"的原因。

我们来画这个数组。假设它是从地址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作为数组,被转换为指向其第一个元素的指针。

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

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

当涉及到pa时,你只是说这个指针应该是a的地址,所以当然当你打印它的值时,它应该是一样的。当然,由于*pa是一个数组(它的数组名),它只是别名它的第一个元素的地址-这也是a的。