Supongamos que tengo 2 punteros:
int *a = something;
int *b = something;
Si quiero compararlos y ver si apuntan al mismo lugar, ¿funciona (a == b)?
Supongamos que tengo 2 punteros:
int *a = something;
int *b = something;
Si quiero compararlos y ver si apuntan al mismo lugar, ¿funciona (a == b)?
Respuestas:
Sí, esa es la definición de igualdad de puntero: ambos apuntan a la misma ubicación (o son alias de puntero )
Para algunos hechos, aquí está el texto relevante de las especificaciones.
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 de punteros) se pueden comparar para determinar la igualdad. Dos punteros del mismo tipo se comparan igual si y solo si ambos son nulos, ambos apuntan a la misma función o ambos representan la misma dirección ( 3.9.2 ).
(dejando de lado los detalles sobre la comparación de punteros al miembro yo las constantes de puntero nulo; continúan en la misma línea de 'Do What I Mean' :)
- [...] Si ambos operandos son nulos, se comparan igual. De lo contrario, si solo uno es nulo, se comparan desiguales. [...]
La advertencia más 'conspicua' tiene que ver con los virtuales, y también parece ser lo lógico:
- [...] si alguno es un puntero a una función miembro virtual, el resultado no está especificado. De lo contrario, se 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 fueran desreferenciados con un objeto hipotético del tipo de clase asociado. [...]
Del § 5.9 del estándar C ++ 11:
Los punteros a objetos o funciones del mismo tipo (después de las conversiones de punteros) se pueden comparar, con un resultado definido de la siguiente manera:
- Si dos punteros pyq del mismo tipo apuntan al mismo objeto o función, o ambos apuntan uno más allá del final de la misma matriz, o ambos son nulos, entonces
p<=q
yp>=q
ambos dan como resultado verdaderop<q
yp>q
ambos dan como resultado falso.- Si dos punteros pyq del mismo tipo apuntan a diferentes objetos que no son miembros del mismo objeto o elementos de la misma matriz o funciones diferentes, o si solo uno de ellos es nulo, los resultados de
p<q,
p>q,
p<=q,
yp>=q
no están especificados .- 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 más tarde se compara mayor siempre que los dos miembros tengan el mismo control de acceso (Cláusula 11) y siempre que su clase no sea un sindicato.
- Si dos punteros apuntan a miembros de datos no estáticos del mismo objeto con diferente control de acceso (cláusula 11), el resultado no se especifica.
- Si dos punteros apuntan a miembros de datos no estáticos del mismo objeto de unión, se comparan igual (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 más alto compara más alto.- 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 del something
en su 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
}
§ 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 el incorporado en los operadores <
, >
, <=
, >=
no lo hacen."
Por lo tanto, puede ordenar globalmente cualquier impar void*
siempre que use std::less<>
y amigos, no solo operator<
.
int *a = arr;
beneficiaría la línea de incluir una referencia a stackoverflow.com/questions/8412694/address-of-array ? Sin embargo, no estoy seguro de si es lo suficientemente relevante para la pregunta formulada ...
<functional>
. Adicional.
El ==
operador de 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 hacerlo. Además, si queremos comparar el contenido de la memoria apuntada por dos punteros, también podemos hacerlo, solo recuerde desreferenciarlos primero.
Si tenemos
int *a = something;
int *b = something;
que son dos punteros del mismo tipo podemos:
Comparar dirección de memoria:
a==b
y comparar contenidos:
*a==*b
Código simple para verificar el alias del puntero:
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;
}
Salida:
p1 and p2 alias each other
p3 and p4 do not alias each other
Comparar punteros no es portátil, por ejemplo, en DOS, diferentes valores de puntero apuntan a la misma ubicación, la comparación de punteros devuelve falso.
/*--{++:main.c}--------------------------------------------------*/
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int val_a = 123;
int * ptr_0 = &val_a;
int * ptr_1 = MK_FP(FP_SEG(&val_a) + 1, FP_OFF(&val_a) - 16);
printf(" val_a = %d -> @%p\n", val_a, (void *)(&val_a));
printf("*ptr_0 = %d -> @%p\n", *ptr_0, (void *)ptr_0);
printf("*ptr_1 = %d -> @%p\n", *ptr_1, (void *)ptr_1);
/* Check what returns the pointers comparison: */
printf("&val_a == ptr_0 ====> %d\n", &val_a == ptr_0);
printf("&val_a == ptr_1 ====> %d\n", &val_a == ptr_1);
printf(" ptr_0 == ptr_1 ====> %d\n", ptr_0 == ptr_1);
printf("val_a = %d\n", val_a);
printf(">> *ptr_0 += 100;\n");
*ptr_0 += 100;
printf("val_a = %d\n", val_a);
printf(">> *ptr_1 += 500;\n");
*ptr_1 += 500;
printf("val_a = %d\n", val_a);
return EXIT_SUCCESS;
}
/*--{--:main.c}--------------------------------------------------*/
Compílelo bajo Borland C 5.0, aquí está el resultado:
/*--{++:result}--------------------------------------------------*/
val_a = 123 -> @167A:0FFE
*ptr_0 = 123 -> @167A:0FFE
*ptr_1 = 123 -> @167B:0FEE
&val_a == ptr_0 ====> 1
&val_a == ptr_1 ====> 0
ptr_0 == ptr_1 ====> 0
val_a = 123
>> *ptr_0 += 100;
val_a = 223
>> *ptr_1 += 500;
val_a = 723
/*--{--:result}--------------------------------------------------*/