Pointer-Arithmetik
Teil des Abschnitts Logic & Flow der C-Journey von Coddy — Lektion 9 von 63.
Sie haben gelernt, wie man auf Array-Elemente mit der Pointer-Notation wie *(array + i) zugreift. Jetzt werden Sie eine noch leistungsfähigere Technik entdecken: Pointer-Arithmetik, die es Ihnen ermöglicht, Pointer mittels einfacher Inkrement- und Dekrement-Operationen durch den Speicher zu bewegen.
Wenn Sie einen Pointer mit ++ inkrementieren oder mit -- dekrementieren, bewegt sich der Pointer nicht nur um ein Byte. Stattdessen bewegt er sich um die Größe des Datentyps, auf den er zeigt. Bei einem Integer-Pointer bewegt sich ptr++ um sizeof(int) Bytes vorwärts und landet genau beim nächsten Integer im Speicher.
int numbers[5] = {10, 20, 30, 40, 50};
int *ptr = numbers; // Zeigt auf das erste Element (10)
ptr++; // Zeigt nun auf das zweite Element (20)
ptr++; // Zeigt nun auf das dritte Element (30)Diese automatische Größenberechnung macht die Zeigerarithmetik so leistungsfähig und praktisch. Sie müssen sich nicht um Byte-Berechnungen kümmern – C übernimmt die Speicheradressierung für Sie basierend auf dem Datentyp des Zeigers.
Zeigerarithmetik ist besonders nützlich für das Durchlaufen von Arrays in Schleifen. Anstatt Array-Indizes zu verwenden, können Sie einen Zeiger inkrementieren, um sich sequenziell durch jedes Element zu bewegen, was oft zu effizienterem Code führt.
Aufgabe
EinfachSchreiben Sie ein C-Programm, das Zeigerarithmetik demonstriert, indem es Zeiger-Inkrement-Operationen verwendet, um ein Array zu durchlaufen und zu verarbeiten. Ihr Programm sollte:
- Ein Integer-Array namens
datamit 5 Elementen deklarieren und es mit den Werten {12, 24, 36, 48, 60} initialisieren - Einen Zeiger auf einen Integer namens
ptrdeklarieren und ihn so initialisieren, dass er auf das erste Element des Arrays zeigt - Eine for-Schleife verwenden, die 5 Mal durchläuft, um das gesamte Array ausschließlich mittels Zeigerarithmetik zu traversieren
- Innerhalb der Schleife:
- Den aktuellen Wert ausgeben, auf den
ptrzeigt, unter Verwendung des Dereferenzierungsoperators - Die in
ptrgespeicherte Speicheradresse unter Verwendung des Formatbezeichners%pausgeben - Den Zeiger mittels
ptr++inkrementieren, um zum nächsten Element zu springen
- Den aktuellen Wert ausgeben, auf den
- Nach der Schleife
ptrzurücksetzen, sodass er wieder auf das erste Element des Arrays zeigt - Zeigerarithmetik verwenden, um direkt auf das dritte Element (Index 2) mittels
*(ptr + 2)zuzugreifen und es auszugeben - Zeigerarithmetik verwenden, um direkt auf das letzte Element (Index 4) mittels
*(ptr + 4)zuzugreifen und es auszugeben
Ihre Ausgabe sollte die Ergebnisse im folgenden Format anzeigen:
Value: 12, Address: [address]
Value: 24, Address: [address]
Value: 36, Address: [address]
Value: 48, Address: [address]
Value: 60, Address: [address]
Third element: 36
Last element: 60Diese Herausforderung testet Ihr Verständnis dafür, wie Zeiger-Inkrement-Operationen automatisch um die Größe des Datentyps verschoben werden und wie Sie Zeigerarithmetik verwenden können, um auf Array-Elemente an bestimmten Offsets von einer Basis-Zeigerposition aus zuzugreifen.
Spickzettel
Zeigerarithmetik ermöglicht es Ihnen, Zeiger mithilfe von Inkrement- und Dekrement-Operationen durch den Speicher zu bewegen. Wenn Sie einen Zeiger inkrementieren, bewegt er sich um die Größe des Datentyps, auf den er zeigt, nicht um ein Byte.
Grundlegende Operationen der Zeigerarithmetik:
int numbers[5] = {10, 20, 30, 40, 50};
int *ptr = numbers; // Zeigt auf das erste Element (10)
ptr++; // Zeigt nun auf das zweite Element (20)
ptr++; // Zeigt nun auf das dritte Element (30)Sie können Zeigerarithmetik auch verwenden, um auf Elemente an bestimmten Offsets zuzugreifen:
*(ptr + 2) // Zugriff auf das Element an Offset 2 von der aktuellen PositionZeigerarithmetik ist nützlich, um Arrays in Schleifen zu durchlaufen, was oft zu effizienterem Code führt als die Verwendung von Array-Indizes.
Probier es selbst
#include <stdio.h>
int main() {
// TODO: Schreiben Sie hier Ihren Code
// Deklarieren und initialisieren Sie das Array 'data' mit den Werten {12, 24, 36, 48, 60}
// Deklarieren Sie den Zeiger 'ptr' und initialisieren Sie ihn so, dass er auf das erste Element zeigt
// Verwenden Sie eine for-Schleife mit Zeigerarithmetik, um das Array zu durchlaufen
// Geben Sie jeden Wert und jede Adresse aus und inkrementieren Sie dann den Zeiger
// Setzen Sie den Zeiger zurück und verwenden Sie Zeigerarithmetik, um auf bestimmte Elemente zuzugreifen
return 0;
}Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Logic & Flow
1Zeiger-Grundlagen
Was ist ein Zeiger?Zeiger deklarierenDer Adressoperator (&)Der Dereferenzierungsoperator (*)NULL-ZeigerZusammenfassung: Zeiger-Grundlagen4Projekt: Einfaches Text-Tool
ProjektübersichtZeichen zählen2Pointer und Arrays
Array-Namen als PointerArray-Elemente - PointerPointer-ArithmetikPointer vergleichenWiederholung: Array-Durchlauf mit Pointern5Zeiger und Funktionen
Wertübergabe (Pass-by-Value)Zeiger an Funktionen übergebenVariablen über Zeiger ändernEin klassisches Beispiel: SwapArrays an Funktionen übergebenZusammenfassung: Zeiger als Funktionsargumente8Structs und Zeiger
Zeiger auf StructsDer Pfeiloperator (->)Structs per Wert übergebenÜbergabe von Struct-ZeigernDynamische Allokation von StructsZusammenfassung: Struct ändern - Ptr11Finale Wiederholungsaufgaben
Wiederholung: Dynamische String-KonkatenationWiederholung: Array von StructsWiederholung: Wortfrequenz-Zähler3Character-Arrays und Strings
Strings als char-ArraysDer Null-TerminatorString-Eingabe mit scanfVerwendung von strlen()Verwendung von strcpy()Verwendung von strcat()Verwendung von strcmp()Zusammenfassung: Grundlegende String-Funktionen