【发布时间】:2017-11-20 23:03:58
【问题描述】:
例如考虑:
struct strct
{
data member_1;
data member_2;
......
};
编译器何时识别
struct strct
作为数据类型? 是不是在执行完这一行之后
struct strct
? 或者在遇到结构定义的右大括号之后?
【问题讨论】:
标签: c structure user-defined-data-types
例如考虑:
struct strct
{
data member_1;
data member_2;
......
};
编译器何时识别
struct strct
作为数据类型? 是不是在执行完这一行之后
struct strct
? 或者在遇到结构定义的右大括号之后?
【问题讨论】:
标签: c structure user-defined-data-types
声明没有“执行”。
看完
struct strct {
编译器将struct strct 识别为不完整类型,它不知道其大小。由于您可以使用指向不完整类型的指针,因此您可以编写如下内容:
struct strct {
struct strct *next; // <- allowed, a pointer doesn't need the size of the object pointed to
int foo;
};
结构声明的“主体”完成后,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;
};
【讨论】: