首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

鏈表創建經典錯誤:函數參數傳指標無法修改實參指向 —— 正確姿勢是二級指標或引用

     編輯:關於C語言

錯誤代碼示例


typedef struct Node {
    int data;
    struct Node *next;
} Node;

void createList(Node *pHead, int len) { // 一級指標參數
    Node *pTail = pHead;
    for (int i = 0; i < len; i++) {
        Node *pNew = malloc(sizeof(Node));
        pNew->data = i;
        pNew->next = NULL;
        pTail->next = pNew;
        pTail = pNew;
    }
    // pHead 在此處指向新鏈表頭,但無法傳回 main!
}

int main() {
    Node *head = NULL;
    createList(head, 5); // head 仍為 NULL!
    return 0;
}

為什麼失敗?

C 語言參數傳值。createList 內的 pHead 是 main 中 head 的副本 (同樣地址值)。函數內修改 pHead 指向 (如 pHead = pNew) 只改變副本,不影響實參 head。

三種正確解法

1. 二級指標 (C 風格標準做法)


void createList(Node **ppHead, int len) {
    Node *pTail = *ppHead; // 可能為 NULL
    for (int i = 0; i < len; i++) {
        Node *pNew = malloc(sizeof(Node));
        pNew->data = i;
        pNew->next = NULL;
        if (!*ppHead) { // 空表
            *ppHead = pNew;
            pTail = pNew;
        } else {
            pTail->next = pNew;
            pTail = pNew;
        }
    }
}

int main() {
    Node *head = NULL;
    createList(&head, 5); // 傳地址
    // head 現在正確指向鏈表頭
}

2. 返回新頭指標 (更簡潔、函數式風格)


Node* createList(int len) {
    Node *head = NULL, *tail = NULL;
    for (int i = 0; i < len; i++) {
        Node *pNew = malloc(sizeof(Node));
        pNew->data = i;
        pNew->next = NULL;
        if (!head) head = tail = pNew;
        else { tail->next = pNew; tail = pNew; }
    }
    return head;
}

int main() {
    Node *head = createList(5);
}

3. C++ 參考 (若編譯為 C++)


void createList(Node *&head, int len) { // 引用參數
    // 同一級指標邏輯,直接修改 head
}

帶頭節點版本的正確創建


Node* createWithDummy(int len) {
    Node *dummy = malloc(sizeof(Node)); // 頭節點不存數據
    dummy->next = NULL;
    Node *tail = dummy;
    for (int i = 0; i < len; i++) {
        Node *pNew = malloc(sizeof(Node));
        pNew->data = i;
        pNew->next = NULL;
        tail->next = pNew;
        tail = pNew;
    }
    return dummy; // 返回頭節點
}

// 使用
Node *head = createWithDummy(5);
Node *firstData = head->next; // 首個數據節點

記憶口訣

「要改指標指向,傳指標的地址;或直接返回新指標;C++ 再用引用最方便。」

延伸:其他需修改指標的場景

  • 鏈表插入/刪除頭節點
  • 樹的根節點修改
  • 動態數組擴容 (realloc 可能改變地址)
  • 輸出型參數 (int *out_err_code)

統統遵循同一原則:傳遞指標的地址 (二級指標) 或返回新值。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved