القائمة(3)

الاسم
LIST_EMPTY, LIST_ENTRY, LIST_FIRST, LIST_FOREACH, LIST_HEAD, LIST_HEAD_INITIALIZER, LIST_INIT, LIST_INSERT_AFTER, LIST_INSERT_BEFORE, LIST_INSERT_HEAD, LIST_NEXT, LIST_REMOVE - تنفيذ قائمة مرتبطة مزدوجة

المكتبة
مكتبة سي المعيارية (libc، -lc)

موجز
#include <sys/queue.h>

LIST_ENTRY(TYPE);

LIST_HEAD(HEADNAME, TYPE);
LIST_HEAD LIST_HEAD_INITIALIZER(LIST_HEAD head);
void LIST_INIT(LIST_HEAD *head);

int LIST_EMPTY(LIST_HEAD *head);

void LIST_INSERT_HEAD(LIST_HEAD *head,
                        struct TYPE *elm, LIST_ENTRY NAME);
void LIST_INSERT_BEFORE(struct TYPE *listelm,
                        struct TYPE *elm, LIST_ENTRY NAME);
void LIST_INSERT_AFTER(struct TYPE *listelm,
                        struct TYPE *elm, LIST_ENTRY NAME);

struct TYPE *LIST_FIRST(LIST_HEAD *head);
struct TYPE *LIST_NEXT(struct TYPE *elm, LIST_ENTRY NAME);

LIST_FOREACH(struct TYPE *var, LIST_HEAD *head, LIST_ENTRY NAME);

void LIST_REMOVE(struct TYPE *elm, LIST_ENTRY NAME);

الوصف
تُعرِّف هذه الكليّات وتُشغّل القوائم المرتبطة المزدوجة.

في تعريفات الكليّات، TYPE هو اسم هيكل مُعرَّف من المستخدم، يجب أن يحتوي على حقل من نوع LIST_ENTRY، يُسمى NAME. المعامل HEADNAME هو اسم هيكل مُعرَّف من المستخدم يجب التصريح به باستخدام الكليّة LIST_HEAD().

  الإنشاء
ترأس القائمة هيكل مُعرَّف بواسطة الكليّة LIST_HEAD(). يحتوي هذا الهيكل على مؤشر واحد للعنصر الأول في القائمة. العناصر مرتبطة مزدوجًا بحيث يمكن إزالة أي عنصر عشوائي دون اجتياز القائمة. يمكن إضافة عناصر جديدة إلى القائمة بعد عنصر موجود، أو قبل عنصر موجود، أو في رأس القائمة. يُصرَّح عن هيكل LIST_HEAD كالتالي:

    LIST_HEAD(HEADNAME, TYPE) head;

حيث struct HEADNAME هي البنية المراد تعريفها، و struct TYPE هو نوع العناصر المراد ربطها في القائمة. يمكن لاحقًا التصريح عن مؤشر لرأس القائمة كـ:

    struct HEADNAME *headp;

(الاسمان head و headp يمكن للمستخدم اختيارهما.)

تُصرِّح LIST_ENTRY() عن هيكل يربط العناصر في القائمة.

تُقيِّم LIST_HEAD_INITIALIZER() إلى مُهيِّئ للقائمة head.

تهيِّئ LIST_INIT() القائمة المشار إليها بواسطة head.

تُقيِّم LIST_EMPTY() إلى صحيح إذا لم تكن هناك عناصر في القائمة.

  إدراج
تُدرج LIST_INSERT_HEAD() العنصر الجديد elm في رأس القائمة.

تُدرج LIST_INSERT_BEFORE() العنصر الجديد elm قبل العنصر listelm.

تُدرج LIST_INSERT_AFTER() العنصر الجديد elm بعد العنصر listelm.

  اجتياز
تُرجع LIST_FIRST() العنصر الأول في القائمة، أو NULL إذا كانت القائمة فارغة.

تُعيد LIST_NEXT() العنصر التالي في القائمة، أو NULL إذا كان هذا هو الأخير.

تتجول LIST_FOREACH() عبر القائمة المُشار إليها بواسطة head في الاتجاه الأمامي، مُسندة كل عنصر بدوره إلى var.

  إزالة
تُزيل LIST_REMOVE() العنصر elm من القائمة.

قيمة الإرجاع
تُعيد LIST_EMPTY() قيمة غير صفرية إذا كانت القائمة فارغة، وصفرًا إذا كانت القائمة تحتوي على إدخال واحد على الأقل.

تُعيد LIST_FIRST() و LIST_NEXT() مؤشرًا إلى أول بنية TYPE أو التالية، على التوالي.

تُعيد LIST_HEAD_INITIALIZER() مُهيئًا يمكن إسناده إلى القائمة head.

المعايير
BSD.

التاريخ
4.4BSD.

العلل
لا تسمح LIST_FOREACH() بإزالة أو تحرير var داخل الحلقة، لأن ذلك سيتداخل مع التجوال. تُصلح LIST_FOREACH_SAFE()، الموجودة في أنظمة BSD ولكنها غير موجودة في glibc، هذا القيد بالسماح بإزالة var بأمان من القائمة وتحريره من داخل الحلقة دون التداخل مع التجوال.

أمثلة
    #include <stddef.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/queue.h>

    struct entry {
        int data;
        LIST_ENTRY(entry) entries;              /* List */
    };

    LIST_HEAD(listhead, entry);

    int
    main(void)
    {
        struct entry *n1, *n2, *n3, *np;
        struct listhead head;                   /* List head */
        int i;

        LIST_INIT(&head);                       /* Initialize the list */

        n1 = malloc(sizeof(struct entry));      /* Insert at the head */
        LIST_INSERT_HEAD(&head, n1, entries);

        n2 = malloc(sizeof(struct entry));      /* Insert after */
        LIST_INSERT_AFTER(n1, n2, entries);

        n3 = malloc(sizeof(struct entry));      /* Insert before */
        LIST_INSERT_BEFORE(n2, n3, entries);

        i = 0;                                  /* Forward traversal */
        LIST_FOREACH(np, &head, entries)
            np->data = i++;

        LIST_REMOVE(n2, entries);               /* Deletion */
        free(n2);
                                                /* Forward traversal */
        LIST_FOREACH(np, &head, entries)
            printf("%i\n", np->data);
                                                /* List deletion */
        n1 = LIST_FIRST(&head);
        while (n1 != NULL) {
            n2 = LIST_NEXT(n1, entries);
            free(n1);
            n1 = n2;
        }
        LIST_INIT(&head);

        exit(EXIT_SUCCESS);
    }

انظر أيضًا
insque(3)، queue(7)

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.