操作符 < 和 > 如何与指针一起使用?

13

仅仅是为了好玩,我有一个指向以空字符结尾的文本字符串的std::list,每个元素都是const char*类型,并在其上运行std::list::sort()。恰好,它(没有双关语)未对字符串进行排序。考虑到它正在处理指针,这是有道理的。

根据std::list::sort()文档,它(默认情况下)使用operator <来比较元素。

暂且不谈列表,我的实际问题是:在C++和C中,这些(>、<、>=、<=)操作符如何作用于指针?它们只是简单地比较实际的内存地址吗?

char* p1 = (char*) 0xDAB0BC47;
char* p2 = (char*) 0xBABEC475;

例如,在32位小端系统上,p1 > p2是因为0xDAB0BC47 > 0xBABEC475吗?
测试似乎证实了这一点,但我认为将其放在StackOverflow上以供将来参考是个好主意。C和C ++都对指针做一些奇怪的事情,所以你永远不知道......

1
是的,它们只是比较内存地址。 - user168715
4
无论是大端序还是小端序,Endiadness在这里都不重要。p1 > p2。 - edA-qa mort-ora-y
1
是的,我注意到了,但用十六进制字符编写DABOBCAT和BABECATS很有趣,所以我忽略了示例的不太好之处... - user1481860
有趣的是,<algorithm>中的所有排序算法和std::list::sort默认使用operator<(我刚刚查了一下;我本来以为它们会默认使用std::less)。 - James McNellis
3个回答

17

在C++中,你不能仅使用关系运算符比较任意指针。只能够比较指向同一数组元素或同一对象成员的两个指针。(当然,你也可以将一个指针与其自身进行比较。)

但是,你可以使用std::less和其他关系比较函数对象来比较任意两个指针。结果是实现定义的,但保证有完全的排序。

如果你有一个平坦的地址空间,指针比较通常会将地址作为整数进行比较。

(我相信在C语言中规则是相同的,没有比较函数对象,但需要有人确认;我对C不如对C++熟悉。)


4
@Zac:指针不是整数,你不能像比较整数一样比较它。 - fredoverflow
9
@FredOverflow,是的 - 这里没有任何人记得近指针和远指针吗? - Mark Ransom
2
@Zac,NULL是编译器保证的特殊情况。所有其他与整数的比较都会令人担忧。我不够了解语言法律,无法确定有多令人担忧。 - Mark Ransom
2
@Zac:这不合法,你不能将指针与整数进行比较。你的说法是错误的,指针并不一定是整数,它们是具有实现定义表示的自己的类型。 - GManNickG
4
你说:“比较两个指针总是将地址作为整数进行比较。”这是错误的。 - John Dibling
显示剩余14条评论

8

这只是一个补充说明。

C++ 20.3.3/8中提到:

对于模板greater、less、greater_equal和less_equal,即使内置的运算符<、>、<=、>=不成立,任何指针类型的特化都会产生一个全序。

C 6.5.8/5中提到:

如果两个指向对象或不完整类型的指针都指向同一对象,或都指向同一数组对象的最后一个元素之后,它们相等。如果所指的对象是同一聚合对象的成员,则稍后声明的结构成员的指针比先前声明的成员的指针大,并且具有较大下标值的数组元素的指针比具有较小下标值的相同数组的元素的指针大。所有指向同一联合对象的成员的指针都相等。如果表达式P指向数组对象的一个元素,表达式Q指向同一数组对象的最后一个元素,则指针表达式Q+1比P大。在所有其他情况下,行为未定义

因此,我认为在问题中比较属于两个不同的'\0'-终止字符串的char const*是未定义行为(在C中)。


0

是的,它们只是比较内存地址。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接