可能重复:
C:为什么数组的地址等于它的值?
我在 GCC 4.4.1 中测试,我发现&a=a
. 我无法理解。我认为&a
应该是存储数组地址的地址,不能相同。有人可以给我一个很好的解释吗?非常感谢。
可能重复:
C:为什么数组的地址等于它的值?
我在 GCC 4.4.1 中测试,我发现&a=a
. 我无法理解。我认为&a
应该是存储数组地址的地址,不能相同。有人可以给我一个很好的解释吗?非常感谢。
数组是内存中的对象。它有一个地址和一个大小。在某些情况下,数组衰减为指向其第一个元素的指针也是正确的。所以从数字上看,如果a
和&a
都作为指针值进行比较,它们比较相等,因为它们都指向内存中的相同地址。但是它们具有不同的数据类型:在某些上下文中a
具有类型int[4]
(“array 4 of int
”)或int*
(“pointer to int
”),而&a
始终具有类型int (*)[4]
(“pointer to array 4 of int
”)。
&a points here
|
V
+------+------+------+------+
| a[0] | a[1] | a[2] | a[3] | sizeof(a) == 16
+------+------+------+------+
^
|
&a[0] also points here
In certain contexts, 'a' means &a[0]
因此,(void *)a == (void *)&a
。
还要注意,因为a
and&a
指向不同的数据类型(特别是指向的类型具有不同的大小),所以进行指针运算会产生不同的结果。 a+1
将指向&a[1]
(前进一个int
值),而&a+1
将指向刚刚超过数组末尾的&a[4]
,因为它前进了一个“array 4 of int
”单位:
&a+1 points here
|
V
+------+------+------+------+
| a[0] | a[1] | a[2] | a[3] |
+------+------+------+------+
^
|
a+1 points here
&a
指向数组中第一个元素的地址(即a[0]
)。
a
保存数组的地址。
并且数组(ie a
)的地址等于数组中第一项的地址(ie &a
)。
如果a
声明为int a[4]
,&a
则为类型为的指针int *[4]
(指向 4 数组的指针int
)。
在大多数表达式上下文中使用时,a
计算结果为指向 的第一个元素的指针a
,并且类型为int*
。表达式完全等价于&a[0]
。这是 C99 标准 6.3.2.1/3“左值、数组和函数指示符”中的要求:
除非它是 sizeof 运算符或一元 & 运算符的操作数,或者是用于初始化数组的字符串文字,否则类型为 ''array of type'' 的表达式将转换为类型为 ''pointer to type'' 指向数组对象的初始元素并且不是左值。
这通常称为衰减到指针;您会听到它被称为“a
衰减为指针”。
因此,根据定义,数组的第一个元素与数组本身具有相同的地址。因此,虽然&a
和a
具有不同的类型,但它们具有相同的指针值。
a
是数组。
&a
是数组的地址。
在大多数情况下,a
在表达式中使用的计算结果为数组第一个元素的地址。当然,哪个地址与数组的地址相同,但类型不同。&a
不是这些上下文之一,但a
您比较的 RHS 是。
对于具有相同值但类型不同的两个事物的另一个示例,请考虑(int)1 == (char)1
该问题(int)1 == (float)1
。相同的数值,因此它们比较相等,但类型不同,因此它们在所有用途中的行为都不相同。
“它”不会将数组的地址存储在您有权担心的任何地方。如果a
是一个自动变量,编译器“知道”a
堆栈指针的偏移量,它不一定存储a
任何地方的地址,除非你告诉它。如果它是一个全局变量,那么它的地址可能存储在某个符号表中的某个地方,但是您的程序不会直接访问符号表中的那个位置。
address of the array
等于 address of the first item in the array
。_
int a[4];
a
是 4 的数组int
。它的类型名称是int [4]
.
&a
是指向数组 4 的指针int
。它的类型名称是int (*)[4]
.
请注意,该表达式&a = a
在 C 中无效:赋值运算符的左操作数必须是可修改的左值,但&
运算符的结果绝不是左值。