何时创建结构(用户定义的数据类型)?

When is the structure (user defined data type) created?

例如考虑:

struct strct
{
 data member_1;
 data member_2;
 ......
};

编译器什么时候识别

struct strct 

作为一种数据类型? 是在执行完

行之后
struct strct

? 或者在遇到结构定义的右大括号之后?

声明不是 "executed"。

看完

struct strct {

编译器将 struct strct 识别为 不完整类型 ,这是一种它不知道其大小的类型。由于您可以使用指向 不完整类型 的指针,因此您可以编写如下内容:

struct strct {
    struct strct *next; // <- allowed, a pointer doesn't need the size of the object pointed to
    int foo;
};

一旦"body"结构声明完成,struct strct是一个完整类型,所以你可以声明该类型的变量(大小必须知道这一点)。


旁注:您实际上可以在标签后停止,声明如下:

struct strct;

因此,让编译器知道一个不完整的类型 struct strct。这也称为 前向声明。当然,只有当你在某个地方也有 complete 声明(可能在模块中是私有的)时,它才有意义。这用于在 C 中实现 OOP 代码时信息隐藏。例如,您只需公开声明如下内容:

struct strct;

struct strct *strct_create(void);
strct_foo(struct strct *self);
strct_bar(struct strct *self, int x);
[...]

并在实现这些函数的文件中包含 完整 struct strct 声明

名字struct strct一出现在代码中就可以看到。这允许您创建指向结构的指针作为结构的成员,如下所示:

struct mystruct {
    int val;
    struct mystruct *next;
};

在定义 next 成员时,struct mystruct 被认为是不完整的。不过这很好,因为允许指向不完整类型的指针。

一旦遇到结构的右大括号,结构就被认为是完整的,您可以定义它的实例。

如果另一方面您尝试这样做:

struct mystruct {
    int val;
    struct mystruct next;
};

那将是无效的,因为结构不能包含自身。

您还可以创建结构的前向声明,如下所示:

struct mystruct;

这也会创建一个不完整的类型,并且可以让您拥有两个相互引用的结构:

struct mystruct1;

struct mystruct2 {
    int val;
    struct mystruct1 *other;
};

struct mystruct1 {
    int val;
    struct mystruct2 *other;
};