結構體的自引用及相互引用

來自我的博客minecode.link

在用C來實現數據結構以及部分算法時,經常用到結構體,比如實現樹以及樹的子節點時,就需要該結構體包含自身類型的成員變量。而最近在研究OC的匿名函數實現時,也涉及到了類似需求。同時,兩個結構體之間相互引用也經常遇到問題。故簡單總結一下C語言結構體的自引用語法。

示例

我們以二叉樹的節點為例來看一下自引用:

struct binary_tree {
    int data    ;   // Data area
    struct binary_tree * left;
    struct binary_tree * right;
};

在樹中,我們需要保存其左右子樹,所以需要引用自身。

結構體自引用

不使用typedef

如果不適用typedef,那么此時我們需要使用struct [名稱]來調用。
但如果按下面的調用方式

struct binary_tree {
    int data;
    struct binary_tree left;
    struct binary_tree right;
};

則會導致在分配內存的時候循環分配,此時編譯器會計算left和right的成員變量并為之分配內存,從而導致嵌套死循環。

struct binary_tree {
    int data;
    struct binary_tree * left;
    struct binary_tree * right;
};

所以后者是正確的,left和right在分配時是以結構體指針的形式來分配內存的。而意義上我們就是為了將其指向另一個binary_tree,所以這樣是復合邏輯的。

使用typedef

使用typedef可以為結構體設置別名,但是要注意的是,typdef的語法為typedef [原類型] [別名];
所以在結構體聲明之前,別名是未定義的。所以我們在內部需要使用其原類型來定義成員變量。

typedef struct binary_tree {
    int data;
    struct binary_tree * left;
    struct binary_tree * right;
}BinTREE;

結構體相互引用

同文件內

使用不完整類型

通過不完整類型語法來實現相互引用

struct s_a {
    int id;
    struct s_b *B_Ptr;
};

struct s_b {
    int id;
    A *A_Ptr;
};

使用前向聲明

typedef struct s_a A;
typedef struct s_b B;

struct s_a {
    int id;
    B *B_Ptr;
};

struct s_b {
    int id;
    A *A_Ptr;
};

不同文件內

對于不同文件,主要有兩點需要注意的。

  • 頭文件重復包含問題
  • 結構體的聲明問題

而前者通過宏定義解決

#ifndef __FILENAME_H
#define __FILENAME_H

// 代碼

#endif

后者通過上述的“前向聲明”或“不完整類型即可解決”。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容