结构体的自引用与互引用

自引用

结构体是各种数据类型的集合,结构体自引用是结构体一个特殊的数据成员:

typedef struct _A

{

    int a;

         struct _A *b;

}A;

结构体A中定义了一个指针b,该指针指向一个结构体A类型。为什么可以这么做呢?因为编译器在编译时已经知道一个指针所占的空间长度可以为其分配空间。而下面的定义是非法的:

typedef struct _A

{

    int a;

         struct _A b;

}A;

首先,结构体还没有定义完,编译器不知道结构体A需要多少空间存储,无法为成员b分配空间,另外成员b是一个完整的结构体,数据b中也会有一个结构体b1,而b1中同样有一个结构体b2……永无止境。

使用结构体自引用还需要注意以下一点:

typedef struct

{

    int a;

         A *b;

}A;

这也是非法的,因为定义指针b时,结构体名A还未可见,编译器会报数据类型A未定义,解决的办法是使用结构体标签:

typedef struct _A

{

    int a;

         struct _A *b;

}A;

此处为结构体A定义了一个标签_A,标签有结构体A的描述信息,使用时前面一定要加上关键词struct。关于C语言的标签到底是个什么,编译器是怎么使用标签的,我也还没弄清楚。

互引用

一个结构体A中包含一个或多个与结构体B相关的成员, 且结构体B中也包含一个或多个与结构体A相关的成员称为结构体的互引用. 

先看一个互引用的错误用法:

struct A

{

    int a;

    struct B *b;

};

struct B

{

    int b;

    struct A *a;

};

为什么是错误的呢?在定义结构体A的成员b时,结构体B对A还未可见,故此时编译器会报数据类型B未定义,解决办法是使用不完整声明:

struct B;  //不完整声明,使结构体B可见,但先不告知B的具体定义

struct A

{

    int a;

    struct B *b;

};

struct B

{

    int b;

    struct A *a;

};

再看互引用的另一个错误用法:

struct B;  //不完整声明,使结构体B可见,但先不告知B的具体定义

struct A

{

    int a;

    struct B b;

};

struct B

{

    int b;

    struct A a;//

};

结构体A和B都是直接包含了对方,这样造成什么问题呢?这个与上文自引用提到到第一个错误用法类似,结构体A包含了结构体B而结构体B由包含了结构体A……永无止境。

所以使用互引用要注意:至少有一个结构必须在另一个结构体中以指针的形式被引用。

猜你喜欢

转载自www.cnblogs.com/heart-flying/p/10250132.html