2011-08-23 24 views
6

這種結構被用作鏈表的頭:當使用指定的初始化程序時,是否可以獲取指向「this」結構的指針?

struct lista 
{ 
    struct lista* next; 
    struct lista* prev; 
}; 

在下一步和上兩分結構本身,則列表爲空。 下面的宏可用於初始化結構:

#define LISTA_INIT_EMPTY(list) { .next = (list), .prev = (list) } 

這樣:

struct lista my_list = LISTA_INIT_EMPTY(&my_list); 

但是,有沒有辦法通過以下方式做同樣的事情,沒有宏參數?:

struct lista my_list = LISTA_INIT_EMPTY; 

我嘗試以下,但它造成的編譯錯誤:

#define LISTA_INIT_EMPTY  { .next = &.next, .prev = &.next } 

回答

6

好了,我看到的唯一的辦法是不愉快:

#define LISTA_INIT_EMPTY  { .next = (&my_list), .prev = (&my_list) } 

不是很好,就好象它只有在您的變量名爲my_list時纔有效。並沒有好方法,因爲this不存在於C.

爲什麼不使用NULL而不是指向「this」?如果這不能令人滿意,保持參數化的宏可能是最好的。

編輯:(感謝於R的評論下面,我終於明白了需要):

至於有沒有「這個」,只有一次輸入變量的名字,我建議使用這樣的宏:

#define CREATE_EMPTY_LISTA(name) struct lista name = { .next=&name, .prev=&name } 

而且在後面的代碼:

CREATE_EMPTY_LISTA(my_list); // creates and initializez my_list at the same time 
+2

我認爲OP希望所有的名單,包括最初的空的一個,是循環的。這並非完全不合理;通常它會消除列表處理函數中所有難看的角落案例。 –

+1

「CREATE_EMPTY_LISTA」與OP提到的「LISTA_INIT_EMPTY」基本相同。 –

+1

是的,但有一個重要的區別:'struct lista my_list = LISTA_INIT_EMPTY(&my_list);'強制你重複變量的名稱,這是不好的,很容易出錯。 'CREATE_EMPTY_LISTA(my_list);'允許你不重複它。 – Shlublu

0

不是真的!如果爲NULL,而不是定義空「本身」,那麼你可以通過做:

#define LISTA_INIT_EMPTY {NULL,NULL}

0

顯然這是不可能的,因爲該塊需要知道實例。因爲類型不匹配,所以.next = &.next也不起作用。 (struct lista*struct lista**

0

不,您的初始化程序會創建一個struct lista,然後爲其分配my_list。你的想法this在這種情況下沒有意義,它不會指向my_list,直到它被分配爲止。

2

請注意,您的列表初始化技術與Linux內核源代碼中的鏈接列表(include/linux/list.h)類似。

因爲當表頭被宣佈名單的初始化,而不是試圖做這樣的事情:

// won't work: 
struct lista my_list = /* something or other */; 

Linux使用具有同時進行的delcaration和初始化宏(因此用戶仍然需要只使用該名稱一次)。爲了您的struct lista它可能看起來像:

#define LISTA_HEAD struct lista name = LISTA_INIT_EMPTY(name) 

// this is all the user needs to do to both declare and initialize a list: 
LISTA_HEAD(my_list); 

看看include/linux/list.h的所有細節。也有名單的操作是如何工作的很好的解釋(不是所有的直觀):