Question

Je n'ai pas en train d'écrire C pendant très longtemps, et je ne suis pas sûr de savoir comment je devrais aller à faire ce genre de choses récursifs ... Je voudrais chaque cellule pour contenir une autre cellule, mais je reçois un erreur le long des lignes de « champ « enfant » a un type incomplet ». Quoi de neuf?

typedef struct Cell {
  int isParent;
  Cell child;
} Cell;
Était-ce utile?

La solution

Il est clair qu'une cellule ne peut pas contenir une autre cellule comme il devient une récursion sans fin.

Cependant, une cellule peut contenir un pointeur vers une autre cellule.

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

Autres conseils

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

#include <stdio.h>
#include <stdlib.h>

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 qu'il soit probablement beaucoup plus compliqué que cela dans la norme, vous pouvez penser comme le compilateur savoir au sujet struct Cell sur la première ligne du typedef mais ne pas connaître tCell jusqu'à la dernière ligne :-) Voilà comment je me souviens cette règle.

Du point de vue théorique, les langues ne peut que soutenir les structures d'auto-référentiel non structures auto-inclus.

Il est en quelque sorte un moyen de contourner ceci:

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

struct Cell;
typedef struct Cell Cell;

Si vous déclarez comme ça, il dit bien que le compilateur Cell struct et ol' cellules plaine sont les mêmes. Vous pouvez donc utiliser comme cellule normale. Ils doivent encore utiliser les cellules à l'intérieur de la struct déclaration initiale elle-même si.

Je sais que ce poste est vieux, mais, 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 chacun des deux cas mentionnés dans le fragment de code ci-dessus, vous devez déclarer votre structure de cellule enfant comme un pointeur. Si vous ne le faites pas, alors vous obtiendrez l'erreur « champ 'enfant a de type incomplet ». La raison en est que « Cell struct » doit être défini pour que le compilateur de savoir combien d'espace à allouer lorsqu'il est utilisé.

Si vous essayez d'utiliser « Cell struct » dans la définition de la « cellule de struct », le compilateur ne peut pas encore savoir combien d'espace « Cell struct » est censé prendre. Cependant, le compilateur sait déjà combien d'espace un pointeur prend, et (avec la déclaration en avant), il sait que « Cell » est un type de « Cell struct » (bien qu'il ne connaît pas encore la taille d'une « cellule struct » est ). Ainsi, le compilateur peut définir une « cellule * » dans le struct qui est défini.

Permet de passer par définition de base de typedef. typedef utiliser pour définir un alias à un type de données existant, soit il est défini par l'utilisateur ou intégré.

typedef <data_type> <alias>;

par exemple

typedef int scores;

scores team1 = 99;

La confusion est ici avec la structure auto-référentiel, en raison d'un membre du même type de données qui définit pas 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 dernière option augmenter quelques lignes supplémentaires et des mots avec généralement nous ne voulons pas faire (nous sommes si paresseux que vous savez;)). Alors préférez View 2.

Une autre méthode pratique est d'effectuer une pré-typedef la structure avec étiquette de structure:

//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;

une structure qui contient une référence à lui-même. Un phénomène courant de cela dans une structure qui décrit un noeud pour une liste de lien. Chaque noeud a besoin d'une référence au noeud suivant de la chaîne.

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

Toutes les réponses précédentes sont grandes, Je pensais juste que de donner un aperçu pourquoi une structure ne peut pas contenir une instance de son propre type (pas une référence).

il est très important de noter que les structures sont des types à savoir qu'ils contiennent « valeur » la valeur réelle, de sorte que lorsque vous déclarez une structure que le compilateur doit décider la quantité de mémoire à allouer à une instance de celui-ci, il passe par tous ses membres et ajoute leur mémoire pour comprendre le savoir struct de mémoire a vous Takes devez décider sur toute la mémoire du struct, mais si le compilateur a trouvé une instance de la même structure à l'intérieur, alors c'est un paradoxe (dans l'ordre la quantité de mémoire struct A prend!).

Mais les types de référence sont différents, si un struct « A » contient une « référence » à une instance de son propre type, bien que nous ne savons pas encore combien de mémoire est alloué, nous savons à quel point la mémoire est allouée à une adresse de mémoire (par exemple la référence).

HTH

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top