Iterator-Muster
Teil des Abschnitts Objektorientierte Programmierung der C-Journey von Coddy. Lektion 56 von 61.
Das Iterator-Muster bietet eine Möglichkeit, sequenziell auf Elemente einer Sammlung zuzugreifen, ohne ihre zugrunde liegende Struktur offenzulegen. Anstatt Benutzern direkten Zugriff auf ein Array zu geben, gibst du ihnen ein Objekt, das weiß, wie es die Daten Element für Element durchläuft.
Ein Iterator benötigt typischerweise zwei Informationen: eine Referenz auf die Sammlung und die aktuelle Position. In C erstellen wir eine Struktur, um diesen Zustand zu speichern:
typedef struct {
int* data; // Zeiger auf das Array
int size; // Gesamtzahl der Elemente
int current; // aktuelle Position
} IntIterator;Der Iterator stellt zwei wichtige Funktionen bereit. has_next() prüft, ob noch weitere Elemente zu lesen sind, und next() gibt das aktuelle Element zurück und rückt die Position vor:
int has_next(IntIterator* it) {
return it->current < it->size;
}
int next(IntIterator* it) {
return it->data[it->current++];
}Die Verwendung des Iterators sieht übersichtlich aus und verbirgt die Details des Arrays:
IntIterator it = create_iterator(numbers, 5);
while (has_next(&it)) {
printf("%d\n", next(&it));
}Der Aufrufer muss nie wissen, dass numbers ein Array ist oder wie die Indizierung funktioniert. Diese Abstraktion macht es einfach, die zugrunde liegende Datenstruktur später beispielsweise von einem Array in eine verkettete Liste zu ändern, ohne den Code zu ändern, der den Iterator verwendet.
Aufgabe
EinfachErstellen wir einen NumberList-Iterator: eine klare Abstraktion, mit der du eine Sammlung von Ganzzahlen durchlaufen kannst, ohne die zugrunde liegende Array-Struktur offenzulegen.
Du organisierst deinen Code über drei Dateien:
iterator.h: Definiere eineIntIterator-Struktur, die einen Zeiger auf ein Ganzzahl-Array, die Gesamtgröße der Sammlung und die aktuelle Position enthält. Deklariere drei Funktionen:create_iterator(nimmt einen Array-Zeiger und die Größe entgegen und gibt einen initialisierten Iterator zurück),has_next(prüft, ob weitere Elemente vorhanden sind) undnext(gibt das aktuelle Element zurück und rückt die Position vor). Vergiss die Include-Guards nicht!iterator.c: Implementiere deine Iteratorfunktionen. Die Funktioncreate_iteratorsollte einenIntIteratorals Wert zurückgeben, wobei die aktuelle Position auf 0 gesetzt ist. Die Funktionhas_nextgibt 1 zurück, wenn weitere Elemente gelesen werden können, andernfalls 0. Die Funktionnextgibt das Element an der aktuellen Position zurück und erhöht anschließend die Position.main.c: Lies die Anzahl der Elemente ein und lies anschließend jeden Ganzzahlwert in ein Array ein. Erstelle einen Iterator für dieses Array und verwende dann eine while-Schleife mithas_nextundnext, um jedes Element zu durchlaufen und in einer eigenen Zeile auszugeben.
Dein Programm erhält:
- Die Anzahl der Elemente im Array
- Jeden Ganzzahlwert in einer eigenen Zeile
Verwende das Iterator-Muster, um alle Elemente auszugeben: keine direkte Array-Indizierung in deiner Durchlaufschleife!
Beispielausgabe bei den Eingaben 4, dann 10, 20, 30, 40:
10
20
30
40Beispielausgabe bei den Eingaben 3, dann -5, 0, 100:
-5
0
100Beispielausgabe bei den Eingaben 1, dann 42:
42Der Iterator verbirgt, wie die Daten gespeichert werden. Deine Hauptschleife fragt einfach „gibt es weitere?“ und „gib mir das nächste“, ohne etwas über Array-Indizes oder das Speicherlayout wissen zu müssen.
Probier es selbst
#include <stdio.h>
#include "iterator.h"
int main() {
int n;
scanf("%d", &n);
int arr[n];
// TODO: Lese n Ganzzahlwerte in das Array ein
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
// TODO: Erstelle einen Iterator für das Array
// TODO: Verwende eine while-Schleife mit has_next und next zum Durchlaufen
// und gib jedes Element in einer eigenen Zeile aus
// Verwende KEINE direkte Array-Indizierung in deiner Durchlaufschleife!
return 0;
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der modularen Programmierung
Header-DateienInclude GuardsQuelldateienStatische FunktionenWiederholung: Modularer Taschenrechner4Kapselung
Konzept der Opaque PointersOpaque Structs definierenGetter und SetterValidierung in SetternRückblick: Die geheime Box2Objekte und Methoden
Structs als ObjekteDer 'Self'-PointerConst-CorrectnessPointer vs. WertHilfsmethodenZusammenfassung: Point Manager5Projekt: Einfaches Bankkonto
Projekt-SetupImplementierung des Kontos3Objekt-Lebenszyklus
Konstruktor-MusterDestruktor-MusterStack-InitialisierungTiefe KopieRückblick: String-Wrapper6Vererbung durch Komposition
Struct-EinbettungDie First-Member-RegelZugriff auf Parent-MemberUpcastingRückblick: Formenhierarchie9Projekt: Formen-Zeichner
ProjektübersichtKreis-ImplementierungRechteck-ImplementierungPolymorphe VerwendungShape-ContainerÜbe selbstständig: Online-C-Compiler