Ponteiro é (em termos leigos) essencialmente um valor inteiro para o endereço de memória em seu computador. É como comparar inteiros.
Kemin Zhou
5
@KeminZhou: isso é verdadeiro na maioria dos computadores atuais, mas falso em geral. Mesmo no antigo PC AT 8086 de 1980, era falso
Basile Starynkevitch
109
Para alguns fatos, aqui está o texto relevante das especificações
Operador de igualdade (==,! =)
Ponteiros para objetos do mesmo tipo podem ser comparados por igualdade com os resultados esperados 'intuitivos':
De § 5.10 do padrão C ++ 11:
Ponteiros do mesmo tipo (após conversões de ponteiro) podem ser comparados quanto à igualdade. Dois ponteiros do mesmo tipo são comparados iguais se e somente se forem nulos, ambos apontam para a mesma função ou representam o mesmo endereço ( 3.9.2 ).
(omitindo detalhes sobre a comparação de ponteiros para membros e / ou constantes de ponteiros nulos - eles continuam na mesma linha de 'Faça o que quero dizer' :)
[...] Se ambos os operandos são nulos, eles comparam iguais. Caso contrário, se apenas um for nulo, eles comparam desiguais. [...]
A advertência mais 'conspícua' tem a ver com os virtuais e também parece ser a coisa lógica a se esperar:
[...] se qualquer um deles for um ponteiro para uma função de membro virtual, o resultado não é especificado. Caso contrário, eles são comparados igual se e somente se eles se referissem ao mesmo membro do mesmo objeto mais derivado (1.8) ou ao mesmo subobjeto se eles fossem referenciados com um objeto hipotético do tipo de classe associado. [...]
Operadores relacionais (<,>, <=,> =)
De § 5.9 do padrão C ++ 11:
Ponteiros para objetos ou funções do mesmo tipo (após conversões de ponteiro) podem ser comparados, com um resultado definido da seguinte maneira:
Se dois ponteiros p e q do mesmo tipo apontam para o mesmo objeto ou função, ou ambos apontam um após o final do mesmo array, ou são ambos nulos, então p<=qe p>=qambos resultam em verdadeiro e p<qe p>qambos resultam em falso.
Se dois ponteiros p e q do mesmo tipo apontam para objetos diferentes que não são membros do mesmo objeto ou elementos do mesmo array ou para funções diferentes, ou se apenas um deles é nulo, os resultados de p<q,p>q,p<=q,e
p>=qnão são especificados .
Se dois ponteiros apontam para membros de dados não estáticos do mesmo objeto, ou para subobjetos ou elementos de matriz de tais membros, recursivamente, o ponteiro para o último membro declarado compara maior, desde que os dois membros tenham o mesmo controle de acesso (Cláusula 11) e desde que sua classe não seja um sindicato.
Se dois ponteiros apontarem para membros de dados não estáticos do mesmo objeto com controle de acesso diferente (Cláusula 11), o resultado não será especificado.
Se dois ponteiros apontarem para membros de dados não estáticos do mesmo objeto de união, eles serão comparados da mesma forma (após a conversão para void*, se necessário). Se dois ponteiros apontam para elementos da mesma matriz ou um além do final da matriz, o ponteiro para o objeto com o subscrito mais alto é comparado mais alto.
Outras comparações de ponteiro não são especificadas.
Então, se você tivesse:
int arr[3];
int *a = arr;
int *b = a + 1;
assert(a != b); // OK! well defined
Também ok:
structX {int x,y; } s;
int *a = &s.x;
int *b = &s.y;
assert(b > a); // OK! well defined
Mas depende do somethingem sua pergunta:
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
}
Bônus: o que mais há na biblioteca padrão?
§ 20.8.5 / 8 : "Para modelos greater, less, greater_equal, e less_equal, os especializações para qualquer tipo de ponteiro produzir uma ordem total, mesmo se o embutido operadores <, >, <=, >=não fazer."
Portanto, você pode solicitar globalmente qualquer item ímpar void*, desde que use std::less<>e amigos, não vazio operator<.
Hoje, o inimitável @JerryCoffin me alertou para o fato de que a biblioteca padrão possui especificações mais rigorosas para os modelos de objeto de função definidos em <functional>. Adicionado.
ver
Parece que este capítulo mudou no rascunho C ++ em andamento. A menos que eu não entenda
É um pouco mais complicado se a herança múltipla estiver envolvida.
fredoverflow
17
Resumindo. Se quisermos ver se dois ponteiros apontam para a mesma localização da memória, podemos fazer isso. Além disso, se quisermos comparar o conteúdo da memória apontado por dois ponteiros, também podemos fazer isso, apenas lembre-se de desreferenciá-los primeiro.
Código simples para verificar o alias do ponteiro:
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;
}
Resultado:
p1 and p2 alias each other
p3 and p4 donot alias each other
Comparar ponteiros não é portátil, por exemplo, no DOS, diferentes valores de ponteiro apontam para o mesmo local, a comparação dos ponteiros retorna falso.
Respostas:
Sim, essa é a definição de igualdade de ponteiro: ambos apontam para o mesmo local (ou são apelidos de ponteiro )
fonte
Para alguns fatos, aqui está o texto relevante das especificações
Operador de igualdade (==,! =)
Ponteiros para objetos do mesmo tipo podem ser comparados por igualdade com os resultados esperados 'intuitivos':
De § 5.10 do padrão C ++ 11:
Operadores relacionais (<,>, <=,> =)
De § 5.9 do padrão C ++ 11:
Então, se você tivesse:
int arr[3]; int *a = arr; int *b = a + 1; assert(a != b); // OK! well defined
Também ok:
struct X { int x,y; } s; int *a = &s.x; int *b = &s.y; assert(b > a); // OK! well defined
Mas depende do
something
em sua pergunta: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 }
Bônus: o que mais há na biblioteca padrão?
§ 20.8.5 / 8 : "Para modelos
greater
,less
,greater_equal
, eless_equal
, os especializações para qualquer tipo de ponteiro produzir uma ordem total, mesmo se o embutido operadores<
,>
,<=
,>=
não fazer."Portanto, você pode solicitar globalmente qualquer item ímpar
void*
, desde que usestd::less<>
e amigos, não vaziooperator<
.fonte
int *a = arr;
linha se beneficiaria com a inclusão de uma referência a stackoverflow.com/questions/8412694/address-of-array ? Não tenho certeza se é relevante o suficiente para a pergunta feita ...<functional>
. Adicionado.O
==
operador em ponteiros irá comparar seu endereço numérico e, portanto, determinar se eles apontam para o mesmo objeto.fonte
Resumindo. Se quisermos ver se dois ponteiros apontam para a mesma localização da memória, podemos fazer isso. Além disso, se quisermos comparar o conteúdo da memória apontado por dois ponteiros, também podemos fazer isso, apenas lembre-se de desreferenciá-los primeiro.
Se tiver-mos
int *a = something; int *b = something;
que são dois indicadores do mesmo tipo, podemos:
Compare o endereço de memória:
e compare os conteúdos:
fonte
Código simples para verificar o alias do ponteiro:
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; }
Resultado:
p1 and p2 alias each other p3 and p4 do not alias each other
fonte
Comparar ponteiros não é portátil, por exemplo, no DOS, diferentes valores de ponteiro apontam para o mesmo local, a comparação dos ponteiros retorna 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}--------------------------------------------------*/
Compile-o no Borland C 5.0, aqui está o 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}--------------------------------------------------*/
fonte