2010-10-21 13 views
28

Sto scrivendo una lista Linked in C, il codice seguente rappresenta la definizione del mio nodo.Come definire una struttura typedef contenente puntatori a se stessa?

typedef struct { 
    int value; 
    struct Node* next; 
    struct Node* prev; 
} Node; 

ho capito (o pensate che io faccio) che struct Node non è la stessa typedef struct Node. Dato che il mio codice viene compilato e eseguito come previsto, tuttavia ricevo molti avvisi quando si assegnano next e prev (avviso: assegnazione dal tipo di puntatore incompatibile). Immagino che questo abbia a che fare con il modo in cui li sto definendo nella struttura dei nodi. ho caricato il sorgente completo here

Quindi, se questo è davvero il problema, come devo definire next e prev all'interno del typedef struct Node?

Ero preoccupato che questo potesse essere un repost, ma non riuscivo a trovare quello che stavo cercando. Grazie.

+0

L'elenco collegato mi sembra molto strano. Quando hai prev e next perché hai bisogno di testa e coda, allora? Trova una buona lista collegata in c e impara da essa. Consiglierei la libreria di runtime di Apache. Penso che abbia una lista collegata. – frast

+2

con puntatori a capo e coda rendono append e antefanno O (1) invece di O (n). Fatemi sapere se vedete altri errori poiché questo è principalmente un esercizio per mantenere le mie abilità C un po 'fresche dopo tutti questi anni di Java. –

risposta

55

È necessario farlo in questo ordine:

typedef struct Node Node; 

struct Node 
{ 
    int value; 
    Node *next; 
    Node *prev; 
}; 

che non fa esattamente quello che hai chiesto, ma si risolve il problema ed è come questo in genere è fatto. Non penso che ci sia un modo migliore.

Questo tipo di dichiarazione anticipata ha un secondo utilizzo, in occultamento dei dati. Se l'elenco è stato realizzato in una libreria, si potrebbe avere solo il typedef nell'intestazione pubblico, insieme a funzioni come:

Node * list_new(void); 
Node * list_append(Node *head, Node *new_tail); 
size_t list_length(const Node *head); 

In questo modo, gli utenti della biblioteca non hanno facile accesso alle parti interne del vostro libreria, ovvero i campi della struttura Node.

+2

Sì. Una dichiarazione anticipata (http://en.wikipedia.org/wiki/Forward_declaration) è esattamente ciò che è necessario. –

+0

Oh wow. Penso di aver provato ogni combinazione tranne quella! Grazie! gli avvertimenti sono finiti! :) –

+0

Esatto, sono a conoscenza delle dichiarazioni anticipate e le ho usate in tutto il C++, ma non ho mai avuto questa circostanza particolare prima, figuriamoci con typedef/structs :) –

17

altro modo accettabile e con il minimo cambiamento al codice del PO è il seguente:

typedef struct NodeT { 
    int value; 
    struct NodeT * next; 
    struct NodeT * prev; 
} Node; 

nota l'introduzione di NodeT e il suo utilizzo in next e prev fino Node è disponibile.

+0

Questo è effettivamente ciò che ho fatto nella mia implementazione. :) per il commento di @R .. –

Problemi correlati