2. Pointer Grundlagen
Um zu verstehen was ein Pointer macht, ist es hilfreich sich die Bedeutung des Wortes klar zu machen. Ein Pointer, im
deutschen ein Zeiger, ist ein Symbol das auf etwas zeigt, z.B. ein Pfeil im Straßenverkehr der einem die Richtung
weist oder der Zeiger einer Uhr der auf die Uhrzeit zeigt. Also hat ein Pointer eine "auf etwas zeigen" Funktion.
Worauf kann oder sollte aber in einem Programm gezeigt werden?
Wenn ein C-Programm geschrieben wird, dann werden ganz selbstverständlich Variablen verwendet. Für die Variable
werden ein Datentyp und ein Name festgelegt. Außerdem kann ein Wert zugewiesen werden, was folgendes Beispiel zeigt.
int messwert = 5;
(Datentyp Variablenname = Wert)
Beim Ausführen des Programms wird dieser Wert incl. Name und Datentyp im Speicher des Computers abgelegt. Der
Anwender bekommt dabei nicht mit, dass dieser Datensatz intern einen zusätzlichen Hexadezimalen Wert, die
Speicheradresse, vom Compiler zugewiesen bekommt. Dieser ist notwendig um bei der Vielzahl an möglichen Speicherplätzen den
richtigen Speicherplatz für einen Wert wieder zu finden. (Der Compiler bekommt vom System einen bestimmten Speicherbereich zugeweisen,
aus dem er wiederum willkürlich den Variablen Speicheradressen zuweisen kann.) Somit könnte die Speicherstelle für die obige Deklaration
folgendermaßen aussehen.
Der gespeicherte Wert kann nun über den Namen als auch über die Adresse abgerufen oder geändert werden. Wobei das
Abrufen eines Wertes über die direkte Adresse eher unüblich ist, da sie zu jeder Programmlaufzeit willkürlich
zugewiesen wird und in hexadezimaler Schreibweise nicht leicht zu merken ist. Jedoch ist ein indirekter Zugriff
möglich der in verschiedensten Programmen Anwendung findet. Dieser wird über den Pointer ermöglicht, der einmal
deklariert und initialisiert, auf die Adresse des Speicherplatzes "zeigt" in dem der Wert einer Variablen abgelegt
ist. Folgender Ausschnitt aus einem Speicherbereich verdeutlicht dies:
Der Wert des Pointers ist, wie im Beispiel erkennbar, die Adresse der Variable auf die der Pointer "zeigt".
Somit kann ein Pointer als normale Variable angesehen werden die als Wert, anstelle von beliebigen Daten,
Speicheradressen enthält. Um eine Pointervariable zu deklarieren muss bekannt sein welchen Datentyp die Variable, auf
die der Pointer zeigen soll, hat. Diese Angabe ist wichtig für die Sichtweise des Pointers. Sie gibt an wie viele
Bytes ab der Anfangsadresse (z.B. bei einer Ausgabe der Variable) ausgewertet werden müssen. Außerdem wird ein so
genannter Inhaltsoperator < * > verwendet, der den Compiler erkennen lässt das die Variable ein Pointer ist.
int *pointer_auf_mw;
(Datentyp auf den der Pointer zeigt – Inhaltsoperator - Pointername)
Zur Initialisierung des Pointers werden der Name der Variable, auf die gezeigt werden soll, und der Adressoperator <
& > (er gibt die Anfangsadresse einer Variablen zurück) benötigt.
pointer_auf_mw = &messwert;
(Pointername = Adressoperator Variablenname)
Wenn die Variable, auf die der Pointer zeigen soll, noch nicht bekannt ist muss dieser mit NULL initialisiert werden.
Der Pointer wird sozusagen geerdet was ihn auf einen definierten Zustand setzt. Dadurch wird vermieden, dass der
Pointer ungültige Daten enthält.
pointer_auf_mw = NULL;
Über vorherige Befehlsfolge wurde als Wert für den Pointer die Adresse der Variable messwert im Speicher abgelegt.
Folgende Befehlszeilen zeigen auf, welche Möglichkeiten es gibt den Wert der Variable messwert auszugeben. Der
Inhaltsoperator kann hier folgendermaßen verstanden werden: „Inhalt der Adresse auf den der Pointer zeigt“.
printf("Inhalt der Variable messwert über Variablenname:%d", messwert);
printf("Inhalt der Variable messwert über Pointer:%d", *pointer_auf_mw);
Folgende Zeilen erscheinen in der Bildschirmausgabe:
In beiden Fällen wird der Inhalt der Variable messwert ausgegeben. Mit folgenden Befehlszeilen
kann überprüft werden, ob die Adresse der Variable und der Wert des Pointers tatsächlich gleich sind.
printf("Adresse der Variable messwert:%d", &messwert);
printf("Inhalt der Variable pointer_auf_mw:%d", pointer_auf_mw);
Und tatsächlich belegt das Ergebnis, wie folgende Bildschirmausgabe beweist, dass die Adressen gleich sind. Dies muss
auch so sein, da die Adresse der Variable messwert als Wert in der Pointervariable gespeichert ist.
Der Wert der Variable messwert kann entweder direkt oder auch über einen Pointerzugriff
geändert werden:
messwert = 7; /* direkte Änderung */
*pointer_auf_mw = 7; /* Änderung über Pointerzugriff */
Grundsätzlich belegt eine Pointervariable 4 Byte im Speicher (bei einem 32 Bit Adressbus, bei einem 64 Bit Adressbus sind es 8 Byte).
Ob ein Pointer eine gültige Adresse enthält wird vom Compiler nicht überprüft. Deshalb kann es nur im Sinne des Programmierers
sein, dieses selbständig zu kontrollieren. Um im Variablennamen kenntlich zu machen das es sich bei der Variable um einen Pointer
handelt, können verschiedene Möglichkeiten der Namensgebung genutzt werden: pointer_auf_mw; pt_messwert; messwert_pt.
Grundsätzlich ist dem Programmierer die Gestaltung des Pointer-Variablennamen freigestellt, jedoch sollte er im
Programm einheitlich sein und anderen Programmierern kenntlich machen, dass eben diese Variable ein Pointer ist.
Welche Vorteile die Verwendung von Pointern bei der C-Programmierung noch haben kann, wird in den nachfolgenden
Einheiten verdeutlicht.