问题的背景:
在 C 语言中,有时需要一个结构 "知道" 另一个结构,但这两个结构的定义又相互依赖(相互嵌套)。在这种情况下,无法在定义第二个结构之前完全定义第一个结构。为此,C 提供了结构的前向声明(forward declaration)。
问题:
没有前向声明,编译器不知道结构内部遇到的是什么类型, 将抛出未知类型的错误。当我们尝试创建一个包含另一个结构的值(而非指针)时,通常会出现错误,或者语法书写不正确。
解决方案:
当需要创建指向结构的指针而不透露其完整定义时,使用前向声明。语法是 struct A;。完整定义(struct A { ... };)可以稍后给出。
示例代码:
struct B; // 前向声明 struct A { int val; struct B *link; }; struct B { int id; struct A *parent; };
关键特点:
能否通过前向声明来创建“其他结构的值”类型字段?
不能,前向声明只允许以指针形式使用类型,否则会出现错误:类型大小未知。
struct B; // ok struct A { struct B b; // 错误:B的大小未知 };
在处理不同文件时,前向声明应该放在哪里?
如果结构只用作指针,则将前向声明放在头文件中。完整定义可以放在另一个头文件或实现文件中。
前向声明是否影响结构的大小和内存的正确分配?
不会,因为 C 不知道 "未定义" 结构的大小,而指针对于给定的编译器始终具有相同的大小,无论声明的类型是什么。
在头文件中,两个模块都包含相互的结构,作为值的字段。编译失败,显示未定义类型的错误。
优点:
缺点:
一位程序员使用了前向声明和指针,最小化了头文件中的冗余依赖关系。代码的编译和维护变得更容易。
优点:
缺点: