Patron Itérateur
Fait partie de la section Object Oriented Programming du Journey C de Coddy — leçon 56 sur 61.
Le patron Itérateur fournit un moyen d'accéder aux éléments d'une collection de manière séquentielle sans exposer sa structure sous-jacente. Au lieu de donner aux utilisateurs un accès direct à un tableau, vous leur donnez un objet qui sait comment parcourir les données un élément à la fois.
Un itérateur a généralement besoin de deux informations : une référence à la collection et la position actuelle. En C, nous créons une struct pour maintenir cet état :
typedef struct {
int* data; // pointeur vers le tableau
int size; // nombre total d'éléments
int current; // position actuelle
} IntIterator;L'itérateur expose deux fonctions clés. has_next() vérifie s'il y a d'autres éléments à lire, et next() retourne l'élément actuel et avance la position :
int has_next(IntIterator* it) {
return it->current < it->size;
}
int next(IntIterator* it) {
return it->data[it->current++];
}L'utilisation de l'itérateur semble propre et masque les détails du tableau :
IntIterator it = create_iterator(numbers, 5);
while (has_next(&it)) {
printf("%d\n", next(&it));
}L'appelant n'a jamais besoin de savoir que numbers est un tableau ou comment l'indexation fonctionne. Cette abstraction permet de modifier facilement la structure de données sous-jacente plus tard — d'un tableau à une liste chaînée, par exemple — sans modifier le code qui utilise l'itérateur.
Défi
FacileConstruisons un itérateur NumberList — une abstraction propre qui vous permet de parcourir une collection d'entiers sans exposer la structure du tableau sous-jacent.
Vous organiserez votre code sur trois fichiers :
iterator.h: Définissez une structureIntIteratorqui contient un pointeur vers un tableau d'entiers, la taille totale de la collection et la position actuelle. Déclarez trois fonctions :create_iterator(prend un pointeur de tableau et une taille, retourne un itérateur initialisé),has_next(vérifie s'il reste des éléments) etnext(retourne l'élément actuel et avance la position). N'oubliez pas les gardes d'inclusion !iterator.c: Implémentez vos fonctions d'itérateur. La fonctioncreate_iteratordoit retourner unIntIteratorpar valeur avec la position actuelle fixée à 0. La fonctionhas_nextretourne 1 s'il y a plus d'éléments à lire, 0 sinon. La fonctionnextretourne l'élément à la position actuelle puis incrémente la position.main.c: Lisez le nombre d'éléments, puis lisez chaque valeur entière dans un tableau. Créez un itérateur pour ce tableau, puis utilisez une boucle while avechas_nextetnextpour parcourir et afficher chaque élément sur sa propre ligne.
Votre programme recevra :
- Le nombre d'éléments dans le tableau
- Chaque valeur entière sur une ligne séparée
Utilisez le modèle d'itérateur (iterator pattern) pour afficher tous les éléments — pas d'indexation directe du tableau dans votre boucle de parcours !
Exemple de sortie lorsque les entrées sont 4, puis 10, 20, 30, 40 :
10
20
30
40Exemple de sortie lorsque les entrées sont 3, puis -5, 0, 100 :
-5
0
100Exemple de sortie lorsque les entrées sont 1, puis 42 :
42L'itérateur masque la façon dont les données sont stockées — votre boucle principale demande simplement "y en a-t-il d'autres ?" et "donne-moi le suivant" sans rien savoir des indices du tableau ou de la disposition de la mémoire.
Aide-mémoire
Le patron Itérateur fournit un moyen d'accéder aux éléments d'une collection de manière séquentielle sans exposer sa structure sous-jacente.
Une structure d'itérateur contient la référence de la collection, la taille et la position actuelle :
typedef struct {
int* data; // pointeur vers le tableau
int size; // nombre total d'éléments
int current; // position actuelle
} IntIterator;L'itérateur expose deux fonctions clés :
int has_next(IntIterator* it) {
return it->current < it->size;
}
int next(IntIterator* it) {
return it->data[it->current++];
}L'utilisation de l'itérateur masque les détails d'implémentation du tableau :
IntIterator it = create_iterator(numbers, 5);
while (has_next(&it)) {
printf("%d\n", next(&it));
}Cette abstraction permet de modifier la structure de données sous-jacente sans modifier le code client.
Essayez vous-même
#include <stdio.h>
#include "iterator.h"
int main() {
int n;
scanf("%d", &n);
int arr[n];
// TODO: Lire n valeurs entières dans le tableau
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
// TODO: Créer un itérateur pour le tableau
// TODO: Utiliser une boucle while avec has_next et next pour parcourir
// et afficher chaque élément sur sa propre ligne
// Ne PAS utiliser l'indexation directe du tableau dans votre boucle de parcours !
return 0;
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Object Oriented Programming
1Bases de la programmation modulaire
Fichiers d'en-têteGardes d'inclusionFichiers sourcesFonctions statiquesRécapitulatif : Calculatrice modulaire4Encapsulation
Concept des pointeurs opaquesDéfinir des structures opaquesGetters et settersValidation dans les settersRécapitulatif : La boîte secrète2Objets et méthodes
Structs comme objetsLe pointeur 'Self'Rigueur du mot-clé constPointeur vs ValeurMéthodes utilitairesRécapitulatif : Point Manager5Projet : Compte bancaire simple
Configuration du projetImplémentation du compte8Polymorphisme
Pointeurs de fonctions dans les structuresSimulation de méthodesLe concept d'interfaceImplémentation d'interfacesItération polymorphiqueRécapitulatif : Greeter11Patrons de conception en C
Patron SingletonPatron FabriquePatron ItérateurRécapitulatif : Logger Factory3Cycle de vie des objets
Pattern de constructeurPattern de destructeurInitialisation sur la pileCopie profondeRécapitulatif : String Wrapper6Héritage par composition
Imbrication de structLa règle du premier membreAccès aux membres parentsUpcastingRécapitulatif : Hiérarchie des formes9Projet : Dessinateur de formes
Aperçu du projetImplémentation du cercle