Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

نمط Iterator

جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 56 من 61.

يوفّر نمط Iterator طريقة للوصول إلى عناصر collection بالتتابع دون كشف بنيتها الأساسية. وبدلاً من منح المستخدمين وصولاً direct إلى array، تمنحهم كائناً يعرف كيفية التنقّل عبر data بمقدار element واحد في كل مرة.

يحتاج iterator عادةً إلى قطعتين من المعلومات: مرجع إلى collection وposition الحالية. في C، ننشئ struct للاحتفاظ بهذه الحالة:

typedef struct {
    int* data;      // مؤشر إلى المصفوفة
    int size;       // العدد الإجمالي للعناصر
    int current;    // الموضع الحالي
} IntIterator;

يكشف المكرّر عن functions رئيسيتين. تتحقق has_next() مما إذا كانت هناك more من elements لقراءتها، وتُرجع next() العنصر current وتُقدّم الموضع:

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

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

يبدو استخدام iterator أنيقًا ويخفي تفاصيل array:

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

لا يحتاج المستدعي أبدًا إلى معرفة أن numbers هي array أو كيفية عمل indexing. يجعل هذا التجريد من السهل تغيير بنية البيانات الأساسية لاحقًا، من array إلى قائمة مرتبطة، على سبيل المثال، من دون تغيير الكود الذي يستخدم iterator.

challenge icon

التحدي

سهل

لنَبْنِ مُكرِّرًا لـ NumberList: تجريدًا نظيفًا يتيح لك اجتياز مجموعة من الأعداد الصحيحة دون كشف بنية array الأساسية.

ستنظّم شيفرتك عبر ثلاثة ملفات:

  • iterator.h: عرّف بنية IntIterator التي تحتوي على مؤشر إلى array من الأعداد الصحيحة، والحجم الإجمالي للمجموعة، والموضع الحالي. أعلن عن ثلاث functions: create_iterator (تأخذ مؤشر array والحجم، وتعيد مُكرِّرًا initializedًا)، وhas_next (تتحقق مما إذا كانت هناك elements إضافية متبقية)، وnext (تعيد element الحالي وتُقدِّم الموضع). لا تنسَ حواجز include!
  • iterator.c: نفّذ functions المخصّصة للمُكرِّر. يجب أن تعيد create_iterator قيمة من النوع IntIterator، مع ضبط الموضع الحالي على 0. تعيد has_next القيمة 1 إذا كانت هناك elements إضافية للقراءة، و0 otherwise. تعيد next الـelement الموجود عند الموضع الحالي، ثم تزيد الموضع.
  • main.c: اقرأ number الـelements، ثم اقرأ قيمة كل عدد صحيح إلى array. أنشئ مُكرِّرًا لهذا الـarray، ثم استخدم while loop مع has_next وnext لاجتياز كل element وطباعته في سطر خاص به.

سيستقبل برنامجك:

  1. عدد elements في الـarray
  2. كل قيمة عدد صحيح في سطر منفصل

استخدم نمط المُكرِّر لطباعة جميع elements: لا تستخدم direct array indexing في loop الاجتياز!

ناتج مثالي عندما تكون المدخلات هي 4، ثم 10، و20، و30، و40:

10
20
30
40

ناتج مثالي عندما تكون المدخلات هي 3، ثم -5، و0، و100:

-5
0
100

ناتج مثالي عندما تكون المدخلات هي 1، ثم 42:

42

يخفي المُكرِّر كيفية تخزين data. يطلب main loop ببساطة "is there more?" و"give me the next one" دون معرفة أي شيء عن مؤشرات الـarray أو تخطيط الذاكرة.

جرّب بنفسك

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

int main() {
    int n;
    scanf("%d", &n);
    
    int arr[n];
    
    // TODO: اقرأ n قيمًا صحيحة في المصفوفة
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    
    // TODO: أنشئ iterator للمصفوفة
    
    // TODO: استخدم حلقة while مع has_next و next للتجول
    // واطبع كل عنصر في سطره الخاص
    // لا تستخدم فهرسة المصفوفة المباشرة في حلقة التجول!
    
    return 0;
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم C عبر الإنترنت