Использование макросов в C для определения структур данных
Я пытаюсь обдумать концепцию использования макросов для определения операций со структурой данных. Следующий код представляет собой простой пример использования встроенной библиотеки списков в FreeBSD. В библиотеке все операции определены как макросы. Я видел этот подход также в нескольких других библиотеках.
Я вижу, что это имеет некоторые преимущества, например. способность использовать любую структуру данных в качестве элемента в списке. Но я не совсем понимаю, как это работает. Например:
- Что такое
stailhead
? Кажется, это "просто" определено. - Как пройти
head
а такжеentries
к функции? - Какой тип
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
Какой тип головы, как я могу объявить указатель на него?
Уже объяснил!
Прочитайте эту справочную страницу для хороших симпатичных примеров.