UN iteratore in C++ è un oggetto simile a un puntatore che punta a un elemento del contenitore STL. Vengono generalmente utilizzati per scorrere il contenuto del contenitore STL in C++. Il vantaggio principale degli iteratori STL è che rendono gli algoritmi STL indipendenti dal tipo di contenitore utilizzato. Possiamo semplicemente passare l'iteratore agli elementi contenitore invece del contenitore stesso agli algoritmi STL.
Dichiarazione dell'iteratore
Ogni contenitore in C++ STL ha il proprio iteratore. Quindi dobbiamo dichiarare un iteratore come:
C++
<type>::iterator it;
Dove
- tipo: Tipo di contenitore per il quale viene dichiarato l'iteratore.
- Esso: Nome assegnato all'oggetto iteratore.
Possiamo quindi inizializzarlo assegnando un iteratore valido. Se abbiamo già un iteratore da assegnare al momento della dichiarazione allora possiamo saltare la dichiarazione del tipo usando il file auto parola chiave.
C++auto it = iter
Dove iter è l'iteratore assegnato all'iteratore appena creato.
Nostro Corso C++ copre l'uso degli iteratori nell'STL assicurandoti di comprendere come attraversare diversi tipi di contenitori.
Esempio di iteratori
Il programma seguente illustra come utilizzare l'iteratore per attraversare il contenitore vettoriale:
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; }
Produzione
1 2 3 4 5
Come avrai notato, abbiamo utilizzato vettore::begin() e vettore::end() funzione. Queste funzioni sono le funzioni membro di std::vettore che restituiscono l'iteratore al primo e un elemento dopo l'ultimo elemento del vettore. Usiamo gli iteratori restituiti da queste funzioni per iterare i vettori.
Funzioni dell'iteratore contenitore
C++ STL fornisce alcune funzioni membro in Contenitore STL che restituiscono gli iteratori almeno al primo e all'ultimo elemento. Queste funzioni membro sono definite in quasi tutto il contenitore STL (lasciando alcuni contenitori ad accesso limitato come pila coda ) con lo stesso nome per coerenza.
La tabella seguente elenca tutti i metodi che restituiscono l'iteratore ai contenitori:
Funzione iteratore | Valore restituito |
|---|---|
inizio() | Restituisce un iteratore all'inizio del contenitore. |
FINE() | Restituisce un iteratore all'elemento teorico subito dopo l'ultimo elemento del contenitore. |
cbegin() | Restituisce un iteratore costante all'inizio del contenitore. Un iteratore costante non può modificare il valore dell'elemento a cui punta. |
alcuni() come stampare java | Restituisce un iteratore costante all'elemento teorico subito dopo l'ultimo elemento del contenitore. |
rbegin() | Restituisce un iteratore inverso all'inizio del contenitore. |
rendere() | Restituisce un iteratore inverso all'elemento teorico subito dopo l'ultimo elemento del contenitore. |
crbegin() | Restituisce un iteratore inverso costante all'inizio del contenitore. |
CREDO () | Restituisce un iteratore inverso costante all'elemento teorico subito dopo l'ultimo elemento del contenitore. |
Ad esempio se una cosa è il nome del vettore, possiamo utilizzare i metodi sopra indicati come mostrato di seguito:
C++vec.begin() vec.rbegin() vec.cbegin() vec.crbegin() vec.end() vec.rend() vec.cend() vec.crend()
Operazioni sugli iteratori
Proprio come l'aritmetica dei puntatori, ci sono alcune operazioni consentite sugli iteratori C++. Vengono utilizzati per fornire diverse funzionalità che aumentano l'importanza degli iteratori. Ce ne sono 5 validi operazioni degli iteratori in C++ :
- Dereferenziazione degli iteratori
- Iteratori di incremento/decremento
- Aggiunta/sottrazione di numeri interi agli iteratori
- Sottrazione di un altro iteratore
- Confronto tra iteratori
Dereferenziazione degli iteratori
L'operazione di dereferenziazione consente agli utenti di farlo accedere o aggiornare il valore dell'elemento puntato dall'iteratore. Usiamo il (*) operatore indiretto per dereferenziare gli iteratori proprio come i puntatori.
C++// Access *it; // Update *it = new_val;
Dove nuova_val è il nuovo valore assegnato all'elemento puntato dall'iteratore Esso .
Iteratori di incremento/decremento
Possiamo incrementare o decrementare l'iteratore di 1 utilizzando (++) o (--) operatori rispettivamente. L'operazione di incremento sposta l'iteratore sull'elemento successivo nel contenitore mentre l'operazione di decremento sposta l'iteratore sull'elemento precedente.
C++it++; // post-increment ++it; // pre-increment it--; // post-decrement --it; // pre-decrement
Aggiunta/sottrazione di numeri interi agli iteratori
Possiamo anche aggiungere o sottrarre un valore intero dagli iteratori. Aggiungerà la posizione successiva o precedente dell'iteratore in base al valore intero aggiunto.
C++// Addition it + int_val; // Subtraction it - int_val;
Dove int_val è il valore intero che viene aggiunto o sottratto dall'iteratore Esso .
Sottrazione di un altro iteratore
Possiamo sottrarre un iteratore da un altro per trovare la distanza (o il numero di elementi) tra la memoria a cui puntano.
C++it1 - it2
Confronto tra iteratori
Possiamo anche testare i due iteratori dello stesso tipo l'uno contro l'altro per trovare la relazione tra loro. Possiamo utilizzare gli operatori relazionali come (==) operatori di uguaglianza e (!=) di disuguaglianza insieme ad altri operatori relazionali come< > <= >=.
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
Tipi di iteratori in C++
Gli iteratori STL possono essere suddivisi in base alle operazioni che possono essere eseguite su di essi. Esistono 5 tipi principali di iteratori in C++ elencati nella tabella seguente insieme ai contenitori supportati e alle operazioni di iteratore supportate.
Iteratore | Descrizione | Contenitori supportati | Operazioni supportate |
|---|---|---|---|
Iteratore di input | È un iteratore unidirezionale utilizzato per leggere i valori. | Flusso di ingresso | Dereferenziazione Incremento Uguaglianza |
Iteratore di output | È anche un iteratore unidirezionale ma utilizzato per assegnare i valori. Non può accedere ai valori. | Flusso di uscita | Dereferenziazione (solo scrittura) Incremento |
Iteratori avanzati | Può accedere e assegnare i valori. È la combinazione dell'iteratore di input e di output. | forward_list unordered_map unordered_set | Dereferenziazione Incremento Uguaglianza |
Iteratori bidirezionali | Può muoversi in entrambe le direzioni, sia in avanti che all'indietro. I contenitori come set di elenchi e multimappa supportano iteratori bidirezionali. | elenco mappa set multimappa multiset | Uguaglianza incremento/decremento del dereferenziamento |
Iteratori ad accesso casuale | Gli iteratori ad accesso casuale sono iteratori che possono essere utilizzati per accedere a elementi a distanza dall'elemento a cui puntano offrendo la stessa funzionalità dei puntatori. | stringa dell'array di decodificazione vettoriale stringhe di Java | Tutto |
Come potremmo aver notato dalla tabella sopra, a parte gli iteratori di input e output man mano che si scende nella tabella, il tipo di iteratore contiene le funzionalità dell'iteratore precedente insieme ad alcune nuove funzionalità.
Adattatori iteratori
Gli adattatori iteratori in C++ sono il tipo speciale di iteratori creati su iteratori tradizionali per fornire funzionalità specializzate. Esistono molti adattatori iteratori in C++, alcuni dei quali sono riportati di seguito:
Tipo di adattatori iteratori | Descrizione |
|---|---|
Iteratore inverso | L'iteratore inverso è costruito su un operatore bidirezionale o superiore e consente agli utenti di attraversare il contenitore nella direzione opposta. |
Iteratori di flusso | Gli iteratori del flusso, vale a dire gli iteratori istream e ostream, sono basati rispettivamente sugli iteratori di input e di output. Questi iteratori consentono agli utenti di utilizzare i flussi come contenitori. |
Sposta gli iteratori | Gli iteratori di spostamento vengono utilizzati per introdurre la semantica di spostamento negli algoritmi STL. Gli iteratori di spostamento spostano la proprietà dei dati del contenitore copiati nel contenitore di copia senza creare copie aggiuntive. |
Iteratore inseritore | Gli iteratori di inserimento consentono di inserire gli elementi specificati in una posizione nel contenitore. Esistono tre iteratori di inserimento in C++:
Questi iteratori possono essere creati utilizzando back_inseritore() inseritore_front() inserire() funzioni in C++. |
Funzioni di utilità dell'iteratore in C++
C++ STL fornisce varie funzioni per semplificare il lavoro con gli iteratori. Sono elencati nella tabella seguente:
| Funzione | Descrizione | Sintassi |
|---|---|---|
| std::avanzamento | Fa avanzare un iteratore di un numero specifico di posizioni. | anticipo ( esso n ) |
| std::successivo | Restituisce l'iteratore che si trova un numero specificato di posizioni prima dell'iteratore specificato. | Prossimo ( esso n ) |
| Std :: Prec | Restituisce l'iteratore che si trova un numero specificato di posizioni dietro l'iteratore specificato. | prec ( esso n ) |
| std::distanza | Restituisce il numero di elementi tra due iteratori. | distanza ( it1 it2 ) |
| std::inizio | Restituisce un iteratore al primo elemento del contenitore specificato. | inizio ( contenitore ) |
| std::fine | Restituisce un iteratore all'elemento successivo all'ultimo elemento del contenitore specificato. | FINE ( contenitore ) |
| std::rbegin | Restituisce un iteratore inverso all'ultimo elemento del contenitore specificato. | rbegin ( contenitore ) |
| std::rend | Restituisce un iteratore inverso all'elemento che precede il primo elemento del contenitore specificato. | fa ( contenitore ) |
| std::inseritore | Crea un iteratore di inserimento che inserisce elementi in un contenitore in una posizione specificata. | inseritore ( posizione del contenitore ) |
| std::back_inserter | Crea un iteratore di inserimento indietro che aggiunge elementi alla fine di un contenitore. | back_inseritore ( contenitore ) |
| std::front_inserter | Crea un iteratore di inserimento frontale che inserisce elementi nella parte anteriore di un contenitore. | front_inserter ( contenitore ) |
Applicazioni degli iteratori con esempi
Gli iteratori sono ampiamente utilizzati in C++ per molti scopi diversi mentre si lavora con contenitori e algoritmi STL. Di seguito sono riportate alcune applicazioni principali degli iteratori in C++ con i loro esempi di codice:
Contenitori di attraversamento
L'attraversamento dei contenitori STL è l'applicazione più elementare degli iteratori. In questo usiamo le funzioni Begin() e End() per fare in modo che gli iteratori Begin e End attraversino l'intero contenitore. Fondamentalmente continuiamo a incrementare l'iteratore iniziale finché non è uguale alla fine.
Esempio
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; }
Produzione
10 20 30 40 50
Come mostrato nel codice sopra attraversiamo il contenitore impostato. Allo stesso modo possiamo usare lo stesso approccio per attraversare qualsiasi contenitore.
Inversione di un contenitore
Gli iteratori inversi consentono di attraversare un contenitore dalla fine all'inizio senza dover gestire manualmente l'inversione.
Esempio
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; }
Produzione
50 40 30 20 10
Algoritmi indipendenti dal contenitore
Gli iteratori consentono agli algoritmi di funzionare con qualsiasi tipo di contenitore rendendo funzioni come std::sort() std::find() e std::for_each() più flessibili. Puoi passare gli iteratori invece del contenitore vero e proprio.
Esempio
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; }
Produzione
10s in Vector: 2 10s in Multiset: 3
Ulteriori applicazioni degli iteratori
Esistono più applicazioni degli iteratori STL:
- Calcolo della distanza: L'uso degli iteratori std::distance() aiuta a calcolare il numero di elementi tra due posizioni in un contenitore.
- Iterazione del flusso: Gli iteratori di flusso consentono di trattare i flussi di input/output come contenitori semplificando la lettura e la scrittura nei flussi utilizzando algoritmi STL.
- Sposta la semantica negli algoritmi STL: Gli iteratori di spostamento introducono la semantica di spostamento negli algoritmi STL che aiuta ad aumentare le prestazioni e l'efficienza evitando copie non necessarie. I dati verranno spostati in base alle regole della semantica di spostamento.
- Iteratori personalizzati per strutture dati: È possibile implementare iteratori personalizzati per strutture dati non STL come alberi o grafici per fornire il supporto per algoritmi STL e molte altre funzionalità. Potrebbe essere necessario seguire alcune serie di regole e convenzioni per fornire un corretto incremento, decremento e altre operazioni.