2011-08-23 16 views
6

yapı Bu tür bağlantılı liste başı olarak kullanılır:Belirlenen başlatıcıyı kullanırken 'bu' yapıya işaretçi almak mümkün mü?

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

aşağıdaki kendini yapısına bir, her iki puan önceki, bu liste boştur. Makro parametre olmadan, şu arada aynı şeyi yapmak için herhangi bir yol yoktur,

struct lista my_list = LISTA_INIT_EMPTY(&my_list); 

Ama ?:

:

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

bu şekilde: aşağıdaki makro yapıyı başlatılırken için de kullanılabilir

struct lista my_list = LISTA_INIT_EMPTY; 

aşağıdaki çalıştı, ama bir derleme hatası neden oldu:

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

cevap

6

Eh, görüyorum tek yol tatsız:

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

ait hiç olarak değil güzel Sadece değişkeniniz my_list olarak adlandırılırsa çalışır. Ve this'un C şeklinde olmaması için iyi bir yol yoktur.

Neden "this" i işaret etmek yerine NULL kullanmıyorsunuz? Bu tatmin edici değilse, parametreli makroyu tutmak muhtemelen en iyisidir.

DÜZENLEME:

hiçbir orada "bu" ve sadece bir kez değişkenin adını girmek için böyle bir makro kullanarak öneririz gibi: (R'ın yorumun sayesinde aşağıda, sonunda gereğini anlamış):

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

Ve daha sonra kodda

: blok örneğini bilmelidir beri

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

Ben OP tüm listeler istiyor, İlk boş olanı içeren, dairesel olmak için. Bu tamamen mantıksız değil; Genellikle liste işleme işlevlerinizdeki tüm çirkin köşe durumlarını ortadan kaldırır. –

+1

'CREATE_EMPTY_LISTA' temel olarak OP tarafından belirtilen 'LISTA_INIT_EMPTY' ile aynıdır. –

+1

Evet, ama önemli bir farkla: 'struct lista my_list = LISTA_INIT_EMPTY (& my_list);' sizi değişkenin ismini tekrarlamaya zorlar, ki bu hoş ve oldukça hataya yatkın değildir. CREATE_EMPTY_LISTA (my_list); 'tekrar etmemenizi sağlar. – Shlublu

0

Pek değil! Eğer yerine NULL olarak boş tanımlarsanız "kendisi" o zaman bunu yapabilirdi:

#define LISTA_INIT_EMPTY {NULL,NULL}

0

Görünüşe göre bu, mümkün değildir.

Ayrıca türler eşleşmediğinden .next = &.next çalışmayacaktır. (struct lista** için struct lista*)

0

Hayır, başlatıcı bir struct lista oluşturur ve daha sonra buna my_list atar. Bir this fikriniz bu bağlamda anlam ifade etmiyor, atandıktan sonra my_list'a işaret etmeyecekti.

2

Liste başlatma tekniklerinizin, bağlantılı listeler için Linux çekirdeği kaynağında kullanılanla benzer olduğunu unutmayın (include/linux/list.h).yerine böyle bir şey yapmaya çalışıyor listesi kafası bildirilen bir listenin başlatma için

:

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

Linux delcaration ve başlatma hem gerçekleştiren bir makro kullanan (böylece kullanıcı yine zorundadır adı sadece bir kez kullanın).

#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); 

tüm ayrıntılar için include/linux/list.h bir göz atın: sizin struct lista için bu gibi görünebilir. listeleri operasyonları nasıl çalıştığını güzel açıklamalar (değil her şeyi sezgisel) da vardır: Chapter 11.5, "Linked Lists"
  • Linux Kernel Linked List Explained tarafından

    • Linux Kernel Gelişimi, Kulesh Shanmugasundaram
  • İlgili konular