2012-04-05 3 views
5

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

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

  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); 
} 
+0

Перейдите к соответствующим заголовкам и посмотрите, что делают 'STAILQ_HEAD',' STAILQ_INIT' expand до –

+2

Или просто используйте 'gcc -E'. BTW, этот способ использования макросов полезен для моделирования дженериков в C. –

+0

Сначала я считаю, что использование STAILQ_HEAD_INITIALIZER в определении, а позже STAILQ_INIT является избыточным. Я считаю, что они делают то же самое. – abelenky

ответ

7

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

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

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

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

Что stailhead? Это кажется «справедливым».

#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

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

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

Прочитано this man page для приятных симпатичных примеров.

+0

'man 3 queue' (XXX глупое дополнение, чтобы makeoveroverflow принимало мой комментарий) –

+1

@ConradMeyer Спасибо, помощник. Я добавил ссылку на man-страницу! –

+0

Спасибо, Паван, спасибо, что нашли время ответить мне. Ваши ответы действительно полезны. – Raj

Смежные вопросы