如何比较指针?

Joe*_*lin 72 c++ pointers

假设我有两个指针:

int *a = something;
int *b = something;
Run Code Online (Sandbox Code Playgroud)

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

seh*_*ehe 95

这里有一些事实是规范中的相关文字

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

可以比较相同类型对象的指针与"直观"预期结果的相等性:

从 C++ 11标准的第5.10节开始:

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

(省略有关成员指针和空指针常量的比较的详细信息 - 它们继续沿着'Do What I Mean'的同一行继续:)

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

最"引人注目"的警告与虚拟有关,它似乎也是合乎逻辑的预期:

  • [...]如果其中一个是指向虚拟成员函数的指针,则结果未指定.否则,只有当它们与相关类类型的假设对象取消引用时,它们才会引用相同的最大派生对象(1.8)的相同成员或相同的子对象,它们才会进行比较.[...]

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

从C++ 11标准的第5.9节开始:

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

  1. 如果两个指针p和相同类型的指向相同的对象或功能或两者点一个过去的同一阵列的末端,的q或均为空,则p<=qp>=q两个产量真实p<qp>q二者产生错误.
  2. 如果相同类型的两个指针p和q指向不是同一对象的成员或相同数组的元素或不同函数的不同对象,或者如果它们中只有一个为null,则结果p<q, p>q, p<=q,p>=q 未指定.
  3. 如果两个指针指向同一对象的非静态数据成员,或者指向这些成员的子对象或数组元素,则递归地指向稍后声明的成员的指针比较更大,前提是两个成员具有相同的访问控制(第11条)和如果他们的班级不是工会.
  4. 如果两个指针指向具有不同访问控制的同一对象的非静态数据成员(第11条),则结果未指定.
  5. 如果两个指针指向同一个union对象的非静态数据成员,则它们比较相等(转换后void*,如果需要).如果两个指针指向同一数组的元素或超出数组末尾的指针,则指向具有较高下标的对象的指针会比较高.
  6. 其他指针比较未指定.

所以,如果你有:

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

还行:

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

但这取决于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
}
Run Code Online (Sandbox Code Playgroud)

额外奖励:标准库还有什么?

§20.8.5/8:"对于模板greater,less,greater_equal,和less_equal,对于任何指针类型的专业化产生总订单,即使内置的运营商<,>,<=,>=没有."

所以,只要你使用和朋友,你可以在全球范围内订购任何奇数,而不是裸.void*std::less<>operator<


Bas*_*tch 60

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

  • @KeminZhou:在大多数当前的计算机上都是如此,但总的来说是假的.即使在1980年的PC PC 8086上也是如此 (4认同)
  • 指针(通俗地说)本质上是计算机内存地址的整数值。这就像比较整数。 (2认同)

Jar*_*Par 20

==指针上的运算符将比较它们的数字地址,从而确定它们是否指向同一个对象.

  • 如果涉及多重继承,则会更复杂一些. (11认同)

ldg*_*man 14

总结一下.如果我们想看看两个指针是否指向相同的内存位置,我们可以做到这一点.另外,如果我们想要比较两个指针所指向的内存的内容,我们也可以这样做,只需记住首先取消引用它们.

如果我们有

int *a = something; 
int *b = something;
Run Code Online (Sandbox Code Playgroud)

我们可以使用相同类型的两个指针:

比较内存地址:

a==b
Run Code Online (Sandbox Code Playgroud)

并比较内容:

*a==*b
Run Code Online (Sandbox Code Playgroud)