5

§6.5.8\6(关于 >、<、<=、>=)

如果表达式 P 指向数组对象的一个​​元素,而表达式 Q 指向同一数组对象的最后一个元素,则指针表达式 Q+1 比较大于 P 。在所有其他情况下,行为是未定义的。

上面的几个部分,第 6.5.8 节,解释了基本上,指针算术在数组上按预期工作。那int a[3]; int *p = a; int *q = &a[2]; //q-p == 3是有效的。但是,正如我所读到的,上面q > p是UB。

我错过了什么?

4

1 回答 1

1

首先,您引用了一段段落的一部分,第一部分解释了这是引用的内容,我在此处包括该段落:

比较两个指针时,结果取决于所指向对象在地址空间中的相对位置。如果指向对象类型的两个指针都指向同一个对象,或者都指向同一个数组对象的最后一个元素,它们比较相等。如果指向的对象是同一个聚合对象的成员,则指向稍后声明的结构成员的指针比较大于指向结构中较早声明的成员的指针,并且指向具有较大下标值的数组元素的指针比较大于指向同一数组的元素的指针具有较低的下标值。所有指向同一个联合对象成员的指针比较相等。如果表达式 P 指向一个数组对象的一个​​元素,而表达式 Q 指向同一个数组对象的最后一个元素,

基本上,您引用的位是指这样一个事实,即通常指针必须始终指向独立对象、对象数组的元素或对象数组末尾的元素。正如你所看到的,通常递增一个已经指向数组最后一个元素的指针会产生一个无效的指针,而且实际上标准中的这个指针绝对不能被取消引用,但是它可以用于一种特殊情况,那就是它可以设置或与另一个指针进行比较。

这在您增加一个指针然后检查它是否超过数组末尾并如果超过则终止的程序中很有用。例如。

int foo = 0;
int ArrSize = 6;
int bar[ArrSize];
while(foo < ArrSize)
{
    foo++;
    printf("%d", bar + 3 < bar + foo);
}

将是合法的,即使在 foo 指向数组末尾之外的最后一种情况下也是如此。

请注意,此示例非常做作,但说明了这一点。

如果没有这条规则,这个程序将是未定义的行为。

于 2014-08-19T10:57:07.623 回答