2012-04-05 20 views
5

Sto cercando di comprendere il concetto di utilizzo delle macro per definire le operazioni della struttura dati. Il seguente codice è un semplice esempio per utilizzare la libreria di elenchi incorporata in FreeBSD. Nella libreria tutte le operazioni sono definite come macro. Ho visto questo approccio anche in un paio di altre librerie.Utilizzo di macro in C per definire le strutture dati

Posso vedere che questo ha alcuni vantaggi ad es. essere in grado di utilizzare qualsiasi struttura dati come elemento nell'elenco. Ma non capisco come funziona. Ad esempio:

  1. Che cos'è stailhead? Questo sembra essere "solo" definito.
  2. Come passare head e entries a una funzione?
  3. Che tipo è head, come posso dichiarare un puntatore ad esso?

Esiste un nome standard per questa tecnica che posso utilizzare per cercare su Google o su qualsiasi libro che spiega questo concetto? Qualsiasi link o buona spiegazione su come funziona questa tecnica sarà molto apprezzato.

Grazie a Niklas B. mi correvano gcc -E e ottenuto questa definizione per head

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

e questo per stailq_entry

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

Quindi credo head è di tipo 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

Passare alle intestazioni appropriate e vedere cosa fa 'STAILQ_HEAD',' STAILQ_INIT' espandere a –

+2

O semplicemente usare 'gcc -E'. A proposito, questo modo di utilizzare i macro è utile per simulare i farmaci generici in C. –

+0

A prima vista, credo che l'utilizzo di STAILQ_HEAD_INITIALIZER nella definizione e successivamente STAILQ_INIT sia ridondante. Credo che facciano la stessa cosa. – abelenky

risposta

7

Prima leggi this di ottenere una sospensione che cosa queste macro fanno. E poi vai a queue.h. Avrai il tuo tesoro qui!

ho trovato alcune monete d'oro per te-

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

consente di scavare un po 'profonda e rispondere alle vostre domande

cosa è stailhead? Questo sembra essere "solo" definito.

#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. */ 

Così stailhead è una struttura

Come passare la testa e le voci a una funzione?

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

Così entries e head (come spiegato in precedenza) sono strutture giuste e si può passare loro proprio come si passa altre strutture. &structure_variable

Che tipo è la testa, come posso dichiarare un puntatore ad esso?

Già spiegato!

Leggi this man page per bellissimi esempi.

+0

'man 3 queue' (XXX stupido riempimento per rendere stackoverflow accetta il mio commento) –

+1

@ConradMeyer Grazie amico. Ho aggiunto il link alla pagina man! –

+0

Grazie Pavan, grazie per avermi dedicato del tempo per rispondermi. Le tue risposte sono davvero utili. – Raj

Problemi correlati