Geschichte der Frage:
Die Zeigerarithmetik wurde in der Sprache C eingeführt, um eine effiziente Arbeit mit dem Speicher, Arrays und Strukturen zu gewährleisten. Sie ist eng verbunden mit der Speicheradressierung und damit, wie C auf der niedrigsten Ebene arbeitet – das Hinzufügen oder Subtrahieren von Zeigern ermöglicht den Zugriff auf aufeinanderfolgende Elemente eines Arrays.
Problem:
Die Hauptschwierigkeit besteht darin, dass die Zeigerarithmetik nicht mit der Arithmetik der Zahlen gleichzusetzen ist: Das Hinzufügen von 1 zu einem Zeiger erhöht dessen Wert um die Größe des Typs, auf den er zeigt. Klassische Fehler sind das Übersteigen der Grenzen eines zugewiesenen Arrays, die Arbeit mit inkompatiblen Zeigertypen und der Versuch, Berechnungen mit void * durchzuführen.
Lösung:
Immer die Größe des Typs bei der Arbeit mit Zeigern berücksichtigen, algebraische Berechnungen mit void* vermeiden und die Grenzen des Arrays kontrollieren. Um auf ein Element eines Arrays zuzugreifen, sollten Sie die Indizierung oder berechnete Zeiger verwenden und zuvor die Grenzen überprüfen.
Beispielcode:
#include <stdio.h> int main() { int arr[5] = {1, 2, 3, 4, 5}; int *p = arr; printf("%d\n", *(p + 2)); // 3 // Ungültig: p + 10 überschreitet die Grenzen des Arrays return 0; }
Wesentliche Merkmale:
Kann man zu einem Zeiger einen Wert vom Typ float oder andere Typen hinzufügen?
Nein, zu Zeigern kann man nur Werte des ganzzahligen Typs hinzufügen oder von ihnen abziehen. Die Verwendung von Gleitkommazahlen führt zu einem Kompilierungsfehler.
*Geben (arr + i) und arr[i] immer das Gleiche zurück, auch wenn i außerhalb der Grenzen des Arrays liegt?
Nein. Semantisch sind sie äquivalent, aber wenn der Index die Grenzen des Arrays überschreitet, führen beide Ausdrücke zu undefiniertem Verhalten (undefined behavior).
Was passiert, wenn man Zeiger subtrahiert, die auf verschiedene Arrays zeigen?
Das Ergebnis ist durch den Standard nicht definiert und wird als Fehler angesehen. Man kann nur Zeiger subtrahieren, die sich innerhalb eines Arrays (oder eines zusammenhängenden Speicherbereichs) befinden.
buffer overrun)Im Code verwendet der Entwickler die Zeigerarithmetik zur Durchlauf eines Arrays:
Vorteile:
Nachteile:
In der überarbeiteten Version werden explizite Grenzüberprüfungen bei jedem Schritt verwendet:
Vorteile:
Nachteile: