Pattern Iterator
Fa parte della sezione Programmazione orientata agli oggetti del percorso C di Coddy. Lezione 56 di 61.
Il pattern Iterator offre un modo per accedere agli elementi di una raccolta in sequenza senza esporne la struttura sottostante. Invece di dare agli utenti accesso diretto a un array, fornisci loro un oggetto che sa come scorrere i dati un elemento alla volta.
Un iteratore ha in genere bisogno di due informazioni: un riferimento alla raccolta e la posizione corrente. In C, creiamo una struct per contenere questo stato:
typedef struct {
int* data; // puntatore all'array
int size; // numero totale di elementi
int current; // posizione corrente
} IntIterator;L'iteratore espone due funzioni chiave. has_next() verifica se ci sono altri elementi da leggere e next() restituisce l'elemento corrente e fa avanzare la posizione:
int has_next(IntIterator* it) {
return it->current < it->size;
}
int next(IntIterator* it) {
return it->data[it->current++];
}Usare l'iteratore è chiaro e nasconde i dettagli dell'array:
IntIterator it = create_iterator(numbers, 5);
while (has_next(&it)) {
printf("%d\n", next(&it));
}Chi chiama non deve mai sapere che numbers è un array né come funziona l'indicizzazione. Questa astrazione rende facile cambiare in seguito la struttura dati sottostante, passando per esempio da un array a una lista concatenata, senza modificare il codice che usa l'iteratore.
Sfida
FacileCostruiamo un iteratore NumberList: un’astrazione chiara che ti permette di attraversare una raccolta di interi senza esporre la struttura dell’array sottostante.
Organizzerai il codice in tre file:
iterator.h: Definisci una strutturaIntIteratorche contiene un puntatore a un array di interi, la dimensione totale della raccolta e la posizione corrente. Dichiara tre funzioni:create_iterator(accetta un puntatore all’array e la dimensione e restituisce un iteratore inizializzato),has_next(controlla se rimangono altri elementi) enext(restituisce l’elemento corrente e avanza la posizione). Non dimenticare le guardie di inclusione!iterator.c: Implementa le funzioni dell’iteratore. La funzionecreate_iteratordeve restituire unIntIteratorper valore, con la posizione corrente impostata a 0. La funzionehas_nextrestituisce 1 se ci sono altri elementi da leggere, altrimenti 0. La funzionenextrestituisce l’elemento nella posizione corrente e poi incrementa la posizione.main.c: Leggi il numero di elementi, poi leggi ogni valore intero in un array. Crea un iteratore per questo array, quindi usa un ciclo while conhas_nextenextper attraversarlo e stampare ogni elemento su una riga separata.
Il programma riceverà:
- Il numero di elementi nell’array
- Ogni valore intero su una riga separata
Usa il modello iteratore per stampare tutti gli elementi: niente accesso diretto agli indici dell’array nel ciclo di attraversamento!
Esempio di output quando gli input sono 4, poi 10, 20, 30, 40:
10
20
30
40Esempio di output quando gli input sono 3, poi -5, 0, 100:
-5
0
100Esempio di output quando gli input sono 1, poi 42:
42L’iteratore nasconde il modo in cui sono memorizzati i dati. Il ciclo principale si limita a chiedere «ce ne sono altri?» e «dammi il prossimo», senza sapere nulla sugli indici dell’array o sulla disposizione della memoria.
Provalo tu
#include <stdio.h>
#include "iterator.h"
int main() {
int n;
scanf("%d", &n);
int arr[n];
// TODO: Leggi n valori interi nell'array
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
// TODO: Crea un iteratore per l'array
// TODO: Usa un ciclo while con has_next e next per scorrere l'array
// e stampa ogni elemento su una riga separata
// NON usare l'accesso diretto agli elementi dell'array tramite indice nel ciclo di scorrimento!
return 0;
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Basi di programmazione modulare
File di intestazioneGuardie di inclusioneFile sorgenteFunzioni staticheRipasso: calcolatrice modulare4Incapsulamento
Il concetto di puntatori opachiDefinire struct opacheGetter e setterLa convalida nei setterRiepilogo: scatola segreta2Oggetti e metodi
Le struct come oggettiIl puntatore 'Self'Correttezza constPuntatore o valoreMetodi di supportoRiepilogo: gestore di punti5Progetto: Conto bancario semplice
Configurazione del progettoImplementazione del conto8Polimorfismo
Puntatori a funzione nelle structSimulare i metodiIl concetto di interfacciaImplementare le interfacceIterazione polimorficaRiepilogo: Greeter11Pattern di progettazione in C
Pattern SingletonPattern FactoryPattern IteratorRiepilogo: Factory di Logger3Ciclo di vita degli oggetti
Pattern del costruttorePattern del distruttoreInizializzazione sullo stackCopia profondaRiepilogo: wrapper di stringhe6Ereditarietà tramite composizione
Incorporamento delle structLa regola del primo membroAccesso ai membri della classe baseUpcastingRiepilogo: gerarchia di forme9Progetto: Disegnatore di forme
Panoramica del progettoImplementazione del cerchioImplementazione del rettangoloUtilizzo polimorficoContenitore di formeEsercitati da solo: Compilatore C online