1
char** buffer{ /* some buffer */ };
char* ptr1{buffer[0]};
char* ptr2{buffer[10]};

assert(ptr1 < ptr2);

如果两个指针指向同一个缓冲区中的不同位置,比较它们是否安全?

我想通过比较来知道一系列指针是否有效:assert(rangeBeginPtr < rangeEndPtr)

4

3 回答 3

4

您可以将指针与关系运算符(<、和)进行比较>,前提是它们都指向同一数组的元素,或者指向该数组的元素。根据 C++11 ,其他任何行为都是未指定的行为。所以,给定:<=>=5.9 Relational operators

char xyzzy[10];
char plugh[10];

所有这些都指定为正常运行:

assert(&(xyzzy[1]) < &(xyzzy[4]));
assert(&(xyzzy[9]) < &(xyzzy[10])); // even though [10] isn't there.

但这些不是:

assert(&(xyzzy[1]) < &(xyzzy[15]));
assert(&(xyzzy[9]) < &(plugh[3]));

类型不会出现在其中,除非如果您要比较同一数组中的两个元素,它必须是相同的类型。如果您有两个变量,即使它们具有相同的类型,它们char *是否指向不同的数组也是未指定的。

于 2013-08-26T12:52:31.067 回答
3

您只能使用 on 数组对象确定指针的顺序,如果它们是非void. 但是,在一个数组对象中,比较是明确定义的。标准中的相关条款是 5.9 [expr.rel] 第 2 段:

[...] 可以比较指向相同类型的对象或函数的指针(在指针转换之后),其结果定义如下:

  • 如果两个相同类型的指针指向pq一个对象或函数,或者都指向同一个数组末尾的后一个,或者都为空,则p<=qandp>=q都 yieldtruep<qandp>q都 yield false
  • 如果两个相同类型的指针指向不同的对象pq这些对象不是同一对象的成员或同一数组的元素或不同的函数,或者如果其中只有一个为空,则 、 、 和 的p<q结果p>qp<=q指定p>=q
  • 如果两个指针指向同一个对象的非静态数据成员,或者这些成员的子对象或数组元素,递归地,如果两个成员具有相同的访问控制(第 11 条)和前提是他们的班级不是工会。
  • 如果两个指针指向具有不同访问控制(第 11 条)的同一对象的非静态数据成员,则结果未指定。
  • 如果两个指针指向同一个联合对象的非静态数据成员,它们比较相等(void*如果需要,在转换为 之后)。如果两个指针指向同一个数组的元素或一个超出数组末尾的元素,则指向具有较高下标的对象的指针比较高。
  • 其他指针比较未指定。
于 2013-08-26T12:59:11.220 回答
2

==并且!=对于相同类型的所有指针都是有效且定义明确的。<, <=, >, 和>=仅对指向同一数组中的对象或数组末尾的指针有意义。如果子对象具有相同的类型和相同的访问说明符,它们对于指向类对象的子对象的指针也是有意义的。如果不满足这些条件,则结果未指定;一个直接的结果是,a<b并不b<c意味着,所以你不能使用等等作为排序函数的比较器。a<c<

std::less, std::less_equal, std::greater, 和std::greater_equal指针类型都定义了一个总排序;它们可用于排序。

于 2013-08-26T13:55:51.490 回答