- 自引用
在一个结构内部包含一个类型为该结构本身的成员称为结构的自引用. 比如:
// 结构的自引用
struct self_ref {
int a;
struct self_ref b;
char c;
};
这种类型的结构自引用是 非法 的, 成员b中又会包含一个self_ref结构, 如此递归下去永无止尽.
下面这种声明却是合法的:
// 另一种自引用
struct self_ref {
int a;
struct self_ref *b;
char c;
};
成员b是一个指向self_ref结构的指针, 在结构self_ref所占内存空间确定之前就可以确定确定指针b所需要的内存空间. 所以这种引用是 合法 的.
当使用 typedef类型定义 和自引用时要注意下面这种陷阱:
// 类型定义的自引用
typedef struct {
int a;
self_ref *b;
char c;
} self_ref;
该声明试图声明一种新的类型self_ref, 该类型是包含一个int 一个指向它自身类型的指针 一个char的结构体. 这是 非法 的, 因为类型名直到整个定义结束才可见, 在结构体内部出现的 self_ref 是未定义的. 解决的方案是在增加一个结构标签.
// 带结构标签的类型定义的自引用
typedef struct self_ref_tag {
int a;
self_ref_tag *b;
char c;
} self_ref;
- 互引用
一个结构体A中包含一个或多个与结构体B相关的成员, 且结构体B中也包含一个或多个与结构体A相关的成员称为结构体的互引用.
首先要确定的是 至少有一个结构必须在另一个结构体中以指针的形式存在.
然后要注意的是先声明哪一个结构, 原则是 必须保证每一个名字在使用时都可见.
解决的方案是使用 不完整声明
struct B; // 不完整声明, 使名字B可见, 但是没有告知B的具体组成
struct A { // 完整声明了A, 并使名字A可见
struct B *partner; // 名字B已经可见
};
struct B { // 完整声明B
struct A *partner; // 名字A已经可见
};