我可以看看那个地址吗?
可能重复:
通过C ++标准,通过下标:合法或不合法的方式获取一个最后一个数组元素的地址?
int array[10];
int* a = array + 10; // well-defined
int* b = &array[10]; // not sure...
最后一行是否有效?
是的,您可以将地址放在数组的末尾,但不能对其进行解引用。 对于10个物品的array+10
, array+10
将起作用。 几次(由委员会等人)争论是否&array[10]
真的会导致不确定的行为(如果确实如此,是否真的应该这样做)。 它的底线是,至少根据现行标准(包括C和C ++)它会正式导致未定义的行为,但如果有一个编译器实际上不起作用,那么任何参数都没有人能够找到或引用它。
编辑:有一次,我的记忆是一半正确 - 这是(委员会的)一份官方缺陷报告(的一部分),至少有一些委员(如汤姆李梅)认为措辞已经改变,所以不会导致未定义的行为。 OTOH,DR的日期从2000年开始,状态仍然是“起草”,因此可以质疑它是否确实是固定的,或者很可能是(我没有通过N3090 / 3092了解)。
然而,在C99中,这显然不是未定义的行为。
正如其他答案指出的,表达式array[10]
等价于*(array + 10)
,这看起来会导致刚刚超出数组末尾的元素的未定义解引用。 然而,表达式&array[10]
等价于&*(array + 10)
,并且C99标准明确了(6.5.3.2地址和间接运算符):
一元&运算符返回其操作数的地址。 如果操作数的类型为''type'',则结果的类型为'',指向类型''。 如果操作数是一元*
运算符的结果,那么该算子和&运算符都不会被计算,结果就好像两个都被省略一样,除了运算符的约束仍然适用并且结果不是左值。 同样,如果操作数是[]
运算符的结果,则评估[]
所隐含的&
运算符和一元运算符*
,结果就好像&
运算符已被删除, []
运算符已更改为a +运算符。
所以,没有任何关于&array[10]
未定义 - 没有取消引用操作发生。
array[10]
相当于*(array + 10)
(也相当于10[array]
),所以&array[10]
就像从*(array+10)
移除*
一样。 任何体面的编译器都应该发出相同的代码(和相同的警告)。
上一篇: May I take the address of the one
下一篇: Does std::list::remove method call destructor of each removed element?