0

如果我初始化一个二维数组让我们说

Int a[2][3] = {
                              1, 2, 3,
                               4, 5, 6};

a[0]== &a[0]??

我知道a[0]指的是数组第一个元素的地址。那么&a[0]地址还在吗?

4

4 回答 4

3

首先, is 的类型和isarrayNum[0]Int[3]类型(我没有将 OP 更改为 probable )。&arrayNum[0]Int(*)[3]Intint

其次,数组可以衰减到指向其第一个元素的指针,因此arrayNum[0]可以衰减到&arrayNum[0][0]which 的 type Int*

这两个指针&arrayNum[0]&arrayNum[0][0]指向同一个位置,但它们的类型却大不相同。

于 2018-02-01T08:50:38.633 回答
1
于 2018-02-01T08:54:14.783 回答
1

有两种意义你可能会问是否a[0]等于&a[0]

a[0]&a[0]指向同一个地方?

和:

a[0] == &a[0]评估为真吗?

从你的问题中不清楚你的意思。你的文字问“是a[0]==&a[0]吗?” 由于“==”不是代码格式,因此不清楚您是否打算排除它。

第一个问题的答案是肯定的(假设a[0]自动转换为地址),第二个问题的答案不一定。

正如其他答案和评论所指出的那样,a[0]&a[0]不同的事情。a是一个由两个三个数组组成的数组inta[0]一个由三个组成的数组也是如此int,并且在大多数表达式中,它会自动转换为指向其第一个元素的指针。所以结果是一个指向 的指针int,有效的&a[0][0]。相比之下,&a[0]是三个数组的地址int

所以,这些表达式指向两个不同的对象,但是这两个对象从同一个位置开始,所以指针指向同一个“地方”。我们可以看到这一点:

(char *) a[0] == (char *) &a[0]  // Evaluates to true.

当我们将指针转换为指向 的指针时char,结果指向对象的第一个(最低地址)字节。由于两个指针指向同一个地方,这个表达式的计算结果为真。

但是,当您评估 时a[0] == &a[0],就会出现问题。为了符合 C 标准,指针的比较必须将指针与兼容类型进行比较。但是int和三个数组int不是兼容的类型。所以这种比较并不严格符合 C,尽管一些编译器可能允许它,可能带有警告消息。我们可以改为评估:

a[0] == (int *) &a[0]  // Value is not specified.

通过将右边的指针转换为指向 的指针int,我们使左右两边的类型相同,我们可以比较它们。但是,比较的结果没有定义。这是因为,尽管 C 标准允许我们将指向一种类型的指针转​​换为指向另一种类型的指针,但它通常不保证转换产生的值是什么,除非将其转换回原始类型,那么它将比较等于原始指针。(转换为指向字符类型的指针是特殊的;对于那些,编译器确实保证结果指向对象的第一个字节。)

所以,由于我们不知道它的值(int *) &a[0]是什么,所以我们不知道比较它a[0]会返回真还是假。

这可能看起来很奇怪;如果一个地址与另一个地址指向同一个地方,为什么它们比较不相等?在某些计算机上,有不止一种方法可以引用内存中的同一位置。地址实际上可能由部分组合形成,例如基地址加偏移量。比如地址(1000, 230),代表1230,和(1200, 30)指向同一个地方,也代表1230。但是显然(1000, 230)和(1200, 30)是不一样的。

当您比较两个指向相同类型的指针时,编译器会自动以执行比较所需的任何方式调整地址的表示。但是,当您将指向一种类型的指针转​​换为指向另一种(非字符)类型的指针时,类型的更改可能会阻止编译器获得正确执行此调整所需的信息。所以 C 标准没有告诉我们在这种情况下会发生什么。

于 2018-02-01T14:17:56.760 回答
0

不,它们不一样。

a[0]是 类型的元素int[3]&a[0]而是指向 的指针 (类型为 int*[3])a[0]

但是它们都指向同一个地址( 的第一个元素a[0]),但并不相同。

于 2018-02-01T09:48:00.177 回答