& a [n]是否有效,其中n是数组的大小?

时间:2014-10-10 00:08:32

标签: c++ language-lawyer

考虑以下简单代码对数组进行排序。

int myarray[4] = {};
std::sort(myarray, myarray + 4);

我知道创建一个指向C风格数组末尾的指针是有效的。

我最近看过这样的代码:

std::sort(myarray, &myarray[4]);

我不确定它是否有效,因为它取消引用数组边界之外的元素,即使元素值没有用于任何东西。

这是有效的代码吗?

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 ++中似乎没有等效的对应物,可能是由于运算符重载。