El puntero es (en términos simples) esencialmente un valor entero para la dirección de memoria en su computadora. Es como comparar enteros.
Kemin Zhou
5
@KeminZhou: esto es cierto en la mayoría de las computadoras actuales, pero falso en general. Incluso en el antiguo PC AT 8086 de 1980 era falso
Basile Starynkevitch
109
Para algunos hechos, aquí está 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 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. [...]
Operadores relacionales (<,>, <=,> =)
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<=qy p>=qambos dan como resultado verdadero p<qy p>qambos 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,y
p>=qno 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:
structX {int x,y; } s;
int *a = &s.x;
int *b = &s.y;
assert(b > a); // OK! well defined
Pero depende del somethingen su pregunta:
int g;
intmain(){
int h;
int i;
int *a = &g;
int *b = &h; // can't compare a <=> bint *c = &i; // can't compare b <=> c, or a <=> c etc.// but a==b, b!=c, a!=c etc. are supported just fine
}
Bono: ¿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 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<.
¿Se 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 ...
sin sentido
Hoy, el inimitable @JerryCoffin me hizo consciente del hecho de que la biblioteca estándar tiene especificaciones más estrictas para las plantillas de objetos de función definidas en <functional>. Adicional.
Es un poco más complicado si se trata de una herencia múltiple.
fredoverflow
17
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.
Código simple para verificar el alias del puntero:
intmain(){
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;
}
return0;
}
Salida:
p1 and p2 alias each other
p3 and p4 donot 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.
Respuestas:
Sí, esa es la definición de igualdad de puntero: ambos apuntan a la misma ubicación (o son alias de puntero )
fuente
Para algunos hechos, aquí está 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:
Operadores relacionales (<,>, <=,> =)
Del § 5.9 del estándar C ++ 11:
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 }
Bono: ¿qué más hay en la biblioteca estándar?
§ 20.8.5 / 8 : "Para las plantillas
greater
,less
,greater_equal
, yless_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 usestd::less<>
y amigos, no solooperator<
.fuente
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.fuente
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:
y comparar contenidos:
fuente
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
fuente
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}--------------------------------------------------*/
fuente