Supposons que j'ai 2 pointeurs:
int *a = something;
int *b = something;
Si je veux les comparer et voir si elles pointent au même endroit, est-ce que (a == b) fonctionne?
Supposons que j'ai 2 pointeurs:
int *a = something;
int *b = something;
Si je veux les comparer et voir si elles pointent au même endroit, est-ce que (a == b) fonctionne?
Réponses:
Oui, c'est la définition de l'égalité des pointeurs: ils pointent tous les deux vers le même emplacement (ou sont des alias de pointeur )
Pour un peu de faits, voici le texte pertinent du cahier des charges
Les pointeurs vers des objets du même type peuvent être comparés pour l'égalité avec les résultats attendus `` intuitifs '':
À partir du § 5.10 de la norme C ++ 11:
Les pointeurs du même type (après les conversions de pointeurs) peuvent être comparés pour l'égalité. Deux pointeurs du même type se comparent égaux si et seulement s'ils sont tous deux nuls, tous deux pointent vers la même fonction, ou les deux représentent la même adresse ( 3.9.2 ).
(en laissant de côté les détails sur la comparaison des pointeurs vers le membre et / ou les constantes du pointeur nul - ils continuent sur la même ligne de 'Do What I Mean' :)
- [...] Si les deux opérandes sont nuls, ils se comparent égaux. Sinon, si un seul est nul, ils comparent des inégalités. [...]
La mise en garde la plus `` visible '' concerne les virtuels, et cela semble être la chose logique à laquelle il faut également s'attendre:
- [...] si l'un ou l'autre est un pointeur vers une fonction membre virtuelle, le résultat n'est pas spécifié. Sinon, ils se comparent égaux si et seulement s'ils font référence au même membre du même objet le plus dérivé (1.8) ou au même sous-objet s'ils ont été déréférencés avec un objet hypothétique du type de classe associé. [...]
À partir du § 5.9 de la norme C ++ 11:
Les pointeurs vers des objets ou des fonctions du même type (après conversions de pointeurs) peuvent être comparés, avec un résultat défini comme suit:
- Si deux pointeurs p et q du même type pointent vers le même objet ou la même fonction, ou tous les deux pointent un après la fin du même tableau, ou sont tous les deux nuls, alors
p<=q
etp>=q
tous deux donnent vrai etp<q
etp>q
tous deux donnent faux.- Si deux pointeurs p et q du même type pointent vers des objets différents qui ne sont pas membres du même objet ou des éléments du même tableau ou vers des fonctions différentes, ou si un seul d'entre eux est nul, les résultats de
p<q,
p>q,
p<=q,
et nep>=q
sont pas spécifiés .- Si deux pointeurs pointent vers des membres de données non statiques du même objet, ou vers des sous-objets ou des éléments de tableau de ces membres, de manière récursive, le pointeur vers le membre déclaré plus tard est supérieur à condition que les deux membres aient le même contrôle d'accès (Article 11) et à condition que leur classe ne soit pas un syndicat.
- Si deux pointeurs pointent vers des membres de données non statiques du même objet avec un contrôle d'accès différent (Article 11), le résultat n'est pas spécifié.
- Si deux pointeurs pointent vers des membres de données non statiques du même objet union, ils se comparent égaux (après conversion en
void*
, si nécessaire). Si deux pointeurs pointent vers des éléments du même tableau ou un au-delà de la fin du tableau, le pointeur vers l'objet avec l'indice le plus élevé se compare plus haut.- Les autres comparaisons de pointeurs ne sont pas spécifiées.
Donc, si vous aviez:
int arr[3];
int *a = arr;
int *b = a + 1;
assert(a != b); // OK! well defined
Aussi correct:
struct X { int x,y; } s;
int *a = &s.x;
int *b = &s.y;
assert(b > a); // OK! well defined
Mais cela dépend de la something
question dans votre question:
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 : « Pour les modèles greater
, less
, greater_equal
et less_equal
, les spécialisations pour tout type de pointeur donnent un ordre total, même si le haut-opérateurs <
, >
, <=
, >=
ne le font pas. »
Ainsi, vous pouvez commander globalement n'importe quel impair void*
tant que vous utilisez std::less<>
et amis, pas nu operator<
.
int *a = arr;
ligne gagnerait-elle à inclure une référence à stackoverflow.com/questions/8412694/address-of-array ? Je ne sais pas si cela est suffisamment pertinent par rapport à la question posée ...
<functional>
. Ajoutée.
L' ==
opérateur sur les pointeurs comparera leur adresse numérique et déterminera donc s'ils pointent vers le même objet.
Pour résumer. Si nous voulons voir si deux pointeurs pointent vers le même emplacement mémoire, nous pouvons le faire. Aussi, si nous voulons comparer le contenu de la mémoire pointé par deux pointeurs, nous pouvons le faire aussi, n'oubliez pas de les déréférencer en premier.
Si nous avons
int *a = something;
int *b = something;
qui sont deux pointeurs du même type, nous pouvons:
Comparer l'adresse mémoire:
a==b
et comparez les contenus:
*a==*b
Code simple pour vérifier l'alias du pointeur:
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;
}
Production:
p1 and p2 alias each other
p3 and p4 do not alias each other
La comparaison des pointeurs n'est pas portable, par exemple sous DOS différentes valeurs de pointeur pointent vers le même emplacement, la comparaison des pointeurs renvoie false.
/*--{++: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}--------------------------------------------------*/
Compilez-le sous Borland C 5.0, voici le résultat:
/*--{++: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}--------------------------------------------------*/