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

C 語言函數參數傳遞本質:值傳遞、指針傳遞、模擬引用的正確姿勢

     編輯:關於C語言

C 語言函數參數傳遞本質:值傳遞、指針傳遞、模擬引用

C 語言只有值傳遞。理解「形參是實參的副本」、「指針值傳遞仍是值傳遞」、「傳遞地址才能修改原變量」三層真相,是寫出正確函數接口的前提。本文以二叉樹創建為例,徹底講透。

核心鐵律

C 函數參數傳遞 = 將實參的值拷貝給形參。
形參與實參:同值、不同址、不同生命周期。

三層傳遞對比

傳遞內容形參類型能否修改實參變量本身能否修改實參指向的數據典型場景
普通變量值int x❌❌只讀輸入
指針值 (地址)int *p❌ (修改 p 不影響實參)✅ (通過 *p 修改 *實參)輸出參數、大結構體避免拷貝
指針的地址 (二級指針)int **pp✅ (通過 *pp 修改實參指針)✅修改指針本身 (如分配內存、鏈表頭插)

錯誤示範:指針值傳遞無法建樹

// ❌ 錯誤:形參 Tree *T 是副本,malloc 給副本,實參不變
void initTree_wrong(Tree *T) {
    char ch = getchar();
    if (ch == '#') { T = NULL; return; }
    T = malloc(sizeof(Tree));
    T->t = ch;
    initTree_wrong(T->lchild);  // 遞歸傳遞的是副本的成員,依然無效
    initTree_wrong(T->rchild);
}

正確示範:傳遞指針地址 (二級指針)

// ✅ 正確:形參 Tree **T 接收實參地址,*T 即實參本身
void initTree(Tree **T) {
    char ch = getchar();
    if (ch == '#') { *T = NULL; return; }
    *T = malloc(sizeof(Tree));
    (*T)->t = ch;
    initTree(&(*T)->lchild);  // 遞歸傳遞成員指針的地址
    initTree(&(*T)->rchild);
}

// 調用
Tree *root;
initTree(&root);  // 傳遞 root 的地址

記憶體圖解

調用 initTree(&root)
         ┌──────────────┐
main:    │ root 0x7fff… │  ← 實參 (一級指針變量)
         └──────┬───────┘
                │ &root (取地址)
                ▼
initTree: ┌──────────────┐
          │ T  0x7fff…   │  ← 形參 (二級指針,存放 &root)
          └──────┬───────┘
                 │ *T 解引用
                 ▼
          ┌──────────────┐
          │ root 0x7fff… │  ← 同一塊內存!修改 *T 即修改 root
          └──────────────┘

通用模式:輸出參數規範

// 分配內存並返回指針
int create_buffer(void **out_ptr, size_t size) {
    *out_ptr = malloc(size);
    return *out_ptr ? 0 : -1;
}

// 修改調用者的指針 (如鏈表頭插)
void list_push(Node **head, int val) {
    Node *n = malloc(sizeof(Node));
    n->val = val; n->next = *head;
    *head = n;   // 修改實參 head
}

常見誤區速查

誤區正確理解
「C 有引用傳遞」無。C++ 才有 int&。C 必須手動傳地址模擬。
「傳指針就能修改指針」只能修改指針指向的數據;修改指針本身需傳指針的地址。
「數組傳遞是引用」數組退化為指針,本質仍是值傳遞指針值。
「結構體大就傳指針」正確,但若需在函數內重新分配/指向新內存,必須傳二級指針。

小結

C 語言參數傳遞鐵律:**只有值傳遞**。
要修改實參變量本身 → 傳遞該變量的地址 (指針)。
要修改實參指針指向 → 傳遞指針的地址 (二級指針)。
二叉樹創建、鏈表頭插、內存分配函數、所有「輸出參數」場景,均遵循此規律。刻入肌肉記憶,告別指針困擾。

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