C++ 如何比较指针?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9086372/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:16:36  来源:igfitidea点击:

How to compare pointers?

c++pointers

提问by Joey Franklin

Suppose I have 2 pointers:

假设我有两个指针:

int *a = something;
int *b = something;

If I want to compare them and see if they point at the same place does (a == b) work?

如果我想比较它们并查看它们是否指向同一个地方 (a == b) 有效吗?

采纳答案by Basile Starynkevitch

Yes, that is the definition of pointer equality: they both point to the same location (or are pointer aliases)

是的,这就是指针相等的定义:它们都指向同一个位置(或者是指针别名

回答by sehe

For a bit of factshere is the relevant text from the specifications

对于一些事实,这里是规范中的相关文本

Equality operator (==,!=)

等号运算符 (==,!=)

Pointers to objects of the same type can be compared for equality with the 'intuitive' expected results:

可以将指向相同类型对象的指针与“直观”预期结果进行比较:

From § 5.10of the C++11 standard:

来自 C++11 标准的第 5.10 节

Pointers of the same type (after pointer conversions) can be compared for equality. Two pointers of the same type compare equal if and only if they are both null, both point to the same function, or both represent the same address (3.9.2).

(leaving out details on comparison of pointers to member and or the null pointer constants - they continue down the same line of 'Do What I Mean':)

  • [...] If both operands are null, they compare equal. Otherwise if only one is null, they compare unequal.[...]

The most 'conspicuous' caveat has to do with virtuals, and it does seem to be the logical thing to expect too:

  • [...] if either is a pointer to a virtual member function, the result is unspecified. Otherwise they compare equal if and only if they would refer to the same member of the same most derived object (1.8) or the same subobject if they were dereferenced with a hypothetical object of the associated class type. [...]

可以比较相同类型的指针(指针转换后)是否相等。两个相同类型的指针比较相等当且仅当它们都为空,都指向同一个函数,或者都表示相同的地址(3.9.2)。

(省略了关于成员指针和/或空指针常量的比较的详细信息——它们继续沿着“按我的意思做”的同一行:)

  • [...] 如果两个操作数都为空,则它们比较相等。否则,如果只有一个为空,则它们比较不相等。[...]

最“显眼”的警告与虚拟有关,而且它似乎也是合乎逻辑的期望:

  • [...] 如果其中一个是指向虚成员函数的指针,则结果未指定。否则,当且仅当它们引用同一最派生对象 (1.8) 的同一成员或同一子对象(如果它们被关联类类型的假设对象取消引用)时,它们才比较相等。[...]

Relational operators (<,>,<=,>=)

关系运算符 (<,>,<=,>=)

From § 5.9of the C++11 standard:

来自C++11 标准的第 5.9 节

Pointers to objects or functions of the same type (after pointer conversions) can be compared, with a result defined as follows:

  1. If two pointers p and q of the same type point to the same object or function, or both point one past the end of the same array, or are both null, then p<=qand p>=qboth yield true and p<qand p>qboth yield false.
  2. If two pointers p and q of the same type point to different objects that are not members of the same object or elements of the same arrayor to different functions, or if only one of them is null, the results of p<q,p>q,p<=q,and p>=qare unspecified.
  3. If two pointers point to non-static data members of the same object, or to subobjects or array elements of such members, recursively, the pointer to the later declared member compares greater provided the two members have the same access control (Clause 11) and provided their class is not a union.
  4. If two pointers point to non-static data members of the same object with different access control (Clause 11) the result is unspecified.
  5. If two pointers point to non-static data members of the same union object, they compare equal (after conversion to void*, if necessary). If two pointers point to elements of the same array or one beyond the end of the array, the pointer to the object with the higher subscript compares higher.
  6. Other pointer comparisons are unspecified.

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

  1. 如果相同类型的两个指针 p 和 q 指向同一个对象或函数,或者都指向同一个数组的末尾,或者都为空,则p<=qp>=q都产生真,p<q并且p>q都产生假。
  2. 如果两个相同类型的指针 p 和 q 指向不同的对象,这些对象不是同一对象的成员或同一数组的元素或不同的函数,或者如果其中只有一个为空,则p<q,p>q,p<=q,和 的结果p>=q是未指定的
  3. 如果两个指针指向同一对象的非静态数据成员,或者指向这些成员的子对象或数组元素,递归地,如果两个成员具有相同的访问控制(第 11 条)和前提是他们的班级不是工会。
  4. 如果两个指针指向具有不同访问控制(第 11 条)的同一对象的非静态数据成员,则结果未指定。
  5. 如果两个指针指向同一个联合对象的非静态数据成员,它们比较相等(转换为 后void*,如有必要)。如果两个指针指向同一数组的元素或一个超出数组末尾,则指向具有较高下标的对象的指针比较高。
  6. 其他指针比较未指定。

So, if you had:

所以,如果你有:

int arr[3];
int *a = arr;
int *b = a + 1;
assert(a != b); // OK! well defined

Also OK:

也可以:

struct X { int x,y; } s;
int *a = &s.x;
int *b = &s.y;
assert(b > a); // OK! well defined

But it depends on the somethingin your question:

但这取决于something您的问题:

int g; 
int main()
{
     int h;
     int i;

     int *a = &g;
     int *b = &h; // can't compare a <=> b
     int *c = &i; // can't compare b <=> c, or a <=> c etc.
     // but a==b, b!=c, a!=c etc. are supported just fine
}

Bonus: what else is there in the standard library?

奖励:标准库中还有什么?

§ 20.8.5/8: "For templates greater, less, greater_equal, and less_equal, the specializations for any pointer type yield a total order, even if the built-in operators <, >, <=, >=do not."

第 20.8.5/8 节:“对于模板greaterlessgreater_equalless_equal,任何指针类型的特化都会产生全序,即使内置运算符<><=>=没有。”

So, you can globally orderany odd void*as long as you use std::less<>and friends, not bare operator<.

所以,只要你和朋友一起使用,你就可以全局订购任何奇怪的东西,而不是裸。void*std::less<>operator<

回答by JaredPar

The ==operator on pointers will compare their numeric address and hence determine if they point to the same object.

==指针上的操作会比较他们的数字地址,从而确定它们是否指向同一个对象。

回答by ldgorman

To sum up. If we want to see if two pointers point to the same memory location we can do that. Also if we want to compare the contents of the memory pointed to by two pointers we can do that too, just remeber to dereference them first.

总结。如果我们想查看两个指针是否指向同一个内存位置,我们可以这样做。此外,如果我们想比较两个指针指向的内存的内容,我们也可以这样做,只需记住先取消引用它们。

If we have

如果我们有

int *a = something; 
int *b = something;

which are two pointers of the same type we can:

这是两个相同类型的指针,我们可以:

Compare memory address:

比较内存地址:

a==b

and compare contents:

并比较内容:

*a==*b

回答by Pankaj Kumar Thapa

Simple code to check pointer aliasing:

检查指针别名的简单代码:

int main () {
    int a = 10, b = 20;
    int *p1, *p2, *p3, *p4;

    p1 = &a;
    p2 = &a;
    if(p1 == p2){
        std::cout<<"p1 and p2 alias each other"<<std::endl;
    }
    else{
        std::cout<<"p1 and p2 do not alias each other"<<std::endl;
    }
    //------------------------
    p3 = &a;
    p4 = &b;
    if(p3 == p4){
        std::cout<<"p3 and p4 alias each other"<<std::endl;
    }
    else{
        std::cout<<"p3 and p4 do not alias each other"<<std::endl;
    }
    return 0;
}

Output:

输出:

p1 and p2 alias each other
p3 and p4 do not alias each other