当我使用指针算法和!=
进行过程时,例如
template <typename T> void reverse_array ( T * arr, size_t n )
{
T * end = arr + n;
while (arr != end && arr != --end)
{
swap(arr,end);
++arr;
}
}
我总是非常谨慎,因为如果我把我的程序写错了,那么在一个角落的情况下,第一个指针可能会跳过&#34;跳过&#34;第二个。但是,如果数组是这样的
&arr[0] < &arr[1] < ... < &arr[n]
对于长度为arr
的任何数组n-1
,我不能做类似
template <typename T> void reverse_array ( T * arr, size_t n )
{
T * end = arr + n;
if (arr == end) break;
--end;
while (arr < end)
{
swap(arr,end);
++arr; --end;
}
}
因为它更具可读性?还是有危险迫在眉睫? Aren的内存只是整数类型,因此与<
相当?
答案 0 :(得分:4)
关系运算符被定义为在比较同一数组中的地址时(实际上也是类类型的对象,其中也存在一些关于内存布局的保证),包括一个接一个结束的指针。 / p>
但是,如果您“跳过”数组结束指针,则不再比较同一数组中的两个地址,并且行为未定义。 (一个原因是,当您在对象外部执行指针运算时,实际上可能会遇到环绕,但UB不受限制。)
关于跳转,你的情况非常好,因为你的end
指针不是数组的结尾,因为你总是至少有一个--end
。一个空数组,其中--end
移出数组,将是一个问题,但你可以单独测试它。
结论:您的第二个代码完全有效。
答案 1 :(得分:1)
对于C(因为你标记了两者),是的,可以在同一个数组中对它们进行比较:
当比较两个指针时,结果取决于指向的对象的地址空间中的相对位置。如果两个指向对象类型的指针都指向同一个对象,或者两个指针都指向同一个数组对象的最后一个元素,则它们相等。如果指向的对象是同一聚合对象的成员,则指向稍后声明的结构成员的指针比指向结构中先前声明的成员的指针要大,指向具有较大下标值的数组元素的指针比指向同一数组的元素的指针要大。具有较低的下标值。指向同一个union对象的成员的所有指针都比较相等。如果 expression
P
指向数组对象的元素,表达式Q
指向同一数组对象的最后一个元素,指针表达式Q+1
比大于P
。在所有其他情况下,行为未定义。
- C11 6.5.8,“关系运营商”。
但这不是因为它们只是“整体类型”,它们不是(和aren't guaranteed to be represented as in memory) - 这是因为它们也有为它们定义的行为。