Prérequis: Pointeurs , Les références
C et C++ prennent en charge les pointeurs, ce qui est différent de la plupart des autres langages de programmation tels que Java, Python, Ruby, Perl et PHP car ils ne prennent en charge que les références. Mais il est intéressant de noter que C++, ainsi que les pointeurs, prend également en charge les références.
En apparence, les références et les pointeurs sont très similaires car les deux sont utilisés pour qu'une variable donne accès à une autre. Les deux offrant les mêmes capacités, il est souvent difficile de savoir ce qui diffère entre ces mécanismes. Dans cet article, je vais essayer d'illustrer les différences entre les pointeurs et les références.
Pointeurs : Un pointeur est une variable qui contient l’adresse mémoire d’une autre variable. Un pointeur doit être déréférencé avec le * opérateur pour accéder à l’emplacement mémoire vers lequel il pointe.
Les références : Une variable de référence est un alias, c'est-à-dire un autre nom pour une variable déjà existante. Une référence, comme un pointeur, est également implémentée en stockant l'adresse d'un objet.
Une référence peut être considérée comme un pointeur constant (à ne pas confondre avec un pointeur vers une valeur constante !) avec indirection automatique, c'est-à-dire que le compilateur appliquera le * opérateur pour vous.
int i = 3; // A pointer to variable i or 'stores the address of i' int *ptr = &i; // A reference (or alias) for i. int &ref = i;>
Différences :
1. Initialisation : Un pointeur peut être initialisé de cette façon :
int a = 10; int *p = &a; // OR int *p; p = &a;>
Nous pouvons déclarer et initialiser le pointeur en même temps ou sur plusieurs lignes.
2. Pendant que vous êtes dans les références,
int a = 10; int &p = a; // It is correct // but int &p; p = a; // It is incorrect as we should declare and initialize references at single step>
NOTE: Cette différence peut varier d'un compilateur à l'autre. La différence ci-dessus concerne Turbo IDE.
3. Réaffectation : Un pointeur peut être réaffecté. Cette propriété est utile pour l'implémentation de structures de données comme une liste chaînée, un arbre, etc. Voir l'exemple suivant :
int a = 5; int b = 6; int *p; p = &a; p = &b;>
4. En revanche, une référence ne peut pas être réaffectée et doit être attribuée lors de l'initialisation.
int a = 5; int b = 6; int &p = a; int &p = b; // This will throw an error of 'multiple declaration is not allowed' // However it is valid statement, int &q = p;>
5. Adresse mémoire : Un pointeur a sa propre adresse mémoire et sa propre taille sur la pile, tandis qu'une référence partage la même adresse mémoire avec la variable d'origine et n'occupe aucun espace sur la pile.
int &p = a; cout << &p << endl << &a;>
6. Valeur NULL : Un pointeur peut se voir attribuer directement NULL, alors qu’une référence ne peut pas l’être. Les contraintes associées aux références (pas de NULL, pas de réaffectation) garantissent que les opérations sous-jacentes ne se heurtent pas à une situation d'exception.
7. Indirection : Vous pouvez avoir un pointeur vers un pointeur (appelé double pointeur) offrant des niveaux d'indirection supplémentaires, alors que les références n'offrent qu'un seul niveau d'indirection. Par exemple,
In Pointers, int a = 10; int *p; int **q; // It is valid. p = &a; q = &p; // Whereas in references, int &p = a; int &&q = p; // It is reference to reference, so it is an error>
8. Opérations arithmétiques: Diverses opérations arithmétiques peuvent être effectuées sur des pointeurs, alors qu'il n'existe pas de chose appelée « arithmétique de référence » (cependant, vous pouvez effectuer de l'arithmétique de pointeur sur l'adresse d'un objet pointé par une référence, comme dans &obj + 5).
Forme tabulaire de différence entre les références et les pointeurs en C++
| Les références | Pointeurs | |
|---|---|---|
| Réaffectation | La variable ne peut pas être réaffectée dans Référence. | La variable peut être réaffectée dans les pointeurs. |
| Adresse mémoire | Elle partage la même adresse que la variable d'origine. | Les pointeurs ont leur propre adresse mémoire. |
| Travail | Il fait référence à une autre variable. | Il stocke l'adresse de la variable. |
| Valeur nulle | Il n'a pas de valeur nulle. | Il peut avoir une valeur attribuée à null. |
| Arguments | Cette variable est référencée par la méthode pass by value. | Le pointeur fonctionne par la méthode dite de passage par référence. |
Quand utiliser quoi
Les performances sont exactement les mêmes puisque les références sont implémentées en interne sous forme de pointeurs. Mais vous pouvez quand même garder certains points à l’esprit pour décider quand utiliser quoi :
- Utiliser des références :
- Dans les paramètres de fonction et les types de retour.
- Utilisez des pointeurs :
- Si l’arithmétique du pointeur ou le passage d’un pointeur NULL est nécessaire. Par exemple, pour les tableaux (notez que l'accès à un tableau est implémenté à l'aide de l'arithmétique du pointeur).
- Pour implémenter des structures de données comme une liste chaînée, un arbre, etc. et leurs algorithmes. En effet, pour pointer vers différentes cellules, nous devons utiliser le concept de pointeurs.
Cité dans FAQ Lite C++ : Utilisez des références lorsque vous le pouvez et des pointeurs lorsque vous le devez. Les références sont généralement préférées aux pointeurs chaque fois que vous n’avez pas besoin de les réinstaller. Cela signifie généralement que les références sont plus utiles dans l’interface publique d’une classe. Les références apparaissent généralement sur la peau d'un objet et les pointeurs à l'intérieur.
L’exception à ce qui précède concerne les cas où le paramètre ou la valeur de retour d’une fonction nécessite une référence sentinelle – une référence qui ne fait pas référence à un objet. Ceci est généralement mieux fait en renvoyant/prenant un pointeur et en donnant à la valeur nullptr cette signification particulière (les références doivent toujours alias des objets, pas un pointeur nul déréférencé).
Article associé:
Quand transmettons-nous des arguments sous forme de référence ou de pointeurs ?