通过下标获取一个过端数组元素的地址:C+标准是否合法?

通过下标获取一个过端数组元素的地址:C+标准是否合法?

我已经多次看到它断言C+标准不允许使用以下代码:

int array[5];int *array_begin = &array[0];int *array_end = &array[5];

&array[5]这种情况下的C+代码合法吗?

如果可能的话,我想要一个参考标准的答案。

知道它是否符合C标准也会很有趣。如果它不是标准的C+,为什么决定将它与array + 5&array[4] + 1?


森林海
浏览 529回答 3
3回答

慕的地8271018

是的,这是合法的。从C99标准草案:第6.5.2.1条第2款:后缀表达式,后面是方括号中的表达式[]是数组对象的元素的订阅指定。下标运算符的定义[]那是E1[E2]是相同的(*((E1)+(E2)))..因为适用于二进制文件的转换规则。+操作员,如果E1是数组对象(等价地,指向数组对象的初始元素的指针)E2是整数,E1[E2]指定E2-第四要素E1(从零算起)。第6.5.3.2条第3款(重点是地雷):一元&运算符生成其操作数的地址。如果操作数具有“类型类型‘,结果有类型’指向类型“”如果操作数是一元数据的结果*运算符,则该运算符和&运算符被计算,结果就好像两者都被省略了一样,只是对运算符的约束仍然适用,并且结果不是lvalue。同样,如果操作数是[]运算符,既不是&运算符,也不是一元*,这是由[]值计算,结果就好像&运算符被移除,并且[]操作符更改为+操作者..否则,结果是指向其操作数指定的对象或函数的指针。第6.5.6条第8款:将具有整数类型的表达式添加到指针或从指针中减去时,结果具有指针操作数的类型。如果指针操作数指向数组对象的一个元素,并且数组足够大,则结果指向与原始元素偏移的元素,从而使结果数组元素和原始数组元素下标的差值等于整数表达式。换句话说,如果表达式P指向i-数组对象的第四个元素,表达式(P)+N(相当于,N+(P))和(P)-N(在哪里N有价值n)分别指向i+n-第四和i−n-数组对象的第四个元素,只要它们存在。另外,如果P指向数组对象的最后一个元素,即表达式。(P)+1指向数组对象的最后一个元素,如果表达式Q指向数组对象的最后一个元素,即表达式。(Q)-1指向数组对象的最后一个元素。如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则计算值不会产生溢出;否则,行为将未定义。如果结果指向数组对象的最后一个元素,则不应将其用作一元的操作数。*计算的运算符。注意,该标准显式地允许指针在数组结束后指向一个元素,但前提是它们不被取消引用..由6.5.2.1和6.5.3.2&array[5]等于&*(array + 5),这相当于(array+5),它指向数组结束后的一个。这不会导致取消引用(6.5.3.2),因此它是合法的。

茅侃侃

它是合法的。根据GCC编写的C+文档, &array[5]是合法的。在C+中在C您可以安全地处理数组结束后的元素-您将得到一个有效的指针。所以&array[5]作为一种表达是合法的。但是,尝试取消指向未分配内存的指针仍然是未定义的行为,即使指针指向有效地址。因此,试图取消引用由该表达式生成的指针仍然是未定义的行为(即非法),即使指针本身是有效的。但在实践中,我认为它通常不会导致坠机。编辑:顺便说一句,STL容器的end()迭代器通常是这样实现的(作为指向一个过端的指针),所以这很好地证明了这种做法是合法的。编辑:哦,现在我看到你并不是真的在问持有指向那个地址的指针是否合法,但是获取指针的确切方式是否合法。我会听从其他人的意见。
打开App,查看更多内容
随时随地看视频慕课网APP