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 真正交換。
// 需傳遞指針的指針 (二級指針)
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 真正交換指向
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 = ...`)