自引用结构体定义?
我没有长时间写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