Computerwissenschaften

Verstehen und Verwenden von Zeigern in Delphi

Obwohl Zeiger in Delphi nicht so wichtig sind wie in C oder C ++. sind sie ein so „grundlegendes“ Werkzeug, dass fast alles, was mit Programmierung zu tun hat, in irgendeiner Weise mit Zeigern umgehen muss.

Aus diesem Grund können Sie lesen, wie eine Zeichenfolge oder ein Objekt wirklich nur ein Zeiger ist, oder dass ein Ereignishandler wie OnClick tatsächlich ein Zeiger auf eine Prozedur ist.

 

Zeiger auf Datentyp

Einfach ausgedrückt ist ein Zeiger eine Variable, die die Adresse von allem im Speicher enthält.

Um diese Definition zu konkretisieren, denken Sie daran, dass alles, was von einer Anwendung verwendet wird, irgendwo im Speicher des Computers gespeichert ist. Da ein Zeiger die Adresse einer anderen Variablen enthält, soll er auf diese Variable verweisen.

Meistens verweisen Zeiger in Delphi auf einen bestimmten Typ:

var
 iValue, j: Ganzzahl ; pIntValue: ^ Ganzzahl; 
begin iValue:=2001; pIntValue:[email protected]; ... j:=pIntValue ^; 
Ende ;

Die Syntax zum Deklarieren eines Zeigerdatentyps verwendet ein Caret (^) . Im obigen Code ist iValue eine Variable vom Typ Integer und pIntValue ein Zeiger vom Typ Integer. Da ein Zeiger nichts anderes als eine Adresse im Speicher ist, müssen wir ihm die Position (Adresse) des in der Ganzzahlvariablen iValue gespeicherten Werts zuweisen.

Der @ -Operator gibt die Adresse einer Variablen zurück (oder eine Funktion oder Prozedur, wie unten gezeigt wird). Entspricht dem @ -Operator ist die Addr-Funktion . Beachten Sie, dass der Wert von pIntValue nicht 2001 ist.

In diesem Beispielcode ist pIntValue ein typisierter Ganzzahlzeiger. Ein guter Programmierstil besteht darin, so oft wie möglich typisierte Zeiger zu verwenden. Der Zeigerdatentyp ist ein generischer Zeigertyp. Es stellt einen Zeiger auf beliebige Daten dar.

Beachten Sie, dass wenn „^“ nach einer Zeigervariable angezeigt wird, der Zeiger nicht mehr referenziert wird. Das heißt, es wird der Wert zurückgegeben, der an der vom Zeiger gehaltenen Speicheradresse gespeichert ist. In diesem Beispiel hat die Variable j den gleichen Wert wie iValue. Es mag so aussehen, als hätte dies keinen Zweck, wenn wir j einfach iValue zuweisen können, aber dieser Code steckt hinter den meisten Aufrufen der Win-API.

 

NILing Zeiger

Nicht zugewiesene Zeiger sind gefährlich. Da wir mit Zeigern direkt mit dem Arbeitsspeicher des Computers arbeiten können, kann es zu einem Fehler bei der Zugriffsverletzung kommen, wenn wir (versehentlich) versuchen, an einen geschützten Speicherort im Speicher zu schreiben. Aus diesem Grund sollten wir immer einen Zeiger auf NIL initialisieren.

NIL ist eine spezielle Konstante, die jedem Zeiger zugewiesen werden kann. Wenn einem Zeiger nil zugewiesen ist, verweist der Zeiger auf nichts. Delphi präsentiert beispielsweise ein leeres dynamisches Array oder eine lange Zeichenfolge als Nullzeiger.

 

Zeichenzeiger

Die Grundtypen PAnsiChar und PWideChar repräsentieren Zeiger auf AnsiChar- und WideChar-Werte. Das generische PChar repräsentiert einen Zeiger auf eine Char-Variable.

Diese Zeichenzeiger werden verwendet, um nullterminierte Zeichenfolgen zu bearbeiten. Stellen Sie sich ein PChar als Zeiger auf eine nullterminierte Zeichenfolge oder auf das Array vor, das eine darstellt.

 

Zeiger auf Aufzeichnungen

Wenn wir einen Datensatz oder einen anderen Datentyp definieren, ist es üblich, auch einen Zeiger auf diesen Typ zu definieren. Dies macht es einfach, Instanzen dieses Typs zu manipulieren, ohne große Speicherblöcke zu kopieren.

Die Möglichkeit, Zeiger auf Datensätze (und Arrays) zu haben, erleichtert das Einrichten komplizierter Datenstrukturen als verknüpfte Listen und Bäume erheblich.

Typ
 pNextItem=^ TLinkedListItem 
TLinkedListItem=Datensatz sName: String; iValue: Integer; NextItem: pNextItem; 
Ende ;

Die Idee hinter verknüpften Listen besteht darin, uns die Möglichkeit zu geben, die Adresse für das nächste verknüpfte Element in einer Liste in einem NextItem-Datensatzfeld zu speichern.

Zeiger auf Datensätze können beispielsweise auch verwendet werden, wenn benutzerdefinierte Daten für jedes Baumansichtselement gespeichert werden.

 

Verfahrens- und Methodenzeiger

Ein weiteres wichtiges Zeigerkonzept in Delphi sind Prozedur- und Methodenzeiger.

Zeiger, die auf die Adresse einer Prozedur oder Funktion verweisen, werden als prozedurale Zeiger bezeichnet. Methodenzeiger ähneln Prozedurzeigern. Anstatt jedoch auf eigenständige Prozeduren zu verweisen, müssen sie auf Klassenmethoden verweisen.

Der Methodenzeiger ist ein Zeiger, der Informationen sowohl zum Namen als auch zum Objekt enthält, das aufgerufen wird.

 

Zeiger und Windows-API

Die häufigste Verwendung für Zeiger in Delphi ist die Anbindung an C- und C ++ – Code, einschließlich des Zugriffs auf die Windows-API.

Windows- API-Funktionen verwenden eine Reihe von Datentypen, die dem Delphi-Programmierer möglicherweise nicht vertraut sind. Die meisten Parameter beim Aufrufen von API-Funktionen sind Zeiger auf einen Datentyp. Wie oben erwähnt, verwenden wir in Delphi nullterminierte Zeichenfolgen, wenn wir Windows-API-Funktionen aufrufen.

In vielen Fällen müssen diese Puffer und Datenstrukturen von der Anwendung zugewiesen werden, bevor ein API-Aufruf erfolgt, wenn ein API-Aufruf einen Wert in einem Puffer oder Zeiger auf eine Datenstruktur zurückgibt. Die Windows-API-Funktion SHBrowseForFolder ist ein Beispiel.

 

Zeiger- und Speicherzuordnung

Die wahre Stärke von Zeigern beruht auf der Fähigkeit, Speicher während der Ausführung des Programms zu reservieren.

Dieser Code sollte ausreichen, um zu beweisen, dass die Arbeit mit Zeigern nicht so schwierig ist, wie es zunächst scheinen mag. Es wird verwendet, um den Text (Beschriftung) des Steuerelements mit dem bereitgestellten Handle zu ändern.

Prozedur GetTextFromHandle (hWND: THandle); 
var pText: PChar; // ein Zeiger auf char (siehe oben) TextLen: integer; 
begin 
{Länge des Textes ermitteln} TextLen:=GetWindowTextLength (hWND); 
{Speicher zuordnen}
 GetMem (pText, TextLen); // nimmt einen Zeiger 
{holt den Text des Steuerelements} GetWindowText (hWND, pText, TextLen + 1); 
{Text anzeigen} ShowMessage (String (pText)) 
{Speicher freigeben } FreeMem (pText); 
Ende ;

Similar Posts

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.