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

C 語言指針進階:跨函數修改實參值、多級指針參數、動態內存跨函數傳遞完全圖解

     編輯:關於C語言

核心原則:C 語言只有值傳遞

函數參數傳遞本質是拷貝實參的值。若要在被調函數中修改主調函數的變量,必須傳遞該變量的地址(指針)。

一級指針參數:修改指向的值


void ModifyValue(int *p) {
    *p = 100; // 解引用修改指向的內存
}

int main() {
    int a = 9;
    ModifyValue(&a); // 傳遞 a 的地址
    printf("%d\n", a); // 100
}

關鍵:形參 p 是實參 &a 的拷貝,但 *p 和 a 指向同一內存單元。

二級指針參數:修改指針本身(指向)

若要在函數內修改主調函數中的指針變量的指向,需傳遞指針的地址(二級指針)。

經典面試題分析


// 題目:使 main 中指針 p 指向合法整型單元
// 選項 A
void fun(int *q) { int s; q = &s; } // 錯:q 是拷貝,修改不影響 p;s 為局部變量,函數返回後失效

// 選項 B
void fun(int **q) { int s; *q = &s; } // 錯:*q 修改了 p 的指向,但指向棧上局部變量 s,函數返回成懸空指針

// 選項 C (正確)
void fun(int **q) { *q = (int*)malloc(sizeof(int)); } // 正確:malloc 分配堆內存,生命週期由程序員控制,需 free

// 選項 D
void fun(int *q) { q = (int*)malloc(sizeof(int)); } // 錯:q 是一級指針拷貝,修改不影響 p

圖解內存模型

main:          fun(int **q):
p ──────> ?    q ──────> p (main中p的地址)
              *q = malloc()  -->  堆內存 0x12345678
              修改 *q 即修改 p 的值
main 返回後: p ──────> 0x12345678 (合法堆內存)

三級指針與更高級

同理可推:修改二級指針的指向需三級指針參數。實際工程中極少超過二級。

最佳實踐總結

目標參數類型調用示例函數內操作
修改普通變量值int *fun(&a)*p = val;
修改一級指針指向int **fun(&p)*p = malloc(...);
修改二級指針指向int ***fun(&pp)*pp = malloc(...);
輸出動態數組int ** 或 int *+長度fun(&arr, &n)*arr = malloc(n*sizeof(int));

避坑指南

  1. 局部變量地址不可外泄:函數返回局部變量指針/將其賦給外部指針 → 懸空指針。
  2. malloc 內存必須 free:跨函數分配,明確所有權,約定誰釋放。
  3. 指針參數加 const:void fun(const int *p) 承諾不修改指向值,void fun(int *const p) 承諾不修改指針本身(僅對形參生效,實參不受影響)。
  4. 檢查 NULL:解引用前必須判斷指針非空。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved