Использование макросов в C для определения структур данных

Я пытаюсь обдумать концепцию использования макросов для определения операций со структурой данных. Следующий код представляет собой простой пример использования встроенной библиотеки списков в FreeBSD. В библиотеке все операции определены как макросы. Я видел этот подход также в нескольких других библиотеках.

Я вижу, что это имеет некоторые преимущества, например. способность использовать любую структуру данных в качестве элемента в списке. Но я не совсем понимаю, как это работает. Например:

  1. Что такое stailhead? Кажется, это "просто" определено.
  2. Как пройти head а также entries к функции?
  3. Какой тип headКак я могу объявить указатель на него?

Есть ли стандартное название для этой техники, которую я могу использовать для поиска в Google, или в любой книге, которая объясняет эту концепцию? Будем весьма благодарны за любые ссылки или хорошее объяснение того, как работает эта техника.

Благодаря Niklas B.. я побежал gcc -E и получил это определение для head

struct stailhead {
  struct stailq_entry *stqh_first;
  struct stailq_entry **stqh_last; 
} head = { ((void *)0), &(head).stqh_first };

и это для stailq_entry

struct stailq_entry {
 int value;
 struct { struct stailq_entry *stqe_next; } entries;
};

Так что я думаю head имеет тип struct stailhead,

#include <stdio.h>
#include <stdlib.h>
#include <sys/queue.h>

struct stailq_entry {
        int value;
        STAILQ_ENTRY(stailq_entry) entries;
};

int main(void)
{
        STAILQ_HEAD(stailhead, stailq_entry) head = STAILQ_HEAD_INITIALIZER(head);
        struct stailq_entry *n1;
        unsigned i;
        STAILQ_INIT(&head);                     /* Initialize the queue. */

        for (i=0;i<10;i++){
                n1 = malloc(sizeof(struct stailq_entry));   /* Insert at the head. */
                n1->value = i;
                STAILQ_INSERT_HEAD(&head, n1, entries);
        }
        n1 = NULL;

        while (!STAILQ_EMPTY(&head)) {
                n1 = STAILQ_LAST(&head, stailq_entry, entries);
                STAILQ_REMOVE(&head, n1, stailq_entry, entries);
                printf ("n2: %d\n", n1->value);
                free(n1);
        }

        return (0);
}

1 ответ

Решение

Сначала прочитайте это, чтобы понять, что делают эти макросы. А затем перейти к queue.h, Вы получите свою сокровищницу там!

Я нашел несколько золотых монет для вас

#define STAILQ_HEAD(name, type)                                         \
struct name {                                                           \
        struct type *stqh_first;/* first element */                     \
        struct type **stqh_last;/* addr of last next element */         \
}

Давайте углубимся и ответим на ваши вопросы

Что такое тупой? Кажется, это "просто" определено.

#define STAILQ_HEAD(name, type)                                         \
struct name {                                                           \
        struct type *stqh_first;/* first element */                     \
        struct type **stqh_last;/* addr of last next element */         \
}
 STAILQ_HEAD(stailhead, entry) head =
 STAILQ_HEAD_INITIALIZER(head);
 struct stailhead *headp;            /* Singly-linked tail queue head. */

Так stailhead это структура

Как передать голову и записи в функцию?

#define STAILQ_ENTRY(type)                                              \
struct {                                                                \
        struct type *stqe_next; /* next element */                      \
}

Так entries а также head (как объяснялось ранее) - это просто структуры, и вы можете передавать их так же, как проходите мимо других структур. &structure_variable

Какой тип головы, как я могу объявить указатель на него?

Уже объяснил!

Прочитайте эту справочную страницу для хороших симпатичных примеров.

Другие вопросы по тегам