关于指向数组的指针的困惑
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 == &a
和 pa == *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
,是一个数组,被转换成指向它第一个元素的指针。
我有一个关于指针和数组的非常基本但令人困扰的问题:
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 == &a
和 pa == *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
,是一个数组,被转换成指向它第一个元素的指针。