#include <stdio.h>
int main()
{ int arr2D[3][3];
printf("%d\n",((arr2D==*arr2D) && (*arr2D==arr2D[0])));
return o;
}
值在* arr2D和 arr2d 处的存储方式相同,而 arr2D 是一个常量指针,它将存储第一个元素的地址 arr2D 表示存在于arr2D指向的地址中的值吗?
答案 0 :(得分:2)
如果我们在“纸”上绘制您的数组,它将看起来像这样
+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+ | arr2D[0][0] | arr2D[0][1] | arr2D[0][2] | arr2D[1][0] | arr2D[1][1] | arr2D[1][2] | arr2D[2][0] | arr2D[2][1] | arr2D[2][2] | +-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
然后,您必须记住,数组自然会衰减为指向其第一个元素的指针。当期望有一个指针时,它就是arr2D
,与&arr2D[0]
相同。
现在,如果我们“重绘”数组,但仅针对arr2D[0]
(这与您的问题最相关),并使用一些可能的指针:
+-------------+-------------+-------------+-----+ | arr2D[0][0] | arr2D[0][1] | arr2D[0][2] | ... | +-------------+-------------+-------------+-----+ ^ | &arr2D[0] | &arr2D[0][0]
由于我们知道arr2D
与&arr2D[0]
相同,因此我们可以在表达式arr2D == *arr2D
中进行替换。这使我们&arr2D[0] == *&arr2D[0]
。
取消引用的*
和地址的&
相互抵消,所以我们有了&arr2D[0] == arr2D[0]
。
现在继续进行……我们知道数组会衰减到指向其第一个元素的指针,并且我们知道arr2D[0]
是一个数组;这意味着它将衰减到&arr2D[0][0]
,剩下表达式&arr2D[0] == &arr2D[0][0]
。如图所示,这两个地址相同,这意味着比较是正确的。
重要说明: :虽然&arr2D[0]
和&arr2D[0][0]
可能都指向同一位置,但它们的类型是不同。 &arr2D[0]
的类型为int (*)[3]
,而&arr2D[0][0]
的类型为int *
。
借助上述信息,应该很容易理解其他比较*arr2D == arr2D[0]
,尤其是因为已经提到了所有比较。
答案 1 :(得分:2)
这不是有效的C代码。
arr2D
在表达式中使用时会衰减为指向第一个元素int (*)[3]
的指针。 *arr2D
给出2D数组的第一项,即int[3]
,它在表达式中使用时也会衰减成int*
。
因此,代码将int (*)[3]
与int*
进行了比较。它们不是兼容的指针类型,不能进行比较-这是违反标准(C17 6.5.9 / 2)的约束,编译器必须生成诊断消息。这意味着这是一个严重的错误,任何尝试在合格的C编译器中尝试代码的人都会找到它。
*arr2D
和arr2D[0]
始终相等。
代码的打印内容是任何人的猜测,因为包含约束违例的代码被视为具有未定义的行为。