为什么在C中不允许的数组的第一个元素之前指向一个?

时间:2017-09-13 14:03:00

标签: c arrays pointers

在C中,允许指针指向数组的任何元素,以及指向数组最后一个元素的指针;指出超出此范围的是未定义的行为(C11标准,§6.5.6,第8段)。

但是,为什么指向一个数组的第一个元素之前没有类似的允许?

PS:我知道,为了规避上述限制,有时可以声明一个大于需要的数组1单位,然后只使用1对的位置来存储元素,最后留下位置0作为保证向后遍历阵列将是安全的。但是,有时我们必须使用给定的数组,然后在第一个元素之前指向一个数组的问题仍然存在。

3 个答案:

答案 0 :(得分:3)

我不确定这是理由,但在实践中你需要

  • 抛弃指针上的关系运算符(由于环绕)或
  • 要求不要将大小为X的对象存储在小于X的地址或
  • 将可用内存减半(由于负地址)。

这两种选择都不是很愉快。

答案 1 :(得分:3)

主题"允许指针指向数组的任何元素"很长一段时间以来一直是C语言的一部分;它已经可以在ANSI-C standard / C89中找到(参见6.3.6添加运算符,第46f页),它已经提到在这个范围内实现必须防止算术溢出。其中,在第47页的末尾,人们还可以找到一个解释其背后理性的脚注:

  

接近指针算法的另一种方法是首先转换   指针到字符指针:在这个方案中的积分   首先在转换后的指针中添加或减去表达式   乘以最初指向的对象的大小和   结果指针将转换回原始类型。对于指针   减去字符之间差异的结果   指针同样除以最初对象的大小   指着。

     

以这种方式查看时,实现只需要提供一个额外的   紧接着之后的字节(可能与程序中的另一个对象重叠)   对象的结尾是为了满足"一个过去的最后一个元素"   要求

由此我们可以推断出原因是防止算术溢出,实现必须避免在数组和一个过去的范围内(但显然不需要保证< / em>表示数组第一个元素之前的元素。)

为什么不在之前 - 很可能(我没有证据证明)与指针范围可能仅限于特定内存段,并将对象放在内存段的开头以及#34等算术数据这一事实相关联;第一个元素之前的一个&#34;可能会导致溢出。我说声明&#34;实现只需要在对象结束后提供一个额外的字节(可能与程序中的另一个对象重叠)&#34; 是一个明确的指标支持这个假设,因为此时的标准明确地解决了最后一个字节&#34; -topic,但没有提出类似于内存段开头的内容。

答案 2 :(得分:2)

为什么允许首先指出一个超过数组的理由是启用某些类型的&#34; C ++ / STL-ish&#34;编程模式:

SELECT 
      customerid
    , orderdate
FROM yourtable 
WHERE EXTRACT(YEAR FROM orderdate) = 2010;

对于像上面那样的情况,将一个项目指向数组之后是有意义的。但是,实际访问该项目当然没有意义 - 这将是未定义的行为。

所以上面是一个特例。但是,没有任何情况可以在数组之前指出一个项。