如何比较指针?
假设我有两个指针:
int *a = something; int *b = something;
如果我想比较它们,看看它们是否指向相同的地方(a == b)是否工作?
是的,这是指针相等的定义:它们都指向相同的位置(或者是指针别名 )
如果这里的事实是规范中的相关文本,那么有一点点
平等运算符(==,!=)
指向相同types的对象的指针可以与“直观的”预期结果进行比较:
从C ++ 11标准的§5.10开始 :
相同types的指针(在指针转换后)可以进行比较以获得相等的结果。 相同types的两个指针比较相等的当且仅当它们都是空的,都指向相同的函数,或者两者都代表相同的地址( 3.9.2 )。
(省略指向成员和空指针常量的比较细节 – 它们继续沿着“做我的意思”的同一行:)
- […]如果两个操作数都为空,则它们相等。 否则,如果只有一个是空的,他们比较不等于[…]
最显而易见的警告与虚拟有关,似乎也是合乎逻辑的事情:
- 如果其中一个是指向虚拟成员函数的指针,则结果是未指定的。 否则,它们比较等于当且仅当它们将引用同一最大派生对象(1.8)的相同成员,或者如果它们与相关类types的假设对象解引用相同的子对象。 […]
关系运算符(<,>,<=,> =)
从C ++ 11标准的§5.9开始:
可以比较指向同一types(指针转换后)的对象或函数的指针,结果定义如下:
- 如果相同types的两个指针p和q指向相同的对象或函数,或者两者都指向同一个数组的末尾,或者都是null,则
p<=q
和p>=q
都产生true,p<q
和p>q
都产生错误。- 如果相同types的两个指针p和q指向不是同一对象或同一数组的元素或不同对象的成员的不同对象,或者只有其中一个为空,则
p<q,
p>q,
p<=q,
p>=q
未指定 。- 如果两个指针指向同一对象的非静态数据成员,或者指向这些成员的子对象或数组元素,recursion地,指向稍后声明的成员的指针比较大,只要两个成员具有相同的访问控制(第11章);只要他们的class级不是工会。
- 如果两个指针指向具有不同访问控制的同一对象的非静态数据成员(第11章),则结果是未指定的。
- 如果两个指针指向相同联合对象的非静态数据成员,则它们相等(如果需要,转换为
void*
之后)。 如果两个指针指向同一个数组的元素或超出数组末尾的指针,则指向具有较高下标的对象的指针比较高。- 其他指针比较是未指定的。
所以,如果你有:
int arr[3]; int *a = arr; int *b = a + 1; assert(a != b); // OK! well defined
还行:
struct X { int x,y; } s; int *a = &s.x; int *b = &s.y; assert(b > a); // OK! well defined
但是这取决于你的问题:
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 }
奖金:标准库还有什么?
§20.8.5 / 8 :“对于greater
, less
, greater
less
和less
模板,即使内置运算符<
, >
, <=
, >=
不包含任何指针types的特化,也会产生全部顺序。
所以,只要你使用std::less<>
和朋友,而不是纯粹的operator<
,那么你可以在全球范围内订购任何奇怪的void*
。
指针上的==
运算符将比较它们的数字地址,从而确定它们是否指向相同的对象。
总结一下。 如果我们想看看两个指针是否指向相同的内存位置,我们可以做到这一点。 另外,如果我们想要比较两个指针指向的内存的内容,我们也可以这样做,只要记住先取消引用它们。
如果我们有
int *a = something; int *b = something;
这是同一types的两个指针,我们可以:
比较内存地址:
a==b
并比较内容:
*a==*b
让我们说你必须指出:
int *a = something1; int *b = something2;
你知道东西1的地址是&something1。 另外东西2的地址是&东西2。
所以你要做的是检查指针指向的两个地址是否正确。
所以你使用类似的东西
if(&something1 == &something2) { //do something }
或者您可以使用==运算符来检查指针a是否与指针b具有相同的值。