HOWTO · C++

Durchlaufen einer Liste in C++

Dies ist ein einfaches Tutorial über die List-Datenstruktur und wie wir die List-Datenstruktur in C++ durchlaufen können.

Auf dieser Seite

Um eine std::list in C++ zu durchlaufen, initialisieren Sie einen Iterator mit begin(), fahren Sie fort, solange er nicht end() entspricht, und erhöhen Sie ihn nach der Verarbeitung jedes Elements. Dereferenzieren Sie den Iterator, um den aktuellen Wert zu lesen oder zu ändern. Die Schleife endet vor end(): Dieser Wert markiert die Position hinter dem letzten Element und ist kein Iterator auf das letzte Element.

Was ist std::list in C++?

std::list ist der doppelt verkettete Listencontainer der C++-Standardbibliothek. Seine Elemente liegen in Knoten, die mit ihren benachbarten Knoten verknüpft sind. Daher befinden sie sich nicht wie die Elemente eines std::vector oder eines Arrays in einem zusammenhängenden Speicherbereich. Diese Struktur ermöglicht das Durchlaufen in beide Richtungen. An einer Position können Elemente in konstanter Zeit eingefügt oder entfernt werden, sofern Sie bereits einen Iterator auf diese Position haben.

Eine Liste bietet keinen direkten Indexzugriff wie items[4]. Um ein Element an einer bestimmten Position zu erreichen, muss ein Iterator durch die Liste bewegt werden; der Zeitaufwand hängt von der zurückgelegten Strecke ab. Außerdem benötigt jedes Element zusätzlich zu seinem Wert Speicher für die Verknüpfungen. Wählen Sie std::list, wenn stabile Iteratoren sowie das Einfügen oder Entfernen an bekannten Positionen wichtig sind. Ein Vektor ist oft einfacher, wenn Sie kompakten Speicher oder häufigen Zugriff über Indizes benötigen.

C++ bietet außerdem std::forward_list, einen separaten einfach verketteten Container, der nur das Durchlaufen in Vorwärtsrichtung unterstützt. Er ist nicht derselbe Container wie std::list. Weitere Hintergrundinformationen finden Sie im Artikel über doppelt verkettete Listen.

So durchlaufen Sie eine std::list in C++

Der von begin() zurückgegebene Iterator verweist auf das erste Element. end() bezeichnet die Position direkt hinter dem letzten Element. Deshalb dient dieser Wert als Abbruchbedingung der Schleife und darf nicht dereferenziert werden. Durch Erhöhen des Iterators gelangen Sie zum nächsten Element.

Führen Sie dieses Beispiel aus:

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

#include <iostream>
#include <list>

int main() {
    std::list<int> scores{12, 18, 25};

    for (std::list<int>::iterator it = scores.begin(); it != scores.end(); ++it) {
        std::cout << *it << '\n';
    }
}
12
18
25

Hier beginnt it bei scores.begin(). Bei jedem Schleifendurchlauf wird der aktuelle Wert mit *it gelesen; anschließend bewegt ++it den Iterator zum nächsten Knoten. Sobald der Iterator scores.end() erreicht, ist die Bedingung falsch und die Schleife endet, ohne auf die Position hinter dem letzten Element zuzugreifen.

Über einen nicht konstanten Iterator können Sie ein Element ändern, indem Sie *it einen neuen Wert zuweisen. Beispielsweise erhöht *it += 1; im Schleifenrumpf den aktuellen Wert. Wenn Sie Werte nur besuchen möchten, verwenden Sie eine bereichsbasierte for-Schleife: for (int score : scores). Um Werte auf diese Weise zu ändern, binden Sie jedes Element als Referenz: for (int& score : scores). Verwenden Sie die Schleife mit explizitem Iterator, wenn Sie den Iterator selbst benötigen, etwa um das aktuelle Element zu entfernen.

Beim Löschen während des Durchlaufens weisen Sie den von erase zurückgegebenen Iterator zu, damit die Schleife beim nächsten Element fortfahren kann. Das Löschen macht den Iterator auf das entfernte Element ungültig; Iteratoren auf andere Elemente der std::list bleiben gültig.