Comprendre et utiliser des pointeurs dans Delphi

click fraud protection

Même si les pointeurs ne sont pas aussi importants dans Delphes comme ils sont en C ou C ++, ils sont un outil tellement "basique" que presque tout ce qui concerne 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.

Pointeur vers le type de données

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, il est 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;
commencer
iValue: = 2001; pIntValue: = @iValue;... j: = pIntValue ^;
fin
;
instagram viewer

le 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 n'importe quelle donnée.

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.

Pointeurs NIL

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 rien est attribué à un pointeur, le pointeur ne fait référence à rien. Delphi présente, par exemple, un tableau dynamique ou une longue chaîne comme pointeur nul.

Pointeurs de caractères

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 terminaisons nulles cordes. 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.

Pointeurs vers les enregistrements

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: Entier; 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.

Pointeurs de procédure et de méthode

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, elles 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é.

Pointeurs et API Windows

L'utilisation la plus courante des pointeurs dans Delphi est l'interface avec le code C et C ++, qui inclut l'accès à l'API Windows.

les fenêtres Les fonctions API 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.

Pointeur et allocation de mémoire

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 texte}
TextLen: = GetWindowTextLength (hWND);
{alocate memory}

GetMem (pText, TextLen); // prend un pointeur
{obtenir le texte du contrôle}
GetWindowText (hWND, pText, TextLen + 1);
{afficher le texte}
ShowMessage (String (pText))
{libérer la mémoire}
FreeMem (pText);
fin
;
instagram story viewer