Ein Iterator in C++ ist ein zeigerähnliches Objekt, das auf ein Element des STL-Containers zeigt. Sie werden im Allgemeinen verwendet, um den Inhalt des STL-Containers in C++ zu durchlaufen. Der Hauptvorteil von STL-Iteratoren besteht darin, dass sie die STL-Algorithmen unabhängig vom Typ des verwendeten Containers machen. Wir können einfach den Iterator an die Containerelemente übergeben, anstatt den Container selbst an die STL-Algorithmen.
Iterator-Deklaration
Jeder Container in C++ STL verfügt über einen eigenen Iterator. Also müssen wir einen Iterator wie folgt deklarieren:
C++
<type>::iterator it;
Wo
- Typ: Typ des Containers, für den der Iterator deklariert ist.
- Es: Dem Iteratorobjekt zugewiesener Name.
Wir können es dann initialisieren, indem wir einen gültigen Iterator zuweisen. Wenn wir zum Zeitpunkt der Deklaration bereits einen Iterator zuweisen möchten, können wir die Typdeklaration mit überspringen Auto Stichwort.
C++auto it = iter
Wo iter ist der Iterator, der dem neu erstellten It-Iterator zugewiesen ist.
Unser C++-Kurs behandelt die Verwendung von Iteratoren in der STL und stellt sicher, dass Sie verstehen, wie Sie verschiedene Containertypen durchlaufen.
Beispiel für Iteratoren
Das folgende Programm veranschaulicht, wie der Iterator zum Durchlaufen des Vektorcontainers verwendet wird:
C++#include using namespace std; int main() { vector<int> v = {1 2 3 4 5}; // Defining an iterator pointing to // the beginning of the vector vector<int>::iterator first = v.begin(); // Defining an iterator pointing // to the end of the vector vector<int>::iterator last = v.end(); // Iterating the whole vector while(first != last) { cout << *first << ' '; first++; } return 0; }
Ausgabe
1 2 3 4 5
Wie Sie vielleicht bemerkt haben, haben wir verwendet vector::begin() und vector::end() Funktion. Diese Funktionen sind die Mitgliedsfunktionen von std::vector, die den Iterator zum ersten und ein Element nach dem letzten Element des Vektors zurückgeben. Wir verwenden die Iteratoren return be dieser Funktionen, um die Vektoren zu iterieren.
Container-Iterator-Funktionen
C++ STL bietet einige Mitgliedsfunktionen in STL-Container die die Iteratoren mindestens zum ersten und letzten Element zurückgeben. Diese Mitgliedsfunktionen sind in fast allen STL-Containern definiert (wobei einige Container mit eingeschränktem Zugriff übrig bleiben, z Stapel Warteschlange ) mit demselben Namen aus Gründen der Konsistenz.
Die folgende Tabelle listet alle Methoden auf, die den Iterator an die Container zurückgeben:
Iteratorfunktion | Rückgabewert |
|---|---|
beginnen() | Gibt einen Iterator an den Anfang des Containers zurück. |
Ende() | Gibt einen Iterator zum theoretischen Element direkt nach dem letzten Element des Containers zurück. |
cbegin() | Gibt einen konstanten Iterator an den Anfang des Containers zurück. Ein konstanter Iterator kann den Wert des Elements, auf das er zeigt, nicht ändern. |
ein paar() Algorithmus für RSA | Gibt einen konstanten Iterator zum theoretischen Element direkt nach dem letzten Element des Containers zurück. |
rbegin() | Gibt einen umgekehrten Iterator zum Anfang des Containers zurück. |
machen() | Gibt einen umgekehrten Iterator zum theoretischen Element direkt nach dem letzten Element des Containers zurück. |
crbegin() | Gibt einen konstanten Reverse-Iterator zum Anfang des Containers zurück. |
CREND () | Gibt einen konstanten umgekehrten Iterator zum theoretischen Element direkt nach dem letzten Element des Containers zurück. |
Zum Beispiel wenn eine Sache ist der Name des Vektors, dann können wir die oben genannten Methoden wie unten gezeigt verwenden:
C++vec.begin() vec.rbegin() vec.cbegin() vec.crbegin() vec.end() vec.rend() vec.cend() vec.crend()
Iteratoroperationen
Genau wie bei der Zeigerarithmetik gibt es einige Operationen, die für C++-Iteratoren zulässig sind. Sie werden verwendet, um verschiedene Funktionalitäten bereitzustellen, was die Bedeutung von Iteratoren erhöht. Es sind 5 gültig Iteratoroperationen in C++ :
- Dereferenzierung von Iteratoren
- Inkrementierende/dekrementierende Iteratoren
- Addieren/Subtrahieren von Ganzzahlen zu Iteratoren
- Einen anderen Iterator subtrahieren
- Vergleich von Iteratoren
Dereferenzierung von Iteratoren
Der Dereferenzierungsvorgang ermöglicht es den Benutzern Zugriff oder Aktualisierung der Wert des Elements, auf das der Iterator zeigt. Wir nutzen die (*) Indirektionsoperator um Iteratoren genau wie Zeiger zu dereferenzieren.
C++// Access *it; // Update *it = new_val;
Wo neuer_Wert ist der neue Wert, der dem Element zugewiesen wird, auf das der Iterator zeigt Es .
Inkrementierende/dekrementierende Iteratoren
Wir können den Iterator mit um 1 erhöhen oder dekrementieren (++) oder (--) Operatoren jeweils. Die Inkrementierungsoperation verschiebt den Iterator zum nächsten Element im Container, während die Dekrementierungsoperation den Iterator zum vorherigen Element verschiebt.
C++it++; // post-increment ++it; // pre-increment it--; // post-decrement --it; // pre-decrement
Addieren/Subtrahieren von Ganzzahlen zu Iteratoren
Wir können den Iteratoren auch einen ganzzahligen Wert hinzufügen oder davon subtrahieren. Je nach hinzugefügtem Ganzzahlwert wird der Iterator an die nächste oder vorherige Position verschoben.
C++// Addition it + int_val; // Subtraction it - int_val;
Wo int_val ist der ganzzahlige Wert, der vom Iterator addiert oder subtrahiert wird Es .
Einen anderen Iterator subtrahieren
Wir können einen Iterator von einem anderen subtrahieren, um den Abstand (oder die Anzahl der Elemente) zwischen dem Speicher zu ermitteln, auf den sie zeigen.
C++it1 - it2
Vergleich von Iteratoren
Wir können auch die beiden Iteratoren desselben Typs gegeneinander testen, um die Beziehung zwischen ihnen herauszufinden. Wir können die relationalen Operatoren wie (==) Gleichheits- und (!=) Ungleichheitsoperatoren zusammen mit anderen relationalen Operatoren wie verwenden< > <= >=.
C++it1 != it2 // Equal to it1 == it2 // Not equal to it1 > it2 // Greater than it1 < it2 // Less than it1 >= it2 // Greater than equal to it1 <= it2 // Less than equal to
Arten von Iteratoren in C++
STL-Iteratoren können anhand der Operationen, die auf ihnen ausgeführt werden können, unterteilt werden. In C++ gibt es fünf Haupttypen von Iteratoren, die in der folgenden Tabelle zusammen mit unterstützten Containern und unterstützten Iteratoroperationen aufgeführt sind.
Iterator | Beschreibung | Unterstützte Container | Unterstützte Operationen |
|---|---|---|---|
Eingabe-Iterator | Es handelt sich um einen Einweg-Iterator, der zum Lesen der Werte verwendet wird. | Eingabestream | Dereferenzierung der Inkrementgleichheit |
Ausgabe-Iterator | Es handelt sich ebenfalls um einen Einweg-Iterator, der jedoch zum Zuweisen der Werte verwendet wird. Es kann nicht auf die Werte zugegriffen werden. | Ausgabestream | Dereferenzierung (nur Schreiben) Inkrementieren |
Forward-Iteratoren | Es kann auf die Werte zugreifen und diese auch zuweisen. Es ist die Kombination aus Eingabe- und Ausgabeiterator. | Forward_list unordered_map unordered_set | Dereferenzierung der Inkrementgleichheit |
Bidirektionale Iteratoren | Es kann sich in beide Richtungen vorwärts oder rückwärts bewegen. Die Container wie List Set und Multimap unterstützen bidirektionale Iteratoren. | Listen Sie den Kartensatz Multimap Multiset auf | Dereferenzierung der Inkrement-/Dekrement-Gleichheit |
Iteratoren mit wahlfreiem Zugriff | Iteratoren mit wahlfreiem Zugriff sind Iteratoren, die verwendet werden können, um auf Elemente in einer Entfernung von dem Element zuzugreifen, auf das sie zeigen, und die dieselbe Funktionalität wie Zeiger bieten. | Vektor-Deque-Array-String Operatoren in der Python-Programmierung | Alle |
Wie wir vielleicht anhand der obigen Tabelle bemerkt haben, abgesehen von den Eingabe- und Ausgabeiteratoren Wenn wir die Tabelle durchgehen, enthält der Iteratortyp die Funktionen des oben genannten Iterators sowie einige neue Funktionen.
Iterator-Adapter
Iteratoradapter in C++ sind spezielle Iteratortypen, die über herkömmlichen Iteratoren aufgebaut sind, um spezielle Funktionen bereitzustellen. Es gibt viele Iterator-Adapter in C++, von denen einige unten aufgeführt sind:
Iterator-Adaptertyp | Beschreibung |
|---|---|
Reverse-Iterator | Der umgekehrte Iterator basiert auf einem bidirektionalen oder höheren Operatortyp und ermöglicht es Benutzern, den Container in umgekehrter Richtung zu durchlaufen. |
Stream-Iteratoren | Die Stream-Iteratoren, nämlich istream- und ostream-Iteratoren, basieren auf den Eingabe- bzw. Ausgabe-Iteratoren. Diese Iteratoren ermöglichen es den Benutzern, die Streams als Container zu verwenden. |
Iteratoren verschieben | Move-Iteratoren werden verwendet, um die Move-Semantik in STL-Algorithmen einzuführen. Die Verschiebungsiteratoren verschieben den Besitz der kopierten Containerdaten auf den Kopiercontainer, ohne zusätzliche Kopien zu erstellen. |
Inserter-Iterator | Mit den Insertor-Iteratoren können Sie die angegebenen Elemente an einer bestimmten Position im Container einfügen. In C++ gibt es drei Insertor-Iteratoren:
Diese Iteratoren können mit erstellt werden back_inserter() front_inserter() einfügen() Funktionen in C++. |
Iterator-Dienstprogrammfunktionen in C++
C++ STL bietet verschiedene Funktionen, um die Arbeit mit Iteratoren zu vereinfachen. Sie sind in der folgenden Tabelle aufgeführt:
| Funktion | Beschreibung | Syntax |
|---|---|---|
| std::advance | Verschiebt einen Iterator um eine bestimmte Anzahl von Positionen. | Vorauszahlung ( es n ) |
| std::next | Gibt den Iterator zurück, der eine angegebene Anzahl von Positionen vor dem angegebenen Iterator liegt. | nächste ( es n ) |
| Std :: Vorher | Gibt den Iterator zurück, der eine angegebene Anzahl von Positionen hinter dem angegebenen Iterator liegt. | vorh ( es n ) |
| std::distanz | Gibt die Anzahl der Elemente zwischen zwei Iteratoren zurück. | Distanz ( it1 it2 ) |
| std::begin | Gibt einen Iterator zum ersten Element des angegebenen Containers zurück. | beginnen ( Container ) |
| std::end | Gibt einen Iterator für das Element zurück, das auf das letzte Element des angegebenen Containers folgt. | Ende ( Container ) |
| std::rbegin | Gibt einen umgekehrten Iterator zum letzten Element des angegebenen Containers zurück. | rbeginnen ( Container ) |
| std::rend | Gibt einen umgekehrten Iterator zu dem Element zurück, das dem ersten Element des angegebenen Containers vorangeht. | macht ( Container ) |
| std::inserter | Erstellt einen Einfüge-Iterator, der Elemente an einer angegebenen Position in einen Container einfügt. | Einfügemaschine ( Behälterposition ) |
| std::back_inserter | Erstellt einen Back-Insert-Iterator, der Elemente an das Ende eines Containers anhängt. | back_inserter ( Container ) |
| std::front_inserter | Erstellt einen Front-Insert-Iterator, der Elemente an der Vorderseite eines Containers einfügt. | front_inserter ( Container ) |
Anwendungen von Iteratoren mit Beispielen
Iteratoren werden in C++ häufig für viele verschiedene Zwecke bei der Arbeit mit STL-Containern und -Algorithmen verwendet. Im Folgenden sind einige Hauptanwendungen von Iteratoren in C++ mit ihren Codebeispielen aufgeführt:
Durchqueren von Containern
Das Durchlaufen von STL-Containern ist die grundlegendste Anwendung von Iteratoren. Hier verwenden wir die Funktionen begin() und end(), um die Anfangs- und End-Iteratoren dazu zu bringen, den gesamten Container zu durchlaufen. Grundsätzlich erhöhen wir den Anfangsiterator so lange, bis er nicht mehr dem Ende entspricht.
Beispiel
C++#include using namespace std; int main() { set<int> s = {10 20 30 40 50}; // Iterator to the beginning // of the set auto it = s.begin(); // Iterating through the // entire set while (it != s.end()) { // Dereferencing iterator // to access value cout << *it << ' '; // Incrementing the // iterator it++; } return 0; }
Ausgabe
10 20 30 40 50
Wie im obigen Code gezeigt, durchlaufen wir den Set-Container. Ebenso können wir den gleichen Ansatz verwenden, um jeden Container zu durchlaufen.
Einen Container umkehren
Mit Reverse-Iteratoren können Sie einen Container vom Ende zum Anfang durchlaufen, ohne die Umkehrung manuell durchführen zu müssen.
Beispiel
C++#include using namespace std; int main() { vector<int> vec = {10 20 30 40 50}; // Defining reverse iterators // pointing to the reverse // beginning of vec auto it = vec.rbegin(); // Iterating the whole // vector in reverse while (it != vec.rend()) { cout << *it << ' '; it++; } return 0; }
Ausgabe
50 40 30 20 10
Containerunabhängige Algorithmen
Iteratoren ermöglichen es Algorithmen, mit jedem Containertyp zu arbeiten, wodurch Funktionen wie std::sort(), std::find() und std::for_each() flexibler werden. Sie können Iteratoren anstelle des eigentlichen Containers übergeben.
Beispiel
C++#include using namespace std; int main() { vector<int> vec = {30 10 40 10 50}; multiset<int> ms = {10 30 10 20 40 10}; // Using the std::count() algorithm to count // the number of occurences of 10 in vector // and multiset using iterator cout << '10s in Vector: ' << count(vec.begin() vec.end() 10) << endl; cout << '10s in Multiset: ' << count(ms.begin() ms.end() 10); return 0; }
Ausgabe
10s in Vector: 2 10s in Multiset: 3
Zusätzliche Anwendungen von Iteratoren
Es gibt weitere Anwendungen von STL-Iteratoren:
- Entfernungsberechnung: Die Verwendung von std::distance()-Iteratoren hilft bei der Berechnung der Anzahl der Elemente zwischen zwei Positionen in einem Container.
- Stream-Iteration: Stream-Iteratoren ermöglichen es Ihnen, Eingabe-/Ausgabe-Streams wie Container zu behandeln, was das Lesen aus und Schreiben in Streams mithilfe von STL-Algorithmen erleichtert.
- Bewegungssemantik in STL-Algorithmen: Move-Iteratoren führen die Move-Semantik in STL-Algorithmen ein, was zur Steigerung der Leistung und Effizienz beiträgt, indem unnötiges Kopieren vermieden wird. Die Daten werden gemäß den Regeln der Verschiebungssemantik verschoben.
- Benutzerdefinierte Iteratoren für Datenstrukturen: Benutzerdefinierte Iteratoren können für Nicht-STL-Datenstrukturen wie Bäume oder Diagramme implementiert werden, um die Unterstützung für STL-Algorithmen und viele andere Funktionen bereitzustellen. Möglicherweise müssen wir einige Regeln und Konventionen befolgen, um ordnungsgemäße Inkrementierungs-, Dekrementierungs- und andere Vorgänge bereitzustellen.