Datentypen in "C", Teil 3 |
|
Ein Zeiger ist eine Variable, die die Adresse einer Variablen enthält.
Zeigervariablen können auf fast jeden beliebigen
Datentypen definiert werden.
Die Definition einer Zeigervariablen enthält die
Bezeichnung des Datentypen, auf welchen der Zeiger gesetzt werden soll und den
Variablennamen der Zeigervariable, welchem jedoch zur Kennzeichnung ein * vorangesetzt wird. Soll also eine
Zeigervariable mit Namen intpointer
definiert werden, die auf ein Integer-Element zeigen kann, so definieren wir:
int *intpointer;
Haben wir nun in unserem Programm eine Variable intvar des Datentyps int, so können wir unsere Zeigervariable auf diese Integervariable zeigen lassen:
intpointer = &intvar;
Um nun den Wert zu bestimmen, der in intvar gespeichert ist, können wir mit dem Inhaltsoperator (*) über die Zeigervariable auf den Speicherplatz zugreifen.
printf ("Der Wert von intvar ist %d\n", *intpointer);
Beispiel:
int i, x, *ip;
i = 5;
ip = &i; /* ip zeigt nun auf i */
x = *ip; /* x enthaelt nun den Wert 5 */
*ip = 3; /* i enthaelt jetzt den Wert 3 */
Wichtig: | Jede Zeigervariable muss vor deren Verwendung auf ein gültiges Ziel gesetzt werden, sonst droht ein Absturz! |
Zusätzlich gibt es noch den generischen Zeiger (void *), der auf auf einen beliebigen Datentypen zeigen kann. Mit diesem generischen Zeiger können jedoch keine Operationen durchgeführt werden, da der Zieldatentyp dem Compiler nicht bekannt ist.
void vp;
int ip;
double *dp;
vp = ip; /* void-Pointer und andere Pointer können sich gegenseitig */
dp = vp; /* zugewiesen werden */
Arrays und Pointer sind in C eng miteinander verknüpft. Um eine Zeigervariable auf ein bestimmtes Element innerhalb eines Arrays zeigen zu lassen, kann der Adressoperator (&) verwendet werden:
ip = &array2dim[2][3];
Soll der Zeiger auf das erste Element eines Arrays gesetzt werden, so kann eine vereinfachte Schreibweise gewählt werden:
ip = array2dim; /* Setzt den Zeiger ip auf das erste Element von array2dim */
Arrayvariablen können bei deren Definition auch initialisiert werden, indem die Initialisierungswerte innerhalb einer Blockanweisung angegeben werden:
int iarray[] = {10, 20, 30};
Die Grössenangabe für das Array kann hier weggelassen werden, da der Compiler die Grösse des Arrays anhand der Anzahl von Initialisierungswerten bestimmen kann.
Wird eine Zeigervariable definiert und mit Hilfe dieser Variablen vom Betrriebsystem dynamischer Speicher angefordert, so kann danach auf die Zeigervariable zugegriffen werden, wie wenn es sich um ein Array handeln würde:
int *iarray;
main ()
{
int i;
iarray = calloc (100, sizeof (int)); /* Reserviert Speicher fuer 100 Integerwerte */
/* Und nun fuellen wir unser dynamisches Array mit Zufallszahlen */
for (i=0; i<100, i++) {
iarray[i] = rand ();
}
free (iarray); /* Speicher sollte am Programmende freigegeben werden */
}
Um Zeigervariablen als ungültig zu kennzeichnen wird ihnen meistens der Wert NULL zugewiesen (ip = NULL). Damit können Zeigervariablen während des Programmablaufs auf ihre Gültigkeit hin überprüft werden:
if (ip == NULL) printf ("Zeiger zeigt nirgendwohin\n");
Mit Zeigervariablen können eine Reihe von Operationen durchgeführt werden:
Addieren und Substrahieren von ganzzahligen
Werten zu bzw. von einer Zeigervariablen.
Wird zu einer Zeigervariablen, die auf ein double-Array zeigt, der Wert 1
addiert, so zeigt die Variable danach auf das nächstfolgende Element im
double-Array. Dies funktioniert ebenso mit jedem beliebigen anderen Datentypen.
Substrahieren zweier Zeiger. Das Resultat einer solchen Berechnung ist ein ganzzahliger Wert.
Logische Vergleiche zweier Zeiger (==, !=, <, > etc).
Zuweisungen einer Zeigervariable an eine andere Zeigervariable. Mit Hilfe des Typecastings (Typenumwandlung) können auch Zeiger, die auf unterschiedliche Datentypen zeigen, einander zugewiesen werden. Zuweisungen an und von Zeigern des Typs void können immer vorgenommen werden, auch ohne Typumwandlung.
Da Zeiger auch nur normale Variablen sind,
können sie auch zu Arrays zusammengefasst werden. Dies wird oft gemacht um eine
Anzahl von Fehler- oder anderen Meldungen zu Programmbeginn festzulegen.
Beachten Sie bitte folgendes Beispiel:
char
*errmess[] = {
"Datei konnte
nicht geöffnet werden!",
"Datei kann nicht
gespeichert werden!",
"Kein Speicher
mehr frei!",
"Ungültige
Operation!",
NULL}
Der Nullzeiger am Schluss wird oft eingefügt, um das Ende des Stringarrays eindeutig zu kennzeichnen.
|