Programmierkurs: Delphi: Pascal: Zeiger
Aus Wikibooks
Inhaltsverzeichnis |
[Bearbeiten] Zeiger
[Bearbeiten] Was sind Zeiger?
Ein Zeiger bzw. Pointer ist eine Variable, die auf einen Speicherbereich des Computers verweist. Zum besseren Verständnis hier ein kleines Beispiel:
Nehmen wir einmal an, wir haben einen Schrank mit 50 verschiedenen Fächern. Jedes Fach ist mit einer Nummer gekennzeichnet, dazu hat er in jedem Fach einen Gegenstand.
Im Sinne von Zeiger in einer Programmiersprache ist der Schrank der Speicherbereich des Computers, welcher dem Programm zur Verfügung gestellt wird. Jedes einzelne Fach des Schrankes repräsentiert eine Adresse auf diesem Speicher. Die Nummer des Faches entspräche der Speicheradresse, der Inhalt der Lade dem Wert des Objektes, auf das der Zeiger verweist. Auf jedem Speicher kann nun auch eine beliebige Bitreihenfolge abgespeichert werden.
[Bearbeiten] Wozu dienen Zeiger?
Es gibt mehrere Gründe, warum man Zeiger benötigt. Zum einen sind hinter den Kulissen von Pascal sehr viele Zeiger versteckt, die große dynamische Speicherblöcke benötigen. Beispielsweise ist ein String ein Zeiger, wie auch eine Klasse nur ein einfacher Zeiger ist.
In vielen Fällen sind aber auch Zeiger dazu da, um die strikte Typisierung von Pascal zu umgehen. Dazu benötigt man einen untypisierten Zeiger, der nur den Speicherblock enthält, ohne Information dazu, was sich auf dem Speicherblock befindet.
Weiterhin kann man Zeiger dazu verwenden, um Speicher zu sparen. Dabei fordert man vom System immer nur genau soviel Speicherplatz an, wie man gerade für seine Daten benötigt. Das ist vor allem in den (zugegebenermaßen seltenen) Fällen sinnvoll, wenn man bei der Entwicklung eines Programms noch nicht weiß, welcher Art diese Daten sind und damit natürlich auch nicht weiß, wie groß die Datenmenge sein wird. Hierfür wird sich jedoch meistens eine elegantere Lösung finden. Man kann durch Zeiger auch Speicher sparen, wenn man ihn immer nur dann anfordert, wenn man ihn benötigt. Ein nicht zugewiesener Zeiger erfordert nämlich immer nur 4 Byte! Ein großes Record kann dagegen auch völlig unbenutzt mehrere KByte belegen.
[Bearbeiten] Anwendung
[Bearbeiten] Deklaration
Es gibt zwei Arten, wie man einen Zeiger deklarieren kann. Eine typisierte und eine untypisierte Variante.
var Zeiger1: ^Integer; // typisiert Zeiger2: Pointer; // untypisiert
[Bearbeiten] Speicheradresse auslesen
Im Code kann man nun entweder die Adresse oder den Inhalt des Speicherblockes auslesen. Das Auslesen der Adresse des Speicherblockes funktioniert gleich bei der un- wie auch bei der typisierten Variante.
begin Zeiger2 := @Zeiger1; Zeiger2 := Addr(Zeiger1); end.
Wie ihr seht, gibt es für das Auslesen der Adresse zwei Varianten. Entweder den @-Operator oder auch mit der Funktion Addr(), wobei zu bemerken ist, dass der @-Operator schneller ist. Hinter einem @-Operator kann jede beliebige Variable stehen, aber nur einem untypisierten Pointer kann jede Adresse jedes Speicherblocks zugeordnert werden, ohne auf den Typ zu achten.
[Bearbeiten] Inhalt auslesen
Hier gibt es einen Unterschied zwischen typisierten und untypisierten Zeiger.
var i, j: Integer; p1: ^Integer; p2: Pointer; begin i := 1; {typisiert} p1 := @i; // dem Pointer wird die Adresse der Integer-Variable übergeben p1^ := p1^+1; // hier wird der Wert um eins erhöht j := p1^; // typisiert: der Variable j wird 2 übergeben {untypisiert} p2 := @i; // analog oben Integer(p2^) := i+1; j := Integer(p2^); end.
Bei einem untypisierten Zeiger muss immer der Typ angegeben werden, welcher aus dem Speicher ausgelesen werden soll. Dies geschieht durch die so genannte Typumwandlung: Typ(Zeiger).
siehe hierzu auch Schnelleinstieg: Pointer
| Inhaltsverzeichnis | Pascal: Aufzählungen |