Menu
Coddy logo textTech

İteratör Kalıbı

Coddy'nin C Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 56 / 61.

Iterator deseni, bir koleksiyonun öğelerine, koleksiyonun alt yapısını ifşa etmeden sıralı bir şekilde erişmek için bir yol sağlar. Kullanıcılara bir diziye doğrudan erişim vermek yerine, onlara veriler arasında her seferinde bir öğe olacak şekilde nasıl ilerleyeceğini bilen bir nesne verirsiniz.

Bir yineleyici (iterator) genellikle iki bilgiye ihtiyaç duyar: koleksiyona bir referans ve mevcut konum. C'de, bu durumu tutmak için bir struct oluştururuz:

typedef struct {
    int* data;      // dizi işaretçisi
    int size;       // toplam eleman sayısı
    int current;    // mevcut konum
} IntIterator;

İteratör iki ana fonksiyon sunar. has_next() okunacak daha fazla öğe olup olmadığını kontrol eder ve next() mevcut öğeyi döndürerek konumu ilerletir:

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

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

İteratörü kullanmak temiz görünür ve dizi detaylarını gizler:

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

Çağıranın, numbers değişkeninin bir dizi olduğunu veya indekslemenin nasıl çalıştığını bilmesine asla gerek yoktur. Bu soyutlama, temel veri yapısını daha sonra — örneğin bir diziden bağlı listeye — yineleyiciyi (iterator) kullanan kodu değiştirmeden değiştirmeyi kolaylaştırır.

challenge icon

Görev

Kolay

Bir NumberList yineleyicisi (iterator) oluşturalım — bu, temel dizi yapısını açığa çıkarmadan bir tam sayı koleksiyonu üzerinde gezinmenizi sağlayan temiz bir soyutlamadır.

Kodunuzu üç dosya halinde düzenleyeceksiniz:

  • iterator.h: Bir tam sayı dizisine işaretçi, koleksiyonun toplam boyutu ve mevcut konumu tutan bir IntIterator yapısı (struct) tanımlayın. Üç fonksiyon bildirin: create_iterator (bir dizi işaretçisi ve boyut alır, başlatılmış bir yineleyici döndürür), has_next (daha fazla eleman kalıp kalmadığını kontrol eder) ve next (mevcut elemanı döndürür ve konumu ilerletir). Include guard'ları eklemeyi unutmayın!
  • iterator.c: Yineleyici fonksiyonlarınızı uygulayın. create_iterator fonksiyonu, mevcut konumu 0 olarak ayarlanmış bir IntIterator değerini döndürmelidir. has_next fonksiyonu, okunacak daha fazla eleman varsa 1, aksi takdirde 0 döndürür. next fonksiyonu, mevcut konumdaki elemanı döndürür ve ardından konumu artırır.
  • main.c: Eleman sayısını okuyun, ardından her bir tam sayı değerini bir diziye okuyun. Bu dizi için bir yineleyici oluşturun, ardından her bir elemanı kendi satırında gezinmek ve yazdırmak için has_next ve next ile bir while döngüsü kullanın.

Programınız şunları alacaktır:

  1. Dizideki eleman sayısı
  2. Her bir tam sayı değeri ayrı bir satırda

Tüm elemanları yazdırmak için yineleyici desenini (iterator pattern) kullanın — gezinme döngünüzde doğrudan dizi indeksleme yapmayın!

Girdiler 4, ardından 10, 20, 30, 40 olduğunda örnek çıktı:

10
20
30
40

Girdiler 3, ardından -5, 0, 100 olduğunda örnek çıktı:

-5
0
100

Girdiler 1, ardından 42 olduğunda örnek çıktı:

42

Yineleyici, verilerin nasıl saklandığını gizler — ana döngünüz, dizi indeksleri veya bellek düzeni hakkında hiçbir şey bilmeden sadece "daha fazlası var mı?" ve "bana bir sonrakini ver" diye sorar.

Kopya kağıdı

Iterator deseni, bir koleksiyonun öğelerine, temel yapısını açığa çıkarmadan sıralı bir şekilde erişme yolu sağlar.

Bir iterator yapısı (struct), koleksiyon referansını, boyutunu ve mevcut konumunu tutar:

typedef struct {
    int* data;      // diziye işaretçi
    int size;       // toplam öğe sayısı
    int current;    // mevcut konum
} IntIterator;

Iterator iki ana fonksiyon sunar:

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

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

Iterator kullanmak, dizi uygulama detaylarını gizler:

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

Bu soyutlama, istemci kodunu değiştirmeden temel veri yapısının değiştirilmesine olanak tanır.

Kendin dene

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

int main() {
    int n;
    scanf("%d", &n);
    
    int arr[n];
    
    // TODO: n tane tam sayı değerini diziye oku
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    
    // TODO: Dizi için bir iterator oluştur
    
    // TODO: Gezinmek için has_next ve next ile bir while döngüsü kullan
    // ve her bir öğeyi kendi satırına yazdır
    // Gezinme döngünüzde doğrudan dizi indeksleme KULLANMAYIN!
    
    return 0;
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Object Oriented Programming bölümündeki tüm dersler