需要澄清指针行为

Posted

技术标签:

【中文标题】需要澄清指针行为【英文标题】:Need for clarification with pointer behaviour 【发布时间】:2021-08-01 21:36:55 【问题描述】:

假设我有一个数组int a[] = 2, 3, 4; 为什么指向第一个元素&a[0] 的指针可以指向数组元素或一般的值,而指针&a 不能?

cout << (&a[0])[1]; // 3
cout << (&a)[0]; // some weird adress (presumably of the array itself
cout << (&a)[1]; 
// a higher adress probably the adress after the end of the array so &a + 0xC (length of array) + 0x1

指针本身 (&a)、类型(带有 int (*)...的东西)是否像某种数组?

【问题讨论】:

struct s int x, y , z; b;做同样的实验并比较结果 【参考方案1】:

数组和指针是 C++ 中的两种不同类型,它们之间有足够的相似性,如果不能正确理解它们会造成混淆。指针是初学者最难掌握的概念之一这一事实也无济于事。

所以我觉得需要快速速成课程。

速成课程

数组,简单

int a[3] = 2, 3, 4;

这将创建一个名为 a 的数组,其中包含 3 个元素。

数组已经定义了数组下标操作符:

a[i]

计算为数组的第 i'th 元素。

指针,简单

int val = 24;
int* p = &val;

p是一个指针,指向对象val的地址。

指针定义了 indirection (dereference) 操作符:

*p

计算为p指向的对象的值。

指针,作用类似于数组

指针为您提供内存中对象的地址。它可以是上面示例中的“独立对象”,也可以是作为数组一部分的对象。指针类型和指针值都不能告诉你它是哪一种。只是程序员。这就是为什么

指针还定义了 数组下标 运算符:

p[i]

计算ith 元素到p 指向的对象的“右侧”。这假定 p 的对象指针是数组的一部分(p[0] 中的对象指针不需要是数组的一部分)。

请注意,p[0] 等同于(完全相同)*p

数组,就像指针一样

在大多数情况下,数组名称衰减为指向数组中第一个元素的指针。这就是为什么许多初学者认为数组和指针是一回事。事实上他们不是。它们是不同的类型。

你的例子

回到你的例子。

为什么指向第一个元素&amp;a[0]的指针可以指向数组元素,或者一般的值,

现在我希望你能看到,如果p 指向数组arr 的第一个元素,那么p[i] 等价于arr[i]。因为&amp;a[0] 是指向数组第一个元素的指针,所以(&amp;a[0])[i] 等价于a[i]

...但是指针&amp;a不能?

如上所述,数组不是指针。

因此,指向数组的指针与指向数组第一个元素的指针不同。获取数组的地址是数组名称不会衰减为指向其第一个元素的指针的少数实例之一。

所以&amp;a 是指向数组的指针,不是指向数组第一个元素的指针。数组和数组的第一个元素都从相同的地址开始,因此两者的值(&amp;a&amp;a[0])相同,但它们的类型不同,这在应用取消引用或数组下标时很重要操作员给他们:

Expression Expression type Dereference / array subscript expresison Dereference / array subscript type
a int[3] *a / a[i] int
&amp;a int (*) [3] (pointer to array) *&amp;a / &amp;a[i] int[3]
&amp;a[0] int * *&amp;a[0] / (&amp;a[0])[i] int

【讨论】:

为什么下标的&amp;a返回一个指针,而不是int[3]呢? &amp; 地址 运算符。 &amp;x 将始终是指向 x 类型的指针。 没关系,它实际上是在取消对int[3] 的引用,但这又会衰减到int *(第一个元素)。非常感谢。 @Raumschifffan 你能详细说明一下吗?你要评判什么表情?我想确保你做对了。指针和数组以及指向数组的指针很快就会变得混乱:) @Raumschifffan 正确。当您将数组传递给函数(作为参数)时,数组会衰减。这就是为什么cout &lt;&lt; a 没有接收到数组,a 在传递给cout 之前衰减到一个指针。您可以编写一个打印模板函数,该函数通过引用获取一个数组,并且该函数可以打印该数组,这是另一个讨论。【参考方案2】:

&amp;a 是指向数组的指针。当您间接通过该指针时,您将获得指向的数组。

&amp;a[0] 是 - 就像你说的 - 一个指向数组元素的指针。当您间接通过该指针时,您将获得指向的元素。

【讨论】:

以上是关于需要澄清指针行为的主要内容,如果未能解决你的问题,请参考以下文章

基于模板类型指针的条件函数行为

这就是我使用指针的原因吗?

如何在 JavaScript 中复制指针事件的行为:无

在 Android Studio 上移动鼠标指针

指针的意外行为(操作时)但使用双指针时定义的行为

在ansi c中释放指向全局指针数组的本地指针