2012-04-05 65 views
5

Tôi đang cố gắng bọc đầu quanh khái niệm sử dụng các macro để xác định các hoạt động cấu trúc dữ liệu. Đoạn mã sau là một ví dụ đơn giản để sử dụng thư viện được xây dựng sẵn trong FreeBSD. Trong thư viện, tất cả các hoạt động được định nghĩa là macro. Tôi đã thấy cách tiếp cận này trong vài thư viện khác.Sử dụng các macro trong C để xác định cấu trúc dữ liệu

Tôi có thể thấy rằng điều này có một số lợi thế, ví dụ: là khả năng sử dụng bất kỳ cấu trúc dữ liệu nào làm phần tử trong danh sách. Nhưng tôi không hoàn toàn hiểu cách làm việc này. Ví dụ:

  1. stailhead là gì? Điều này có vẻ là "chỉ" được xác định.
  2. Cách vượt qua headentries cho một chức năng?
  3. Loại nào là head, làm cách nào để khai báo một con trỏ?

Có tên chuẩn cho kỹ thuật này mà tôi có thể sử dụng để tìm kiếm trên google hoặc bất kỳ cuốn sách nào giải thích khái niệm này không? Bất kỳ liên kết hoặc giải thích tốt như thế nào kỹ thuật này hoạt động sẽ được nhiều đánh giá cao.

Nhờ Niklas B. Tôi chạy gcc -E và có định nghĩa này cho head

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

và điều này cho stailq_entry

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

Vì vậy, tôi đoán head là loại 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

Chuyển đến tiêu đề thích hợp và xem 'STAILQ_HEAD',' STAILQ_INIT' mở rộng thành –

+2

Hoặc chỉ sử dụng 'gcc -E'. BTW, cách này bằng cách sử dụng macro là hữu ích để mô phỏng generics trong C. –

+0

Ở cái nhìn đầu tiên, tôi tin rằng bằng cách sử dụng STAILQ_HEAD_INITIALIZER trong định nghĩa, và sau đó STAILQ_INIT là dư thừa. Tôi tin rằng họ cũng làm như vậy. – abelenky

Trả lời

7

Đầu tiên đọc this để giữ các macro này hoạt động như thế nào. Và sau đó đi đến queue.h. Bạn sẽ nhận được kho báu của bạn ở đó!

Tôi tìm thấy một vài đồng xu vàng cho anh-

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

Cho phép khai thác trong một chút sâu sắc và giải đáp thắc mắc của bạn

gì được stailhead? Điều này có vẻ là "chỉ" được xác định.

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

Vì vậy stailhead là một cấu trúc

Làm thế nào để vượt qua người đứng đầu và các mục để một chức năng?

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

Vì vậy entrieshead (như đã giải thích trước đó) chỉ là cấu trúc và bạn có thể vượt qua họ cũng giống như bạn vượt qua các cấu trúc khác. &structure_variable

Loại đầu là gì, làm cách nào để khai báo con trỏ?

Đã được giải thích!

Đọc this man page để biết các ví dụ điển hình hay.

+0

'man 3 queue' (XXX đệm ngu ngốc để làm cho stackoverflow chấp nhận nhận xét của tôi) –

+1

@ConradMeyer Cảm ơn bạn đời. Tôi đã thêm liên kết trang người đàn ông! –

+0

Cảm ơn Pavan, Cảm ơn bạn đã dành thời gian trả lời tôi. Câu trả lời của bạn thực sự hữu ích. – Raj

Các vấn đề liên quan