logo

Iteratori in C++ STL

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++:

  1. back_insert_iterator: Inserti sul retro del contenitore.
  2. front_insert_iterator: Inserti nella parte anteriore del contenitore.
  3. insert_iterator: Si inserisce in qualsiasi punto del contenitore.

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::inizioRestituisce un iteratore al primo elemento del contenitore specificato. inizio ( contenitore )
std::fineRestituisce un iteratore all'elemento successivo all'ultimo elemento del contenitore specificato. FINE ( contenitore )
std::rbeginRestituisce un iteratore inverso all'ultimo elemento del contenitore specificato. rbegin ( contenitore )
std::rendRestituisce 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.