# Programmation C-C++/Référencement, indirection

Ce livre est en cours de copie depuis le site http://casteyde.christian.free.fr/online/cours_cpp/ qui le fournit sous licence GFDL.
Cours de C/C++ :
| Pointeurs et références ||
| | Notion d'adresse |
| | Notion de pointeur |
| | Référencement, indirection |
| | Notion de référence |
| | Lien entre les pointeurs et les références |
| | Passage de paramètres par variable ou par valeur |
| | Références et pointeurs constants et volatiles |
| | Arithmétique des pointeurs |
| | Utilisation des pointeurs avec les tableaux |
| | Les chaînes de caractères : pointeurs et tableaux à la fois ! |
| | Allocation dynamique de mémoire |
| | Pointeurs et références de fonctions |
| | Paramètres de la fonction main - ligne de commande |
| | DANGER |
| Livre original de C. Casteyde ||

## Référencement, indirection

Un pointeur ne servirait strictement à rien s'il n'y avait pas de possibilité d'accéder à l'adresse d'une variable ou d'une fonction (on ne pourrait alors pas l'initialiser) ou s'il n'y avait pas moyen d'accéder à l'objet référencé par le pointeur (la variable pointée ne pourrait pas être manipulée ou la fonction pointée ne pourrait pas être appelée).
Ces deux opérations sont respectivement appelées référencement et indirection (ou déréférencement). Il existe deux opérateurs permettant de récupérer l'adresse d'un objet et d'accéder à l'objet pointé. Ces opérateurs sont respectivement & et *.
Il est très important de s'assurer que les pointeurs que l'on manipule sont tous initialisés (c'est-à-dire contiennent l'adresse d'un objet valide, et pas n'importe quoi). En effet, accéder à un pointeur non initialisé revient à lire ou, plus grave encore, à écrire dans la mémoire à un endroit complètement aléatoire (selon la valeur initiale du pointeur lors de sa création). En général, on initialise les pointeurs dès leur création, ou, s'ils doivent être utilisés ultérieurement, on les initialise avec le pointeur nul. Cela permettra de faire ultérieurement des tests sur la validité du pointeur ou au moins de détecter les erreurs. En effet, l'utilisation d'un pointeur initialisé avec le pointeur nul génère souvent une faute de protection du programme, que tout bon débogueur est capable de détecter. Le pointeur nul se note NULL.
Note : NULL est une macro définie dans le fichier d'en-tête stdlib.h. En C, elle représente la valeur d'une adresse invalide. Malheureusement, cette valeur peut ne pas être égale à l'adresse 0 (certains compilateurs utilisent la valeur -1 pour NULL par exemple). C'est pour cela que cette macro a été définie, afin de représenter, selon le compilateur, la bonne valeur. Voir le chapitre "le préprocesseur" pour plus de détails sur les macros et sur les fichiers d'en-tête.
La norme du C++ fixe la valeur nulle des pointeurs à 0. Par conséquent, les compilateurs C/C++ qui définissent NULL comme étant égal à -1 posent un problème de portabilité certain, puisque un programme C qui utilise NULL n'est plus valide en C++. Par ailleurs, un morceau de programme C++ compilable en C qui utiliserait la valeur 0 ne serait pas correct en C.
Il faut donc faire un choix : soit utiliser NULL en C et 0 en C++, soit utiliser NULL partout, quitte à redéfinir la macro NULL pour les programmes C++ (solution qui me semble plus pratique).

### Exemple - Déclaration de pointeurs

Il est à présent facile de comprendre pourquoi il faut répéter l'étoile dans la déclaration de plusieurs pointeurs :
signifie syntaxiquement : p1, p2 et p3 sont des pointeurs d'entiers, mais aussi *p1, *p2 et *p3 sont des entiers.
Si l'on avait écrit :
seul p1 serait un pointeur d'entier. p2 et p3 seraient des entiers.
L'accès aux champs d'une structure par le pointeur sur cette structure se fera avec l'opérateur '->', qui remplace '(*).'.