关于指针和数组我有一个非常基本但令人难以忘怀的问题:
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和编译器中究竟发生了什么。
答案 0 :(得分:1)
你几乎回答了自己的问题。您想知道为什么a
,&a
是相同的:指定数组的第一个表达式求值为指向第一个元素的指针,另一个表达式指向指向整个事物的指针,正如您所注意到的那样。但两者都是相同的地址:第一个元素位于数组的基址。那为什么pa
一样?为什么,因为你在声明中从&a
初始化了它;它从&a
得到了它的价值。并且*pa
是相同的,因为pa
是指向数组的指针,因此*pa
是数组。但是数组计算为指向第一个元素的指针:并且您已经使用a
看到了这一点。表达式*pa
指定与a
相同的对象,具有相同的类型并以相同的方式进行评估。
答案 1 :(得分:1)
理解a
不是指针是很重要的。在C的语义中,数组名称可以转换为指针,但在其他方面只是数组第一个元素的地址的别名。
然后说到pa
,你只是说这个指针应该是a
的地址,所以当你打印它的值时,它应该是相同的。
当然,因为*pa
是一个数组(它的数组名称),所以它只是别名它的第一个元素的地址 - 也是a
的。
答案 2 :(得分:1)
隐式转换和&#34;数组衰减为指针&#34;就在这背后。
让我们绘制这个数组。假设它从地址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
被转换为指向其第一个元素的指针。