Même si les pointeurs ne sont pas aussi importants dans Delphi qu'ils le sont en C ou C ++, ils sont un outil si "basique" que presque tout ce qui concerne la programmation doit traiter les pointeurs d'une certaine façon.
C'est pour cette raison que vous pourriez lire comment une chaîne ou un objet n'est vraiment qu'un pointeur, ou qu'un gestionnaire d'événements tel que OnClick, est en fait un pointeur vers une procédure.
Autrement dit, un pointeur est une variable qui contient l'adresse de quoi que ce soit en mémoire.
Pour concrétiser cette définition, gardez à l'esprit que tout ce qui est utilisé par une application est stocké quelque part dans la mémoire de l'ordinateur. Parce qu'un pointeur contient l'adresse d'une autre variable, on dit qu'il pointe vers cette variable.
La plupart du temps, les pointeurs de Delphi pointent vers un type spécifique:
var
iValue, j: entier; pIntValue: ^ entier;
commenceriValue: = 2001; pIntValue: = @iValue;… j: = pIntValue ^;
fin;
La syntaxe pour déclarer un type de données de pointeur utilise un caret (^). Dans le code ci-dessus, iValue est une variable de type entier et pIntValue est un pointeur de type entier. Puisqu'un pointeur n'est rien de plus qu'une adresse en mémoire, nous devons lui attribuer l'emplacement (adresse) de la valeur stockée dans la variable entière iValue.
le @ opérateur renvoie l'adresse d'une variable (ou d'une fonction ou procédure comme on le verra ci-dessous). L'équivalent de l'opérateur @ est Fonction Addr. Notez que la valeur de pIntValue n'est pas 2001.
Dans cet exemple de code, pIntValue est un pointeur entier typé. Un bon style de programmation consiste à utiliser autant de pointeurs que possible. Le type de données Pointer est un type de pointeur générique; il représente un pointeur vers toutes les données.
Notez que lorsque "^" apparaît après une variable de pointeur, il dé-référence le pointeur; c'est-à-dire qu'il renvoie la valeur stockée à l'adresse mémoire détenue par le pointeur. Dans cet exemple, la variable j a la même valeur que iValue. Il peut sembler que cela n'a aucun sens lorsque nous pouvons simplement attribuer iValue à j, mais ce morceau de code se trouve derrière la plupart des appels à l'API Win.
Les pointeurs non attribués sont dangereux. Étant donné que les pointeurs nous permettent de travailler directement avec la mémoire de l'ordinateur, si nous essayons (par erreur) d'écrire dans un emplacement protégé en mémoire, nous pourrions obtenir une erreur de violation d'accès. C'est la raison pour laquelle nous devons toujours initialiser un pointeur sur NIL.
NIL est une constante spéciale qui peut être affectée à n'importe quel pointeur. Lorsque nil est affecté à un pointeur, le pointeur ne fait référence à rien. Delphi présente, par exemple, un tableau dynamique vide ou une longue chaîne comme pointeur nul.
Les types fondamentaux PAnsiChar et PWideChar représentent des pointeurs vers les valeurs AnsiChar et WideChar. Le PChar générique représente un pointeur vers une variable Char.
Ces pointeurs de caractères sont utilisés pour manipuler des chaînes terminées par null. Considérez un PChar comme un pointeur vers une chaîne terminée par un caractère nul ou vers le tableau qui en représente un.
Lorsque nous définissons un enregistrement ou un autre type de données, il est également courant de définir un pointeur vers ce type. Cela facilite la manipulation des instances du type sans copier de gros blocs de mémoire.
La possibilité d'avoir des pointeurs vers des enregistrements (et des tableaux) facilite la configuration de structures de données complexes sous forme de listes et d'arbres liés.
type
pNextItem = ^ TLinkedListItem
TLinkedListItem = recordsName: String; iValue: Integer; NextItem: pNextItem;
fin;
L'idée derrière les listes liées est de nous donner la possibilité de stocker l'adresse de l'élément lié suivant dans une liste à l'intérieur d'un champ d'enregistrement NextItem.
Les pointeurs vers les enregistrements peuvent également être utilisés lors du stockage de données personnalisées pour chaque élément de l'arborescence, par exemple.
Un autre concept de pointeur important dans Delphi est les pointeurs de procédure et de méthode.
Les pointeurs qui pointent vers l'adresse d'une procédure ou d'une fonction sont appelés pointeurs procéduraux. Les pointeurs de méthode sont similaires aux pointeurs de procédure. Cependant, au lieu de pointer vers des procédures autonomes, ils doivent pointer vers des méthodes de classe.
Le pointeur de méthode est un pointeur qui contient des informations sur le nom et l'objet invoqué.
L'utilisation la plus courante des pointeurs dans Delphi est l'interface avec le code C et C ++, qui comprend l'accès à l'API Windows.
Les fonctions de l'API Windows utilisent un certain nombre de types de données qui peuvent ne pas être familiers au programmeur Delphi. La plupart des paramètres d'appel des fonctions API sont des pointeurs vers un type de données. Comme indiqué ci-dessus, nous utilisons des chaînes terminées par null dans Delphi lors de l'appel des fonctions de l'API Windows.
Dans de nombreux cas, lorsqu'un appel d'API renvoie une valeur dans un tampon ou un pointeur vers une structure de données, ces tampons et structures de données doivent être alloués par l'application avant que l'appel d'API ne soit effectué. La fonction API Windows SHBrowseForFolder en est un exemple.
La véritable puissance des pointeurs vient de la possibilité de mettre de la mémoire de côté pendant l'exécution du programme.
Ce morceau de code devrait être suffisant pour prouver que travailler avec des pointeurs n'est pas aussi difficile qu'il n'y paraît au premier abord. Il est utilisé pour changer le texte (légende) du contrôle avec la poignée fournie.
procédure GetTextFromHandle (hWND: THandle);
var pText: PChar; // un pointeur sur char (voir ci-dessus)TextLen: entier;
commencer
obtenez la longueur du texteTextLen: = GetWindowTextLength (hWND);
alocate memory
GetMem (pText, TextLen); // prend un pointeur
obtenir le texte du contrôleGetWindowText (hWND, pText, TextLen + 1);
afficher le texteShowMessage (String (pText))
libérer la mémoireFreeMem (pText);
fin;