Pointeur (programmation)
En programmation informatique, un pointeur est un objet qui contient une adresse mémoire. On dit que le pointeur pointe vers la donnée à cette adresse-là. C'est l'outil fondamental de l'adressage dit « indirect ». L'opération qui consiste à obtenir la donnée à l'adresse mémoire s'appelle le déréférencement. Intuitivement, un numéro de page, par exemple 42, dans un livre peut être considéré comme un pointeur ; déréférencer un tel pointeur correspondent à obtenir le texte de la page 42.
Les données pointées par un pointeur peuvent être de différents types (entier, suite de caractères, etc.). Une donnée peut aussi être un point d'entrée d'une fonction, comme dans une table de méthode virtuelle.
Histoire
modifierLes pointeurs « typés », le type le plus répandu de pointeur actuellement, sont apparus avec le langage Algol 68, sous le vocable de "référence". Le langage C y a ajouté l'arithmétique des pointeurs : quand on incrémente de 1 un tel pointeur, on augmente l'adresse mémoire de la taille du type pointé afin de lire la donnée suivante.
Utilité
modifier
La notion de pointeur reflète l'utilisation différente que l'on peut faire d'un entier naturel, à savoir indiquer une adresse mémoire. Cette utilisation est très différente d'une utilisation arithmétique, d'où la création de registres de processeurs spécifiques (les registres d'adresse) et d'un type de donnée spécifique dans les langages de programmations.
L'utilisation des pointeurs permet d'avoir accès à la couche basse de l'ordinateur, à savoir la mémoire. On peut se déplacer de case mémoire en case mémoire. Cette technique permet au programmeur d'effectuer des optimisations sur l'utilisation de la mémoire ou la performance.
Les pointeurs sont entre autres utilisés pour stocker les adresses des zones mémoires allouées dynamiquement par l'application. Si on alloue un bloc de taille T et qu'on reçoit l'adresse A en retour, cela veut dire que le bloc occupe la mémoire à partir de l'adresse A jusqu'à l'adresse A+T-1.
Dans les langages de plus haut niveau, l'utilisation des pointeurs est supprimée, au profit des références et des tableaux dynamiques gérés par le compilateur. Les références remplissent certaines fonctions des pointeurs en supprimant l'accès à la mémoire. Cela évite beaucoup de problèmes, en contrepartie certaines utilisations et optimisations ne sont plus possibles, tandis que d'autres le deviennent.
Complexification
modifierL'utilisation des pointeurs est très puissante[Quoi ?] dans certains langages[Lesquels ?]. Cette puissance (et surtout le fait que l'on touche directement à la mémoire sans aucun contrôle) complexifie le développement d'une application.
Si l'on ne fait pas attention et que le programme accède à une zone mémoire qui ne lui est pas allouée, le processeur via le système d'exploitation engendrera une erreur de segmentation qui provoquera une exception voire plantera l'application. De plus, comme les allocations mémoire sont réalisées en partie par le développeur, il doit également se charger de la libération de la mémoire lorsqu'il n'en a plus besoin, au risque de voir une fuite de mémoire apparaître.
Tous ces inconvénients obligent le développeur à prendre en charge des tâches supplémentaires, compliquant ainsi l'application et pouvant ajouter des bugs.
Pour toutes ces raisons, les pointeurs sont regardés avec une certaine méfiance. 01 Informatique les a qualifiés d'« aussi puissants qu'ils sont dangereux »[1], en expliquant les atouts du langage D. En effet, au vu des avantages et inconvénients des pointeurs, ce langage a été conçu pour en autoriser l'usage aux programmeurs appréciant leur efficacité, tout en fournissant constamment des solutions alternatives à ceux qui s'en méfient.
Arithmétique des pointeurs
modifierOn appelle arithmétique des pointeurs la possibilité de faire des opérations arithmétiques (incrémentation, décrémentation, addition et soustraction) sur les pointeurs. Cela revient à effectuer un déplacement en mémoire.
La particularité de cette utilisation des pointeurs est que l'on se déplace par saut de la taille mémoire du type de donnée pointé par le pointeur et non par byte (la plus petite unité de mémoire adressable).
Langages sans pointeurs
modifierCertains langages ne permettent pas l'utilisation explicite de pointeurs. La majorité des langages de programmation utilisent (ou au moins permettent) le passage de paramètres par valeur. Typiquement, si n est un entier, alors l'appel de fonction f(n) ne pourra pas modifier n même si dans le code de la fonction, l'argument est incrémenté ; la raison est que la valeur de la variable n est d'abord copiée, si bien que la fonction f peut lire et écrire cette copie de la variable n, mais ne peut pas modifier la variable n originale.
Avec les pointeurs, il devient possible de passer en argument d'une fonction l'adresse d'une variable, et ainsi d'accéder en lecture et en écriture à la variable originale, et ce dans le code de la fonction.
Dans la plupart des langages de programmation sans pointeurs, par exemple Python, Java ou JavaScript/ActionScript, les variables ou objets sont toujours passés par valeur, mais l'accès aux champs de ces objets se fait par référence ou par adresse. Typiquement, si o est un objet, alors f(o) ne pourra modifier o, mais pourra modifier (s'ils existent) les champs de o, par exemple s'il existe le champ o.taille de l'objet o original pourra être incrémenté dans le code de la fonction. Ainsi, en passant par référence / adresse les champs des objets, c'est-à-dire en modélisant un objet comme étant une liste de références / pointeurs sur ses champs, il devient possible d'implémenter toutes les structures de données qui nécessitent des pointeurs tels que les arbres, les listes chaînées, etc. Pour ce qui est des tableaux, tout fonctionne comme si les tableaux étaient des objets possédant un opérateur [], l'écriture tab[i] donnant accès au champ i de l'objet tab. Dans une fonction prenant en argument un tableau, il est donc (uniquement) possible de modifier les éléments du tableau.
Mais certains langages fonctionnent différemment. En PHP, les variables ou objets peuvent être au choix passés par valeur/copie ou par référence/adresse, en utilisant au choix la syntaxe f(&$n) au lieu de f($n).
Langages utilisant les pointeurs
modifierPointeur sur une fonction
modifierLes pointeurs peuvent également contenir l'adresse d'une fonction. Cette dernière peut ainsi être passée en paramètre à une autre fonction et être appelée.
C
modifierVoici un exemple en C de la déclaration d'un pointeur de fonction f qui pointe successivement vers les fonctions f1() et f2() :
#include<stdio.h>
void f1() {
printf("Affichage de f1.\n");
}
void f2() {
printf("Affichage de f2.\n");
}
int main() {
void (*f) ();
f = f1;
f();
f = f2;
f();
return 0;
}
Ce code va produire la sortie suivante :
Affichage de f1.
Affichage de f2.
Pascal
modifierprocedure f1;
begin
writeln('Affichage de f1.\n');
end;
procedure f2;
begin
writeln('Affichage de f2.\n');
end;
var
f : procedure;
begin
@f := @f1;
f;
@f := @f2;
f;
end.
Voir aussi
modifierRéférences
modifier- ↑ Philippe Davy, « Le langage D rénove la programmation systèmes », 01 Informatique, (consulté le ).

