Menu
Coddy logo textTech

Wzorzec iteratora

Część sekcji Programowanie obiektowe ścieżki C w Coddy. Lekcja 56 z 61.

Wzorzec iteratora zapewnia sposób sekwencyjnego dostępu do elementów kolekcji bez ujawniania jej wewnętrznej struktury. Zamiast zapewniać użytkownikom bezpośredni dostęp do tablicy, dajesz im obiekt, który wie, jak przechodzić przez dane po jednym elemencie naraz.

Iterator zazwyczaj potrzebuje dwóch informacji: odwołania do kolekcji i bieżącej pozycji. W C tworzymy strukturę, która przechowuje ten stan:

typedef struct {
    int* data;      // wskaźnik do tablicy
    int size;       // całkowita liczba elementów
    int current;    // bieżąca pozycja
} IntIterator;

Iterator udostępnia dwie kluczowe funkcje. has_next() sprawdza, czy są jeszcze elementy do odczytania, a next() zwraca bieżący element i przesuwa pozycję:

int has_next(IntIterator* it) {
    return it->current < it->size;
}

int next(IntIterator* it) {
    return it->data[it->current++];
}

Korzystanie z iteratora wygląda przejrzyście i ukrywa szczegóły dotyczące tablicy:

IntIterator it = create_iterator(numbers, 5);
while (has_next(&it)) {
    printf("%d\n", next(&it));
}

Wywołujący nigdy nie musi wiedzieć, że numbers jest tablicą ani jak działa indeksowanie. Ta abstrakcja ułatwia późniejszą zmianę bazowej struktury danych, na przykład z tablicy na listę wiązaną, bez zmieniania kodu, który korzysta z iteratora.

challenge icon

Wyzwanie

Łatwy

Zbudujmy iterator NumberList: przejrzystą abstrakcję, która pozwala przechodzić przez kolekcję liczb całkowitych bez ujawniania struktury bazowej tablicy.

Rozmieścisz swój kod w trzech plikach:

  • iterator.h: Zdefiniuj strukturę IntIterator, która przechowuje wskaźnik do tablicy liczb całkowitych, całkowity rozmiar kolekcji oraz bieżącą pozycję. Zadeklaruj trzy funkcje: create_iterator (przyjmuje wskaźnik do tablicy i jej rozmiar, zwraca zainicjalizowany iterator), has_next (sprawdza, czy pozostały jeszcze elementy) i next (zwraca bieżący element i przesuwa pozycję). Nie zapomnij o strażnikach nagłówka!
  • iterator.c: Zaimplementuj funkcje iteratora. Funkcja create_iterator powinna zwracać strukturę IntIterator przez wartość, z bieżącą pozycją ustawioną na 0. Funkcja has_next zwraca 1, jeśli są jeszcze elementy do odczytania, a w przeciwnym razie 0. Funkcja next zwraca element z bieżącej pozycji, a następnie ją zwiększa.
  • main.c: Wczytaj liczbę elementów, a następnie wczytaj każdą liczbę całkowitą do tablicy. Utwórz iterator dla tej tablicy, a następnie użyj pętli while z funkcjami has_next i next, aby przejść przez elementy i wypisać każdy w osobnym wierszu.

Twój program otrzyma:

  1. Liczbę elementów w tablicy
  2. Każdą liczbę całkowitą w osobnym wierszu

Użyj wzorca iteratora, aby wypisać wszystkie elementy: w pętli przechodzącej przez elementy nie używaj bezpośredniego indeksowania tablicy!

Przykładowe wyjście dla danych wejściowych 4, a następnie 10, 20, 30, 40:

10
20
30
40

Przykładowe wyjście dla danych wejściowych 3, a następnie -5, 0, 100:

-5
0
100

Przykładowe wyjście dla danych wejściowych 1, a następnie 42:

42

Iterator ukrywa sposób przechowywania danych. Twoja główna pętla po prostu pyta „czy są jeszcze jakieś?” i „daj mi następny element”, nie wiedząc nic o indeksach tablicy ani układzie pamięci.

Spróbuj swoich sił

#include <stdio.h>
#include "iterator.h"

int main() {
    int n;
    scanf("%d", &n);
    
    int arr[n];
    
    // TODO: Wczytaj n liczb całkowitych do tablicy
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    
    // TODO: Utwórz iterator dla tablicy
    
    // TODO: Użyj pętli while oraz has_next i next, aby przejść przez tablicę
    // i wypisz każdy element w osobnym wierszu
    // NIE używaj bezpośredniego indeksowania tablicy w pętli przechodzącej przez tablicę!
    
    return 0;
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C online