如果我初始化一个二维数组让我们说
Int a[2][3] = {
1, 2, 3,
4, 5, 6};
是a[0]
== &a[0]
??
我知道a[0]
指的是数组第一个元素的地址。那么&a[0]
地址还在吗?
如果我初始化一个二维数组让我们说
Int a[2][3] = {
1, 2, 3,
4, 5, 6};
是a[0]
== &a[0]
??
我知道a[0]
指的是数组第一个元素的地址。那么&a[0]
地址还在吗?
首先, is 的类型和isarrayNum[0]
的Int[3]
类型(我没有将 OP 更改为 probable )。&arrayNum[0]
Int(*)[3]
Int
int
其次,数组可以衰减到指向其第一个元素的指针,因此arrayNum[0]
可以衰减到&arrayNum[0][0]
which 的 type Int*
。
这两个指针&arrayNum[0]
都&arrayNum[0][0]
指向同一个位置,但它们的类型却大不相同。
有两种意义你可能会问是否a[0]
等于&a[0]
:
做
a[0]
和&a[0]
指向同一个地方?
和:
a[0] == &a[0]
评估为真吗?
从你的问题中不清楚你的意思。你的文字问“是a[0]
==&a[0]
吗?” 由于“==”不是代码格式,因此不清楚您是否打算排除它。
第一个问题的答案是肯定的(假设a[0]
自动转换为地址),第二个问题的答案不一定。
正如其他答案和评论所指出的那样,a[0]
是&a[0]
不同的事情。a
是一个由两个三个数组组成的数组int
。a[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 标准没有告诉我们在这种情况下会发生什么。
不,它们不一样。
a[0]
是 类型的元素int[3]
,&a[0]
而是指向 的指针 (类型为 int*[3])a[0]
。
但是它们都指向同一个地址( 的第一个元素a[0]
),但并不相同。