結構體的相互引用(mutual reference),就是說在多個結構體中,都包含指向其他結構體的指針。
1. 自引用 結構體
1.1 不使用typedef時
錯誤的方式:
- struct tag_1{
- struct tag_1 A; /* 結構體 */
- int value;
- };
struct tag_1{
struct tag_1 A; /* 結構體 */
int value;
};
這種聲明是錯誤的,因爲這種聲明實際上是一個無限循環,成員b是一個結構體,b的內部還會有成員是結構體,依次下去,無線循環。在分配內存的時候,由於無限嵌套,也無法確定這個結構體的長度,所以這種方式是非法的。
正確的方式: (使用指針):
- struct tag_1{
- struct tag_1 *A; /* 指針 */
- int value;
- };
struct tag_1{
struct tag_1 *A; /* 指針 */
int value;
};
由於指針的長度是確定的(在32位機器上指針長度爲4),所以編譯器能夠確定該結構體的長度。
1.2 使用typedef 時
錯誤的方式:
- typedef struct {
- int value;
- NODE *link; /* 雖然也使用指針,但這裏的問題是:NODE尚未被定義 */
- } NODE;
typedef struct {
int value;
NODE *link; /* 雖然也使用指針,但這裏的問題是:NODE尚未被定義 */
} NODE;
這裏的目的是使用typedef爲結構體創建一個別名NODEP。但是這裏是錯誤的,因爲類型名的作用域是從語句的結尾開始,而在結構體內部是不能使用的,因爲還沒定義。
正確的方式:有三種,差別不大,使用哪種都可以。
- /* 方法一 */
- typedef struct tag_1{
- int value;
- struct tag_1 *link;
- } NODE;
- /* 方法二 */
- struct tag_2;
- typedef struct tag_2 NODE;
- struct tag_2{
- int value;
- NODE *link;
- };
- /* 方法三 */
- struct tag_3{
- int value;
- struct tag *link;
- };
- typedef struct tag_3 NODE;
/* 方法一 */
typedef struct tag_1{
int value;
struct tag_1 *link;
} NODE;
/* 方法二 */
struct tag_2;
typedef struct tag_2 NODE;
struct tag_2{
int value;
NODE *link;
};
/* 方法三 */
struct tag_3{
int value;
struct tag *link;
};
typedef struct tag_3 NODE;
2. 相互引用 結構體
錯誤的方式:
- typedef struct tag_a{
- int value;
- B *bp; /* 類型B還沒有被定義 */
- } A;
- typedef struct tag_b{
- int value;
- A *ap;
- } B;
typedef struct tag_a{
int value;
B *bp; /* 類型B還沒有被定義 */
} A;
typedef struct tag_b{
int value;
A *ap;
} B;
錯誤的原因和上面一樣,這裏類型B在定義之 前 就被使用。
正確的方式:(使用“不完全聲明”)
- /* 方法一 */
- struct tag_a{
- struct tag_b *bp; /* 這裏struct tag_b 還沒有定義,但編譯器可以接受 */
- int value;
- };
- struct tag_b{
- struct tag_a *ap;
- int value;
- };
- typedef struct tag_a A;
- typedef struct tag_b B;
- /* 方法二 */
- struct tag_a; /* 使用結構體的不完整聲明(incomplete declaration) */
- struct tag_b;
- typedef struct tag_a A;
- typedef struct tag_b B;
- struct tag_a{
- struct tag_b *bp; /* 這裏struct tag_b 還沒有定義,但編譯器可以接受 */
- int value;
- };
- struct tag_b{
- struct tag_a *ap;
- int value;
- };
/* 方法一 */
struct tag_a{
struct tag_b *bp; /* 這裏struct tag_b 還沒有定義,但編譯器可以接受 */
int value;
};
struct tag_b{
struct tag_a *ap;
int value;
};
typedef struct tag_a A;
typedef struct tag_b B;
/* 方法二 */
struct tag_a; /* 使用結構體的不完整聲明(incomplete declaration) */
struct tag_b;
typedef struct tag_a A;
typedef struct tag_b B;
struct tag_a{
struct tag_b *bp; /* 這裏struct tag_b 還沒有定義,但編譯器可以接受 */
int value;
};
struct tag_b{
struct tag_a *ap;
int value;
};
本文鏈接:http://blog.csdn.net/daheiantian/archive/2011/01/27/6233058.aspx