在C中,允许指针指向数组的任何元素,以及指向数组最后一个元素的指针;指出超出此范围的是未定义的行为(C11标准,§6.5.6,第8段)。
但是,为什么指向一个数组的第一个元素之前没有类似的允许?
PS:我知道,为了规避上述限制,有时可以声明一个大于需要的数组1单位,然后只使用1对的位置来存储元素,最后留下位置0作为保证向后遍历阵列将是安全的。但是,有时我们必须使用给定的数组,然后在第一个元素之前指向一个数组的问题仍然存在。答案 0 :(得分:3)
我不确定这是理由,但在实践中你需要
这两种选择都不是很愉快。
答案 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;
对于像上面那样的情况,将一个项目指向数组之后是有意义的。但是,实际访问该项目当然没有意义 - 这将是未定义的行为。
所以上面是一个特例。但是,没有任何情况可以在数组之前指出一个项。