Delphipage - la reference en Delphi
Accueil - Astuces - Composants - Programmes - Tutoriaux - Livres - Liens
 Sources
- Astuces
- Composants
- Programmes
- Tutoriaux
 Rechercher
- Delphipage
- Ngscan
 Ressources
- Lexique Delphi
- Livres
- News
- Patchs Delphi
 Liens
- Borland France
- CodeGear
- Les meilleurs sites


Tutoriaux - Pointeurs

Présentation 

Un pointeur est une variable dont le le contenu n'est pas une donnée mais une adresse mémoire (emplacement dans la mémoire).


L'utilité d'un pointeur est d'accèder à une variable par son pointeur, c'est à dire son adresse mémoire.


Utiliser les pointeurs en Delphi

Déclarer un pointeur

Pour déclarer un pointeur en Pascal, on utilise l'opérateur "^" devant le nom.


var PInt:^integer; //PInt pointe sur un entier

"PInt" est donc une adresse mémoire.
Par convention, lorsque l'on créé généralement un pointeur, on commence le nom du pointeur par la lettre "P" pour distinguer plus facilement une variable et un pointeur.

Récupèrer l'adresse d'une variable

La valeur initiale d'un pointeur est la valeur "NIL", c'est à dire que le pointeur ne pointe sur rien. Il faut donc lui attribuer une adresse mémoire.

Pour récupèrer l'adresse d'une variable, on utilise la fonction "Addr".

var PInt:^integer; //PInt pointe sur un entier
i:integer; //i est un entier
begin
PInt:=Addr(i); //Le pointeur "PInt" contient maintenant l'adresse de la variable "i"
end;

A noté également, qu'au lieu d'utiliser la fonction "Addr", nous aurions put utiliser l'opérateur "@".
Voici ce que le code aurait donné :

var PInt:^integer;
i:integer;
begin
PInt:=@i; //Le pointeur "PInt" contient l'adresse de la variable "i"
end;

En faites, la fonction "Addr" est équivalent à l'opérateur "@".


Accèder à une variable par son pointeur

Pour accèder à une variable à partir de son pointeur, il suffit dans un premier temps de récupèrer l'adresse de la variable grâce à la fonction "Addr" (ou l'opérateur "@") que l'on a vu précèdemment.
Puis dans un deuxième temps, de déférencer le pointeur, c'est à dire de prendre en compte le contenu (l'adresse de la variable "i") que designe le pointeur.

Pour déférencer le pointeur, il suffit de spécifier le nom du pointeur suivit de l'opérateur "^". On accède ainsi à la valeur de l'adresse correspondante.

var PInt:^integer; //PInt pointe sur un entier
i:integer; //"i" est un entier
begin
PInt:=Addr(i); //Le pointeur "PInt" contient maintenant l'adresse de la variable "i"
PInt^:=10; //Met la valeur "10" à l'adresse correspondante (l'adresse de la variable "i")
ShowMessage(IntToStr(i)); //Affiche la valeur de la variable "i" (10)
end;

Lorsque l'on effectue l'instruction "PInt^:=10;", cela équivaut à faire "i:=10;".

On peut schématiser cette opération de cette manière :


En réalité, un pointeur est une valeur stockée dans un emplacement de la mémoire. Cette valeur correspond à une adresse spécifique (l'adresse de la variable "i") de la mémoire.



Création d'un nouveau type

On a également la possibilité de créer un nouveau type qui est un pointeur.


type PInteger=^integer; //Crée un nouveau type "PInteger"
var PInt:PInteger; //Associe une variable "PInt" au type "PInteger"

Gérer l'espace mémoire

Pour gérer l'espace mémoire d'un pointeur, il existe deux solutions :
- Les procédures "New" et "Dispose".
- Les procédures "GetMem" et "FreeMem".

La procédure "New" permet de réserver l'espace mémoire suffisant selon le type.
La procédure "Dispose", quant à elle, permet de libèrer l'espace mémoire allouée grâce à la procédure "New".

type PInteger=^integer;
var PInt:PInteger;
begin
New(PInt); //Réserve un espace mémoire suffisant
PInt^:=10;
ShowMessage(IntToStr(PInt^)); //Affiche la valeur "10"
Dispose(PInt); //Libère l'espace mémoire allouée
end;

Dans notre cas, la taille du bloc de mémoire alloué correspond à la taille du type pointé par "PInt".
On se sert d'un pointeur comme d'une variable.

Contrairement aux procédures "New" et "Dispose", vous devez spécifier l'espace mémoire allouée selon le type. Pour cela, on utilise la fonction "SizeOf".

type PInteger=^integer;
var PInt:PInteger;
begin
GetMem(PInt,SizeOf(integer)); //Réserve un espace mémoire suffisant
PInt^:=10;
ShowMessage(IntToStr(PInt^)); //Affiche la valeur "10"
FreeMem(PInt,SizeOf(integer)); //Libère l'espace mémoire allouée
end;

Pointeurs non typés

Nous avons vu précèdemment les pointeurs typés, c'est à dire que le pointeur "PInt" était associé à un type de données (dans notre cas, le type était "integer"). Cela permet de connaitre le nombre d'octets mémoire à réserver.

On peut également utiliser les pointeurs non typé (appelé aussi "atypiques"). On se sert des pointeurs non typés pour affecter le contenu de n'importe quel pointeur typé.
Pour déclarer un pointeur non typé, on utilise le mot "pointer".

var PInt:^integer;
PCh:^char;
PPoint:pointer; //Déclare le pointeur non typé
begin
PPoint:=PInt; //Affecte n'importe quel pointeur
PPoint:=PCh;
end;

Il est impossible de déférencer directement un pointeur pour manipuler la valeur stockée à cette adresse. En effet, aucun type n'étant désigné, le compilateur Delphi ne peut affecter une valeur particulière.

Néanmoins, vous pouvez affecter quand même une valeur en faisant en transtypage, c'est à dire en indiquant un type spécifique.

var PPoint:pointer; //PInt est un pointeur non typé
i:integer; //i est un entier
begin
i:=10; //Affecte la valeur "10" à "i"
PPoint:=Addr(i); //Récupère l'adresse de la variable "i"
Integer(PPoint^):=i; //Spécifie un type
ShowMessage(IntToStr(Integer(PPoint^))); //Affiche la valeur "10"
end;

Tous droits réservés - Contacts
Haut de la page