当前位置:  开发笔记 > 编程语言 > 正文

自引用结构定义?

如何解决《自引用结构定义?》经验,为你挑选了5个好方法。

我没有写C很长时间,所以我不确定我应该怎么做这些递归的东西...我希望每个单元格包含另一个单元格,但我得到一个错误沿着"田地'孩子'的行具有不完整的类型".这是怎么回事?

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

Andrew Grant.. 174

显然,Cell不能包含另一个单元格,因为它变成永无止境的递归.

但是,Cell CAN包含指向另一个单元的指针.

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

@ cs01不,`Cell`还不在范围内. (5认同)

@noɥʇʎԀʎzɐɹƆ因为Python抽象了指针,所以你没有注意到它们.由于`C中的struct`s基本上只是将它们的所有值存储在一起,所以实际上不可能存储一个结构(因为该结构必须包含另一个结构,依此类推,导致内存结构为无限大小). (2认同)


paxdiablo.. 26

在C中,您无法使用结构本身引用您正在创建的typedef.您必须使用结构名称,如以下测试程序中所示:

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

虽然它可能比标准中的这个要复杂得多,但你可以把它想象成编译器struct Cell在第一行typedef知道但不知道tCell直到最后一行:-)这就是我记得那个规则的方法.



1> Andrew Grant..:

显然,Cell不能包含另一个单元格,因为它变成永无止境的递归.

但是,Cell CAN包含指向另一个单元的指针.

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


@ cs01不,`Cell`还不在范围内.
@noɥʇʎԀʎzɐɹƆ因为Python抽象了指针,所以你没有注意到它们.由于`C中的struct`s基本上只是将它们的所有值存储在一起,所以实际上不可能存储一个结构(因为该结构必须包含另一个结构,依此类推,导致内存结构为无限大小).

2> paxdiablo..:

在C中,您无法使用结构本身引用您正在创建的typedef.您必须使用结构名称,如以下测试程序中所示:

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

虽然它可能比标准中的这个要复杂得多,但你可以把它想象成编译器struct Cell在第一行typedef知道但不知道tCell直到最后一行:-)这就是我记得那个规则的方法.



3> Sundar..:

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


在大多数机器上,比自身大四个字节.

4> 小智..:

有一种解决方法:

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

struct Cell;
typedef struct Cell Cell;

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


你为什么再写`struct Cell;`?
@TylerCrompton如果将以上代码块放入单个C源文件中,则类型定义“已由编译器执行”,从而使多余的“结构单元”成为多余。但是,如果出于某种原因将最后两行放入包含_before_的头文件中,则用前四行定义`Cell`结构,那么* n *多余的`struct Cell;`是必要的。
@YoYoYonnY不,您仍然可以只编写typedef struct Cell Cell;它将使Cell成为struct Cell的别名。编译器之前是否已经看到过“ struct Cell {....}”,这并不重要。

5> Shawn..:

我知道这篇文章很老,但为了获得你想要的效果,你可能想尝试以下方法:

#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结构声明为指针.如果你不这样做,那么你将得到"字段'子'具有不完整类型"错误.原因是必须定义"struct Cell",以便编译器知道在使用它时要分配多少空间.

如果您尝试在"struct Cell"的定义中使用"struct Cell",那么编译器还不能知道"struct Cell"应该占用多少空间.但是,编译器已经知道指针占用了多少空间,并且(使用前向声明)它知道"Cell"是一种"struct Cell"(尽管它还不知道"struct Cell"有多大) ).因此,编译器可以在正在定义的结构中定义"Cell*".

推荐阅读
手机用户2402851335
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有