关于指针比较,标准中的措辞比较奇怪

时间:2013-05-14 13:33:03

标签: c pointers language-lawyer c11

§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。

我缺少什么?

1 个答案:

答案 0 :(得分:1)

首先,你引用了段落的一部分,第一部分解释了这个引用的内容,我在这里包含了段落:

  

当比较两个指针时,结果取决于中的相对位置   指向的对象的地址空间。如果两个指向对象类型的指针都指向   相同的对象,或两者都指向同一个数组对象的最后一个元素,它们   比较平等。如果指向的对象是同一聚合对象的成员,   稍后声明的结构成员的指针比指向成员的指针要大   在结构中先前声明,并指向具有较大下标的数组元素   值比具有较低下标值的同一数组的元素的指针大。指向同一个union对象的成员的所有指针都比较相等。如果   表达式P指向数组对象的元素,表达式Q指向同一数组对象的最后一个元素,指针表达式Q + 1比较大于P.在所有其他情况下,行为未定义。

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

这在一个程序中非常有用,在该程序中,您递增一个指针,然后检查它是否超过了数组的末尾,如果是,则终止。例如。

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

即使在foo指向超出数组末尾的最后一种情况下也是合法的。

请注意,此示例非常有用,但证明了这一点。

如果不符合此规则,则此程序将是未定义的行为。