自引用结构体定义?

我没有长时间写C,所以我不知道如何去做这些recursion的事情……我希望每个单元格包含另一个单元格,但是我得到了一个错误“字段”子字段的行数不完整“。 这是怎么回事?

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

PS(Ziggy也显然被typedef弄糊涂了:他​​已经敲入Cell to Cell并且奇怪为什么?)

显然一个单元格不能包含另一个单元格,因为它成为一个永无止境的recursion。

但是一个Cell可以包含一个指向另一个单元的指针。

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

在C中(与C ++相反,我可能没有检查),你不能引用你正在用结构本身创build的typedef。 您必须使用结构名称,如以下testing程序中所示:

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

虽然这个标准可能比这个复杂得多,但是你可以把它看作是编译器知道typedef的第一行的struct Cell ,但是直到最后一行才知道tCell :-)我记得那条规则。

有一种解决方法:

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

如果你这样声明,它正确地告诉编译器,struct Cell和plain-ol'-cell是一样的。 所以你可以像正常一样使用Cell。 尽pipe如此,仍然必须在初始声明本身内部使用struct Cell。

从理论的angular度来看,语言只能支持自我指涉的结构而不是自我包容的结构。

我知道这个post是旧的,但是,要得到你正在寻找的效果,你可能要尝试以下几点:

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

在上面的代码片段中提到的两种情况中,你必须声明你的孩子的Cell结构作为一个指针。 如果你不这样做,那么你会得到“领域”的孩子“有不完整的types”的错误。 原因是必须定义“struct Cell”,以便编译器知道在使用时需要分配多less空间。

如果你尝试在“struct Cell”的定义中使用“struct Cell”,那么编译器还不知道“struct Cell”应该占用多less空间。 然而,编译器已经知道一个指针需要多less空间,并且(使用前向声明)它知道“Cell”是一种“struct Cell”(尽pipe它还不知道“struct Cell”有多大)。 所以,编译器可以在正在定义的结构中定义一个“Cell *”。

让我们通过typedef的基本定义。 typedef用来定义一个现有的数据types的别名,它是用户定义的或内置的。

 typedef <data_type> <alias>; 

例如

 typedef int scores; scores team1 = 99; 

由于相同数据types的成员之前没有定义,所以这里的混淆与自引用结构有关。 所以在标准的方式,你可以写你的代码为: –

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

但最后一个选项通常增加一些额外的行和词,我们不想做(我们是如此懒惰,你知道;))。 所以更喜欢查看2。

包含对自身的引用的结构。 在描述链接列表节点的结构中经常出现这种情况。 每个节点都需要对链中下一个节点的引用。

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

另一种方便的方法是用结构标签预先键入结构,如下所示:

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

所有以前的答案都很好,我只是想了解一下为什么一个结构不能包含它自己types的实例(而不是一个参考)。

需要注意的是结构是“有价值的”types,即它们包含实际的值,所以当你声明一个结构时,编译器必须决定分配给它的一个实例有多less内存,所以它通过它的所有成员并添加他们的内存来找出结构的所有内存,但如果编译器发现内部相同的结构的一个实例那么这是一个悖论(即为了知道有多less内存结构A需要你决定有多less内存结构A需要!)。

但是引用types是不同的,如果一个struct“A”包含一个对它自己types的实例的“引用”,尽pipe我们还不知道有多less内存被分配给它,我们知道有多less内存被分配给一个内存地址(即参考)。

HTH