2010-11-04 30 views

Répondre

10

Lorsque vous créez un type de données auto-référentiel, vous devez utiliser des pointeurs pour contourner les problèmes de circularité:

struct node; 

struct node { 
    struct node * next; 
    int id; 
} 

... devraient travailler, mais veillez à allouer correctement la mémoire lors de son utilisation.

Pourquoi un pointeur? Considérez ceci: le point d'une définition struct est de sorte que le compilateur peut comprendre combien de mémoire allouer et quelles parties accéder lorsque vous dites node.id. Si votre structure node contient une autre structure node, combien de mémoire le compilateur doit-il allouer pour un node donné? En utilisant un pointeur, vous contournez ce problème, car le compilateur sait combien d'espace allouer pour un pointeur.

0

Le problème est, lorsque le compilateur atteint cette ligne:

struct node{ 
    struct node next; /* << this line */ 

le compilateur ne fait pas ce qui est savoir struct node, parce que vous définissez struct node.

En général, vous ne pouvez pas utiliser un type qui n'est pas défini ou incomplet.

+0

En fait, le compilateur * sait * déjà. Le vrai problème est que le 'struct' sera de taille infinie en raison de l'auto-référentialité. La solution consiste à utiliser un pointeur ('struct node * next').;-) –

2
  1. Vous devez faire une déclaration avant de noeud, puisque le compilateur ne connaît pas encore node pendant qu'il traite sa définition.
  2. Vous vouliez probablement stocker un pointeur, pas un objet nœud lui-même.

Essayez ceci:

struct node; 

struct node{ 
    struct node *next; 
    int id; 
}; 
+0

La déclaration forward n'est pas nécessaire car la déclaration de la structure agit comme sa propre déclaration forward. Le problème est entièrement qu'il a essayé de mettre une structure à l'intérieur de lui-même et aurait dû utiliser un pointeur. – JeremyP

1

Certaines utilisations de types incomplets sont mal formées, par exemple lorsque vous essayez de déclarer un objet de type incomplet. Cependant, vous pouvez déclarer un pointeur sur un type incomplet (par exemple). Dans ce cas, qui est juste ce qu'il faut ici:

struct node{ 
    struct node *next; 
    int id; 
}; 
5

Si un struct pourrait contenir une autre instance de son propre type, sa taille serait infinie.

C'est pourquoi il ne peut contenir qu'un pointeur à son propre type.

En outre, à ce stade du code, la taille de la structure est inconnue, de sorte que le compilateur ne pouvait pas savoir combien d'espace à réserver pour cela.

0

Pour travailler, vous devez écrire:

typedef struct _node{ 
    struct _node* next; 
    int   id; 
}node; 
+0

Les identifiants commençant par un trait de soulignement sont réservés à l'implémentation. – Flexo

+0

awoodland: uniquement trait de soulignement + lettre majuscule ou double trait de soulignement. – u0b34a0f6ae