¿Cómo comparar punteros?

Supongamos que tengo 2 punteros:

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

Si quiero compararlos y ver si señalan en el mismo lugar, ¿funciona (a == b)?

Sí, esa es la definición de igualdad de puntero: ambos apuntan a la misma ubicación (o son alias de puntero )

Por un momento si los hechos aquí son el texto relevante de las especificaciones

Operador de igualdad (==,! =)

Los punteros a objetos del mismo tipo se pueden comparar por igualdad con los resultados esperados “intuitivos”:

Del § 5.10 del estándar C ++ 11:

Los punteros del mismo tipo (después de las conversiones del puntero) pueden compararse para la igualdad. Dos punteros del mismo tipo se comparan igual si y solo si son ambos nulos, ambos apuntan a la misma función, o ambos representan la misma dirección ( 3.9.2 ).

(omitiendo detalles sobre la comparación de punteros a miembro y / o las constantes de puntero nulo – continúan en la misma línea de ‘Haz lo que quiero decir’ 🙂

  • […] Si ambos operandos son nulos, se comparan iguales. De lo contrario, si solo uno es nulo, se compararán desiguales. […]

La advertencia más ‘conspicua’ tiene que ver con los virtuales, y parece ser lo lógico esperar también:

  • […] si cualquiera de ellos es un puntero a una función de miembro virtual, el resultado no está especificado. De lo contrario, comparan igual si y solo si se referirían al mismo miembro del mismo objeto más derivado (1.8) o al mismo subobjeto si se desreferenciaran con un objeto hipotético del tipo de clase asociado. […]

Operadores relacionales (< ,>, < =,> =)

Del § 5.9 del estándar C ++ 11:

Se pueden comparar punteros a objetos o funciones del mismo tipo (después de las conversiones de puntero), con un resultado definido de la siguiente manera:

  1. Si dos punteros p y q del mismo tipo apuntan al mismo objeto o función, o ambos señalan uno pasado el final de la misma matriz, o ambos son nulos, entonces p< =q y p>=q ambos dan verdadero y p y p>q ambos dan falso.
  2. Si dos punteros p y q del mismo tipo apuntan a diferentes objetos que no son miembros del mismo objeto o elementos de la misma matriz o a diferentes funciones, o si solo uno de ellos es nulo, los resultados de p p>q, p< =q, y p>=q no están especificados .
  3. Si dos punteros apuntan a miembros de datos no estáticos del mismo objeto, o a subobjetos o elementos de matriz de dichos miembros, de forma recursiva, el puntero al miembro declarado posterior se compara mayor siempre que los dos miembros tengan el mismo control de acceso (cláusula 11) y siempre que su clase no sea una unión.
  4. Si dos punteros apuntan a los miembros de datos no estáticos del mismo objeto con diferente control de acceso (Cláusula 11), el resultado no se especifica.
  5. Si dos punteros apuntan a los miembros de datos no estáticos del mismo objeto de unión, se comparan iguales (después de la conversión a void* , si es necesario). Si dos punteros apuntan a elementos de la misma matriz o uno más allá del final de la matriz, el puntero al objeto con el subíndice superior se compara más alto.
  6. Otras comparaciones de punteros no están especificadas.

Entonces, si tuvieras:

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

También está bien:

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

Pero depende de something en tu pregunta:

 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 } 

Bonificación: ¿qué más hay en la biblioteca estándar?

§ 20.8.5 / 8 : "Para las plantillas greater , less , greater_equal y less_equal , las especializaciones para cualquier tipo de puntero producen un orden total, incluso si los operadores integrados < , > , < = , >= no lo hacen".

Por lo tanto, puede ordenar globalmente cualquier void* siempre que use std::less<> y amigos, no operator< desnudo operator< .

El operador == en punteros comparará su dirección numérica y, por lo tanto, determinará si apuntan al mismo objeto.

Para resumir. Si queremos ver si dos punteros apuntan a la misma ubicación de memoria, podemos hacer eso. Además, si queremos comparar el contenido de la memoria apuntada por dos punteros, podemos hacerlo también, solo recordar para desreferenciarlos primero.

Si tenemos

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

que son dos punteros del mismo tipo que podemos:

Comparar la dirección de memoria:

 a==b 

y comparar contenidos:

 *a==*b 

Digamos que tienes que apuntar:

 int *a = something1; int *b = something2; 

Usted sabe la dirección de algo1 que es & algo1. También la dirección de algo2 es & algo2.

Entonces, lo que tienes que hacer es verificar si las dos direcciones a las que apuntan los punteros son correctas.

entonces usas algo como

 if(&something1 == &something2) { //do something } 

o puede usar el operador == para verificar si el puntero a tiene el mismo valor con el puntero b.