Iteratoren und gültige Bereiche
Ein Iterator ist ein Objekt, mit dem du eine Position in einer Sammlung beschreibst. begin() zeigt auf das erste Element oder bei leerer Sammlung direkt auf das Ende. end() bezeichnet die Position hinter dem letzten Element. Diese Endposition darfst du vergleichen, aber nicht als Element lesen.
Iteratoren und gültige Bereiche#
Daten sammeln und verarbeiten · Lektion 30 von 60
Voraussetzungen: Vector, Maps. Lernziel: Du erkennst Anfang, Ende und ungültig gewordene Positionen.
Ein Iterator ist ein Objekt, mit dem du eine Position in einer Sammlung beschreibst. begin() zeigt auf das erste Element oder bei leerer Sammlung direkt auf das Ende. end() bezeichnet die Position hinter dem letzten Element. Diese Endposition darfst du vergleichen, aber nicht als Element lesen.
1#include <iostream>2#include <vector>3 4int main() {5 std::vector<int> werte{2, 4, 6};6 for (auto it = werte.begin(); it != werte.end(); ++it) {7 std::cout << *it << '\n';8 }9}*it ist das Dereferenzieren des Iterators: Du greifst auf das Element an seiner Position zu. ++it bewegt ihn weiter. it ist eine verbreitete Kurzform für Iterator; bei komplexerem Code darf der Name genauer sein.
Halboffene Bereiche#
Viele Standardalgorithmen verwenden ein Paar [anfang, ende). Diese mathematische Notation bedeutet: Anfang gehört dazu, Ende nicht. Der Bereich heißt halboffen. Bei anfang == ende ist er leer. Dieselbe Darstellung funktioniert für leere und nichtleere Sammlungen ohne Sonder-Endelement.
Begin und End müssen zum selben gültigen Bereich gehören. Iteratoren aus zwei verschiedenen Vektoren bilden auch dann keinen Bereich, wenn ihre Werte zufällig ähnlich aussehen.
Nicht jeder Iterator kann alles#
Ein Vector unterstützt Iteratoren mit direktem Positionsspringen wie it + 2. Ein Map-Iterator unterstützt diese Addition nicht. Iteratorkategorien beschreiben solche Fähigkeiten, etwa vorwärts gehen, rückwärts gehen oder beliebig springen. Algorithmen stellen Anforderungen an diese Fähigkeiten.
Ungültigkeit durch Änderungen#
Invalidierung bedeutet, dass ein vorher brauchbarer Iterator nicht mehr verwendet werden darf. Eine Reallokation des Vectors invalidiert alle Iteratoren auf seine bisherigen Elemente. Löschen verändert ebenfalls die Gültigkeit betroffener Positionen.
Wenn du während des Durchlaufens Elemente entfernst, beachte den Rückgabewert von erase: Bei Vector und vielen anderen Containern erhältst du damit eine passende nächste Position. Nicht blind nach dem Löschen noch den alten Iterator erhöhen. Eine Bereichsschleife eignet sich nicht automatisch zum gleichzeitigen strukturellen Umbauen ihrer Sammlung.
Übung#
Warum ist *werte.end() falsch, selbst wenn der Vector nicht leer ist?
Lösung
end() bezeichnet ausdrücklich kein vorhandenes Element. Die Position hinter dem Ende ist nur für Grenzvergleiche da. Das letzte Element erreichst du etwa mit back(), nachdem du auf Nichtleere geprüft hast.
Weiterlernen#
Zurück: Schlüssel, Werte und Mengen: map und set · Kursübersicht · Weiter: Standardalgorithmen statt selbst gebauter Schleifen
Kommentare 0
Kommentare sind für diese Seite deaktiviert.