初学者关于数组和指针的问题

Questions about array and pointer from a beginner

本文关键字:指针 问题 数组 于数组 初学者      更新时间:2023-10-16

我是C++和一般编程的新手。当我学习指针和数组的概念时,我感到困惑。 以int*p = arr; int arr[]={5,1};为例。我了解到arr也是一个指针。

p(a pointer)                          arr[0]
the thing it stores:    [first element address: 601]                   [5]
its memory         :                501                                601
address(just make 
some fake address)
However,                                 arr(the pointer)
[first element address: 601]
601

通常,指针应具有与数组不同的地址。但是,作为指向第一个元素的指针,arr与第一个元素具有相同的地址。所以我感到困惑。而我想知道是不是因为arr[0]的记忆盒被分成两部分:一部分用于arr[0],一部分用于指针arr,以便它们在内存中具有相同的地址。

我了解到arr也是一个指针。

然后你被教导了一些错误的东西,这可能是你困惑的原因。

如果你有int arr[] = {5, 1};那么arr是一个数组,而不是一个指针。数组可以隐式转换为指向其第一个元素的指针。但数组本身仍然是一个数组。例如,做一个int arr[512];并检查sizeof(arr)将是什么。如果arr是一个指针,那么它应该与sizeof(int*)相同。但这并不是因为数组不是指针。它们是数组...

如果你写

int arr[] = {5, 1, 3};
int* p = arr;

你最终得到的是这样的:

arr
+---+---+---+
0xA0:  | 5 | 1 | 3 |
+---+---+---+
p
+-------+
0xB0:  |  0xA0 |
+-------+

在内存中的某个地方,假设在地址 0xA0 处,将有一个对象,该对象是一个由三个int组成的数组。标识符arr只是在代码中表示此数组对象的名称。数组对象包含三个一个接一个放置的int对象。单个int(数组的元素)是完整数组对象的子对象。请注意,完整数组对象的地址与作为第一个数组元素的子对象的地址相同。然而,数组对象arr(类型为int[3]并包含整个数组)与第一个元素(类型为int)之间存在差异。

同样在内存中,假设在地址 0xB0 处,将有另一个类型int*的对象。标识符p只是在代码中表示此指针对象的名称。p是一个与arr完全分开的对象。它存在于一个完全不同的地址。 初始化p以指向表达式arr的结果。表达式arr表示我们的数组。指针和数组是完全不同的东西。将数组分配给指针的方式有什么意义!?这是怎么回事?

要了解int* p = arr;为什么有效以及它的作用,让我们稍微备份一下,想想我们如何实际访问arr元素。如果我们知道数组元素开始的地址,我们可以通过将元素大小乘以元素索引来简单地计算任何元素的地址。这正是指针算术在C++中的工作方式(这不是巧合):给定一个指向数组第一个元素p的指针,我们可以通过将它们加在一起来获得指向i-th 元素的指针:p + i。实际上,用于元素访问(例如p[i])的下标运算符[]字面上定义为*(p + i)的速记表示法。

因此,虽然数组和指针是完全不同的东西,但数组只有在指针进入图片时才真正有用。使用数组通常需要访问其元素。访问数组的元素通常需要指针。由于通常需要指向第一个元素的指针才能真正将数组用于任何操作,因此数组可以隐式转换为指向 C 和 C++ 中第一个元素的指针。

当你写p = arr你真正写的就是p = &arr[0]。因为,虽然不能将数组分配给指针,但可以将int数组隐式转换为指向数组第一个元素的int*。并且可以将int*分配给指针。这就是为什么上面示例中的p将包含数组第一个元素的地址(恰好与数组的地址相同)。

但是,由于数组是数组,而不是指针(如有必要,它们可以转换为指向第一个元素的指针),因此获取像&arr这样的数组的地址将导致指向数组对象本身的指针(正如我们所看到的,它与第一个元素具有相同的地址)。&arr的类型将int(*)[3](指向三个int数组的指针)。不像&p,它实际上将是一个指向int的指针......

注意:当你写arr[2]时,你真正写的是*((&arr[0]) + 2),因为[]运算符在指针上工作。数组不是指针,但可以隐式转换为指向其第一个元素的指针......

我建议指针不是C++的初学者主题,它们大多只是从 C 继承而来的。如果可以,您应该避免使用它们并使用 STL 容器。


在代码示例中,arr的类型为int[2]。您应该将其在内存中视为如下所示:

arr --+
|
v
+---+---+
| 5 | 1 |
+---+---+

arr中包含的值是第一个元素(5)的位置。arr本质上是指向该5的指针。唯一的区别是类型(int[2])也记住了有多少元素。

赋值语句p = arr工作p因为 的类型是int*int[]可以衰减到该类型。