首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 指針交換函數:為什麼交換指針本身無法交換數值?內存圖解與正確寫法

     編輯:程式設計綜合問答

兩個版本對比

版本一:正確交換數值 (解引用修改指向內存)


void swap_value(int *p1, int *p2) {
    int temp = *p1;  // 取出 p1 指向的數值
    *p1 = *p2;       // 將 p2 指向的數值寫入 p1 指向的內存
    *p2 = temp;      // 將暫存數值寫入 p2 指向的內存
}

效果:調用者的兩個變量數值真正交換。

版本二:錯誤嘗試交換指針 (僅修改局部參數副本)


void swap_ptr_wrong(int *p1, int *p2) {
    int *p = p1;  // p 指向 p1 指向的內存
    p1 = p2;      // p1 (局部參數) 指向 p2 指向的內存
    p2 = p;       // p2 (局部參數) 指向原 p1 指向的內存
}

效果:**調用者變量完全不變**。函數內部只是交換了**參數副本**的指向,函數返回後副本銷毀,調用者的指針變量未被修改。

內存圖解


調用前:
main 棧幀: a=10 (地址 0x1000), b=20 (地址 0x2000)
           p1=0x1000, p2=0x2000 (傳遞地址值)

swap_ptr_wrong 內部:
參數副本 p1=0x1000, p2=0x2000
p = p1 (0x1000)
p1 = p2 (0x2000)  // 只有局部 p1 變了
p2 = p  (0x1000)  // 只有局部 p2 變了
堆/全局區 0x1000 仍存 10, 0x2000 仍存 20

函數返回: 參數副本銷毀,main 中 a,b 地址值未變,數值未變。

swap_value 內部:
*p1 讀取 0x1000 → 10
*p2 讀取 0x2000 → 20
*p1 = 20  → 0x1000 寫入 20
*p2 = 10  → 0x2000 寫入 10
main 棧幀 a=20, b=10 真正交換。

若真要在函數內交換調用者的指針變量 (C 語言模擬引用)


// 需傳遞指針的指針 (二級指針)
void swap_ptr_correct(int **pp1, int **pp2) {
    int *temp = *pp1;
    *pp1 = *pp2;
    *pp2 = temp;
}

// 調用
int *pa = &a, *pb = &b;
swap_ptr_correct(&pa, &pb); // 現在 pa、pb 真正交換指向

C++ 參考參數簡化 (推薦)


void swap_cpp(int &a, int &b) { // 編譯器自動處理取址/解引用
    int t = a; a = b; b = t;
}
void swap_ptr_cpp(int *&p1, int *&p2) { // 指針引用
    int *t = p1; p1 = p2; p2 = t;
}

核心口訣

要改變調用者的變量,必須拿到該變量的地址,並通過解引用寫入新值。
交換數值 → 傳變量地址 (`int*`) → 解引用賦值 (`*p = ...`)
交換指針 → 傳指針地址 (`int**`) → 解引用賦值 (`*pp = ...`)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved