自引用指針
結構體是各類數據類型的集合,結構體自引用是結構體一個特殊的數據成員:編譯器
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……永無止境。
因此使用互引用要注意:至少有一個結構必須在另外一個結構體中以指針的形式被引用。