結構體的自引用與互引用
自引用
結構體是各種資料型別的集合,結構體自引用是結構體一個特殊的資料成員:
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……永無止境。
所以使用互引用要注意:至少有一個結構必須在另一個結構體中以指標的形式被引用。