POINTEUR
On accède habituellement à une variable par son nom.Nb1:=Nb2;On localise l'adresse par le nom de la variable, mais on peut aussi accéder à son contenu directement par son adresse. L'adresse sert à localiser un emplacement en mémoire. Un pointeur est une constante ou variable qui possède l'adresse d'une variable. Le pointeur pointe vers la variable concernée.
Les pointeurs sont plus rapides et utilisent moins de mémoire que si on utiliserait directement la variable. Les variables utilisent la mémoire locale qui est en quantité minime. Lorsqu'on utilise un pointeur, seul ce dernier est dans la mémoire locale. Les éléments pointés sont eux dans la mémoire globale qui est beaucoup plus grande. On peut aisément se rendre compte de l'importance d'utiliser les pointeurs.
var ptrNote : Pointer; Note : integer; begin ptrNote := @Note; end;
La variable stocke l'adresse l'adresse de ptrNote. C'est un pointeur non typé.
Les pointeurs ne pointent pas obligatoirement vers une adresse, on peut leur assigner une valeur nulle avec le mot «nil». On utilise beaucoup cette affectation afin de vérifier si le pointeur pointe quelque part.
var ptrNote : pointer; begin ptrNote := nil; end;
Le type pointer déclare un pointeur sur n'importe quoi. Le type de donnée pointé ne peut être connu même si on peut accèder à son contenu. Ce n'est vraiment pas pratique dans un programme. On doit utiliser des pointeurs spécifiques à un type pour régler le problème. Un pointeur sur un integer, sur un real... Au lieu d'utiliser directement le pointeur, on préfèrera créer un nouveau type et on déclarera les variables ou les paramètres en utilisant ce nouveau type. Pointeur vers s'écrit en delphi ^, ce qui équivaut à * du c.
Langage c | Delphi |
int *ptrNote; int Note=74; ptrNote=&Note; |
type pNote:=^integer; var Note:pNote; begin Note^:=74; end; |
type pNote:=^integer;
Dans cet exemple, la variable pNote pointe sur un type integer. On déclare ainsi un pointeur sur un integer. pNote := ^long; Ici pNote serait un pointeur sur un long. Lorsque ^ est avant un type de donnée (déclaration) comme dans les exemples ci-dessus, le ^ signifie pointe sur. Le ^ est avant le type de donnée, c'est typique à la déclaration.
variable :=^ <type de donnée>Lorsqu'on veut effectuer des opérations sur le contenu de la valeur pointé par le pointeur, on utilise encore ^. Le ^ est après le nom du pointeur comparativement au cas de déclaration qui est situé après.
pNote ^:= 54;Dans cette exemple, on affecte 54 à la valeur contenu à l'adresse pointé par le pointeur. On effectue ainsi une affectation.
Les éléments pointés par les pointeurs sont gérés dynamiquement et c'est au programmeur qui doit coordonner, le tout. La gestion de l'élément pointé se fait en deux étapes
- Initialisation
- Destruction
type pNote = ^Integer; var Note : pNote; begin new(Note); //initialisation du pointeur Note^ := 54; //affectation du pointeur dispose(Note); //destruction du pointeur end;
Opération sur les pointeurs
Les pointeurs sont limités aux opérations d'affection et de comparaison.
Affectation
Les pointeurs doivent pointer vers le même type avant de pouvoir faire une affectationvar PNote : ^Integer; PNbEleve :^Integer; begin new(PNote); new(PNbEleve); PNote := PNbEleve; dispose(PNote); dispose(PNbEleve); end;
L'affectation ci-dessus est possible, car les deux pointeurs pointent sur des integers. Étant donnée qu'après cette affectation les deux pointeurs pointent au même endroit, il faut détruire qu' un seul pointeur. Il est aussi possible de copier le contenu d'un pointeur dans un autre pointeur, mais les deux pointeurs doivent pointer sur le même type de donnée.
var PNote :^Integer; PNbEleve :^Integer; begin new(PNote); new(PNbEleve); PNote :=PNbEleve; PNote^ := 5; dispose(PNote); end;
Comparaison
La comparaison sert à savoir si les pointeurs pointent au même endroit. Les signes «=» et «<>» peuvent être utilisés.if PNbEleve = PNote thenSi cette ligne de code retourne true (vrai), les deux pointeurs pointent à la même adresse.
Pointeurs d'enregistrements
Ce type de pointeur est tout simplement un pointeur vers un enregistrement. On utilise beaucoup ce type de pointeur. Prenons comme exemple un enregistrement du chapitre 5type TInfoClient = record Prenom:string[20]; Nom:string[20]; Adresse:string[30]; Ville:string[20]; CodePostal:string[6]; end; PInfoClient:TInfoClient; var InfoClient:PInfoClient; begin New(InfoClient); InfoClient^.Prenom := 'Paul'; InfoClient^.Nom := 'Houle'; InfoClient^.Adresse := '1024 Des Chênes'; InfoClient^.Ville := 'Montreal'; InfoClient^.CodePostal := 'J4S2R4'; Dispose(InfoClient); end;Pour mieux comprendre les pointeurs, nous allons étudier les listes.
Liste
Les listes sont une suite d'éléments mis les uns à la suite des autres. On les utilise constamment dans la vie de tous les jours. En programmation, leurs utilités ne sont plus à faire. Les listes peuvent être utilisées pour y mettre n'importe quel type de donnée. Souvent, on les utilise avec les enregistrements.Opération sur les pointeurs
Création
type //Création des informations pour la liste TInfoClient = record Prenom:string[20]; Nom:string[20]; Adresse:string[30]; Ville:string[20]; CodePostal:string[6]; end;
Déclaration
type //Déclaration de la liste PListClient = ^TListClient; TListClient = record InfoClient :TInfoClient; ProchainNoeud:PListClient; end;
Construction
var PremierClient,TempClient:PListClient; begin PremierClient:=nil; //Initialise le premier pointeur new(TempClient); //Crée un noeud temporaire TempClient^.InfoClient.Prenom:='Paul'; TempClient^.InfoClient.Nom:='Prenom'; TempClient^.InfoClient.Adresse:='23 Nobert'; TempClient^.InfoClient.Ville:='Longueuil'; TempClient^.InfoClient.CodePostal:='J3S1H4'; TempClient^.ProchainNoeud:=PremierClient; end;
La dernière ligne permet d'ajouter le noeud à la liste afin qu'il pointe à la même adresse que le premier pointeur.
Cette instruction permet de faire pointer PremierClient au début de la liste
PremierClient:=TempClient;
Un petit programme illustrant les principes de base des listes est disponible en téléchargement ici.