考虑以下简单代码对数组进行排序。
int myarray[4] = {};
std::sort(myarray, myarray + 4);
我知道创建一个指向C风格数组末尾的指针是有效的。
我最近看过这样的代码:
std::sort(myarray, &myarray[4]);
我不确定它是否有效,因为它取消引用数组边界之外的元素,即使元素值没有用于任何东西。
这是有效的代码吗?
答案 0 :(得分:7)
A[i]
, *(A + i)
在语法上等同于A
。
因此,&A[i]
在语法上等同于&(*(A + i))
。
当*(A + i)
没有未定义的行为时,&(*(A + i))
的行为与A + i
相同。
问题在于myarray[4]
在语法上等同于*(myarray + 4)
,它从数组的边界取消引用位置。根据标准,这是未定义的行为。
所以你绝对应该更喜欢myarray + 4
而不是&myarray[4]
- 后者是未定义的行为。
&myarray[4]
有" 正确"大多数(如果不是全部)编译器的行为不能免除它根据标准的未定义行为。
答案 1 :(得分:0)
它与原始文件有效的原因相同:它可以确定 所在元素的位置。在后一种情况下,仅仅因为它标识了一个不存在的元素,因为它不会尝试访问它,所以没有问题。
或者,更简洁:myarray+4
和&myarray[4]
是同义词。
答案 2 :(得分:-2)
该标准要求指向数组末尾的指针是指针的有效值。 (这并不意味着可以取消引用)。
这在一些地方是必需的,例如在指针比较(5.9,关系运算符)中:
如果两个指针指向同一个数组的元素或超出的指针 数组的末尾,指向具有较高下标的对象的指针 比较高。
这实际上是STL所依赖的。 "结束()"迭代器的函数相当于数组末尾的1。
我在第27.6.2节:流缓冲要求
中也看到了这一点所以你的片段:
std::sort(myarray, &myarray[4]);
与使用int
的向量基本相同 vector<int> yourArray;
std::sort(yourArray.begin(), yourArray.end());
答案 3 :(得分:-2)
根据C99标准中的§6.5.3.2,其有效C:
一元&amp;运算符产生其操作数的地址。如果是操作数 类型为''type'',结果有''指向类型''的指针。如果 操作数是一元*运算符的结果,既不是运算符也不是运算符 和&amp;运算符被评估,结果好像两者都被省略
在C ++中似乎没有等效的对应物,可能是由于运算符重载。