1. 程式人生 > 其它 >關於連結串列中結構體typedef相關疑惑的解釋

關於連結串列中結構體typedef相關疑惑的解釋

本文將以單鏈表和靜態連結串列的初始化程式碼(c++)為例,具體分析了結構體中typedef struct LNode{....} LNode, *LinkList, SLinkList[MaxSize];的相關問題,並補充了C++中引用型別的一點知識。

第一部分

首先給出單鏈表的初始化程式碼:

typedef struct LNode {
    ElemType data;
    struct LNode *next;
} LNode, *LinkList;

bool InitList(LinkList &L) {
    L = (LNode *) malloc(sizeof(LNode));
    if (L == NULL) {
        return false;
    }
    L -> next = NULL;
    return true;
}

int main() {
    LinkList L;
    InitList(L);
}

從以上程式碼中,我們看到在定義結構體時,將struct LNode重定義為兩個名字:LNode*LinkList

之所以這樣命名,有助於我們後面對程式碼的理解。我們使用LNode來定義結構體變數並統一指代連結串列中的一個結點,使用LinkList定義指向結構體的指標並代表整個連結串列。

⭐上述表示定義了結構體struct LNode,並且struct LNode等價於LNodestruct LNode *等價於LinkList。所以定義結構體變數可以採用struct LNode L或者LNode L;定義結構體指標變數時可以採用struct LNode *L或者LNode *L或者LinkList L

第二部分

現在有一個問題是為什麼InitList()函式的形參為LinkList &L?這對於不瞭解c++的我來說確實引發了一陣困惑。

⭐其實,在c++中LinkList &L這種格式宣告的是一種特殊的型別---->引用型別,它直接以按引用呼叫的方式呼叫變數(有點類似於指標,但並不相同)。

舉個例子:

void swap1(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
}

void swap2(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

void swap3(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}

int main() {
    int a = 1, b = 2;
    swap1(a, b); // 按值呼叫 其結果仍然是a = 1, b = 2;
    swap2(&a, &b); // 通過指標模擬按引用呼叫,其結果為a = 2, b = 1;
    swap3(a, b); // 按引用呼叫,其結果為a = 2, b = 1;
}

通過以上的解釋,我們就可以理解InitList(LinkList &L)實際上是按引用呼叫了連結串列指標,這樣就可以將函式內對指標的修改帶回到主函式中。

那麼,如果我們不用這種方式,我們該怎麼做呢?

此時,我們就需要使用雙指標,程式碼如下:

typedef struct LNode {
    ElemType data;
    struct LNode *next;
} LNode, *LinkList;

bool InitList(LNode **L) { // 或者 InitList(LinkList *L)
    (*L) = (LNode *) malloc(sizeof(LNode));
    if ((*L) == NULL) {
        return false;
    }
    (*L) -> next = NULL;
    return true;
}

int main() {
    LinkList L;
    InitList(&L);
}

到此為止,我們就解釋了LNodeLinkList的具體使用情況(LNode宣告結構體變數,LinkList宣告結構體指標)以及C++中的引用型別。

第三部分

下面我們在舉一個靜態連結串列中的例子,深入理解一下。

先上程式碼:

#define MaxSize 10

typedef struct SNode{
    ElemType data;
    int next;
} SLinkList[MaxSize];

void testSLinkList() {
    SLinkList a;
    // 其他程式碼
}
---------------------------------
// 等價於
---------------------------------
# define MaxSize 10
struct SNode{
    ElemType data;
    int next;
};

void testSLinkList() {
    struct SNode a[MaxSize];
    // 後續程式碼
}


// 也就是說 struct Node a[MaxSize] <==> SLinkList a;

從上面我們總結出如下結論:

  1. typedef .... *LinkList;可以使簡化後續宣告結構體指標的過程,LinkList就指代了一個結構體指標型別
  2. typedef ..... LinkList[MaxSize];可以使簡化後續宣告結構體陣列的過程,LinkList就指代了一個結構體陣列型別

也就是說,我們通過typedef生成了一個簡化版的新的資料型別。