définition de structure auto-référentielle?

Je n’ai pas écrit C depuis très longtemps, et je ne suis donc pas sûr de savoir comment procéder pour faire ce genre de choses récursives … J’aimerais que chaque cellule contienne une autre cellule, mais j’ai une erreur le long du lignes de “champ” enfant “a type incomplet”. Quoi de neuf?

typedef struct Cell { int isParent; Cell child; } Cell; 

Clairement, une cellule ne peut pas contenir une autre cellule car elle devient une récursion sans fin.

Cependant, une cellule CAN peut contenir un pointeur sur une autre cellule.

 typedef struct Cell { bool isParent; struct Cell* child; } Cell; 

En C, vous ne pouvez pas référencer le typedef que vous créez avec la structure elle-même. Vous devez utiliser le nom de la structure, comme dans le programme de test suivant:

 #include  #include  typedef struct Cell { int cellSeq; struct Cell* next; /* 'tCell *next' will not work here */ } tCell; int main(void) { int i; tCell *curr; tCell *first; tCell *last; /* Construct linked list, 100 down to 80. */ first = malloc (sizeof (tCell)); last = first; first->cellSeq = 100; first->next = NULL; for (i = 0; i < 20; i++) { curr = malloc (sizeof (tCell)); curr->cellSeq = last->cellSeq - 1; curr->next = NULL; last->next = curr; last = curr; } /* Walk the list, printing sequence numbers. */ curr = first; while (curr != NULL) { printf ("Sequence = %d\n", curr->cellSeq); curr = curr->next; } return 0; } 

Bien que ce soit probablement beaucoup plus compliqué que cela dans le standard, vous pouvez le considérer comme un compilateur connaissant struct Cell sur la première ligne de typedef mais ne connaissant pas tCell jusqu’à la dernière ligne 🙂 Voilà comment je me souviens de cette règle .

Du sharepoint vue théorique, les langues ne peuvent supporter que des structures autoréférentielles et non des structures autonomes.

Il y a une sorte de moyen de contourner cela:

 struct Cell { bool isParent; struct Cell* child; }; struct Cell; typedef struct Cell Cell; 

Si vous le déclarez comme cela, il indique correctement au compilateur que struct Cell et plain-ol’-cell sont les mêmes. Vous pouvez donc utiliser Cell comme d’habitude. Encore faut-il utiliser struct Cell à l’intérieur de la déclaration initiale elle-même.

Je sais que cet article est ancien, cependant, pour obtenir l’effet que vous recherchez, vous pouvez essayer ce qui suit:

 #define TAKE_ADVANTAGE /* Forward declaration of "struct Cell" as type Cell. */ typedef struct Cell Cell; #ifdef TAKE_ADVANTAGE /* Define Cell structure taking advantage of forward declaration. */ struct Cell { int isParent; Cell *child; }; #else /* Or...you could define it as other posters have mentioned without taking advantage of the forward declaration. */ struct Cell { int isParent; struct Cell *child; }; #endif /* Some code here... */ /* Use the Cell type. */ Cell newCell; 

Dans l’un des deux cas mentionnés dans le fragment de code ci-dessus, vous DEVEZ déclarer votre structure de cellule enfant en tant que pointeur. Si vous ne le faites pas, vous obtiendrez alors l’erreur “champ” enfant “de type incomplet”. La raison en est que “struct Cell” doit être défini pour que le compilateur sache combien d’espace il doit allouer lorsqu’il est utilisé.

Si vous essayez d’utiliser “struct Cell” dans la définition de “struct Cell”, le compilateur ne peut pas encore savoir combien d’espace “struct Cell” est censé prendre. Cependant, le compilateur sait déjà combien d’espace un pointeur prend et (avec la déclaration forward) il sait que “Cell” est un type de “struct Cell” (bien qu’il ne connaisse pas encore la taille d’une “struct cellule”) ). Ainsi, le compilateur peut définir une “cellule *” dans la structure en cours de définition.

Passons en revue la définition de base de typedef. typedef permet de définir un alias pour un type de données existant, qu’il soit défini par l’utilisateur ou intégré.

 typedef  ; 

par exemple

 typedef int scores; scores team1 = 99; 

La confusion est ici avec la structure auto-référentielle, due à un membre du même type de données qui n’est pas défini plus tôt. Donc, de manière standard, vous pouvez écrire votre code comme: –

 //View 1 typedef struct{ bool isParent; struct Cell* child;} Cell; //View 2 typedef struct{ bool isParent; struct Cell* child; } Cell; //Other Available ways, define stucture and create typedef struct Cell { bool isParent; struct Cell* child; }; typedef struct Cell Cell; 

Mais la dernière option augmente certaines lignes et certains mots supplémentaires avec lesquels nous ne voulons généralement pas faire (nous sums tellement paresseux que vous le savez;)). Alors, préférez View 2.

Une structure qui contient une référence à elle-même. Une occurrence courante de ceci dans une structure qui décrit un nœud pour une liste de liens. Chaque nœud a besoin d’une référence au nœud suivant dans la chaîne.

 struct node { int data; struct node *next; // <-self reference }; 

Une autre méthode pratique consiste à pré-typer la structure avec l’étiquette de structure comme suit:

 //declare new type 'Node', as same as struct tag typedef struct Node Node; //struct with structure tag 'Node' struct Node { int data; //pointer to structure with custom type as same as struct tag Node *nextNode; }; //another pointer of custom type 'Node', same as struct tag Node *node; 

Toutes les réponses précédentes sont excellentes, j’ai juste pensé à expliquer pourquoi une structure ne peut pas contenir une instance de son type (pas une référence).

Il est très important de noter que les structures sont des types “valeur”, c’est-à-dire qu’elles contiennent la valeur réelle. Par conséquent, lorsque vous déclarez une structure, le compilateur doit décider de la quantité de mémoire à atsortingbuer à une instance. leur mémoire pour comprendre la mémoire de la structure, mais si le compilateur a trouvé une instance de la même structure à l’intérieur, alors il s’agit d’un paradoxe (c.-à-d. struct A prend!).

Mais les types de référence sont différents, si une structure “A” contient une “référence” à une instance de son type, même si nous ne soaps pas encore combien de mémoire lui est allouée, nous soaps combien de mémoire est allouée à une mémoire. adresse (c.-à-d. la référence).

HTH