現在,假設我要寫一個函數,這個函數是交換二個整數,也就是 a 的值給 b, b 的值給 a,該怎麼寫?這種問題是一般初學者最常犯的錯誤 – 使用 call by value。下面的例子說明了為什麼不能使用 call by value 的方式進行 swap 的動作。在看此例的執行結果時,手邊一樣先準備好紙跟筆,畫出各變數的記憶體位置及儲存值,對學習會很很大的幫助。
原始碼:
// ====================================
// FileName: CallByValue.cpp
// Author : Edison.Shih.
// Complier: VC 2008
#include <stdio.h>
// ====================================
void Swap_V(int a, int b)
{
int c;
printf("\n=== swap_v function initial ===\n");
printf(" a = %6d, b = %6d\n", a, b);
printf(" &a = %06X, &b = %06X\n", &a,&b);
c = a;
a = b;
b = c;
printf("\n=== swap_v function swap end ===\n");
printf(" a = %6d, b = %6d\n", a, b);
printf(" &a = %06X, &b = %06X\n", &a,&b);
}
// ====================================
int main(int argc, char **argv)
{
int a=10;
int b=5;
printf("\n *=== before swap in main ===* \n");
printf(" a = %6d, b = %6d\n", a, b);
printf(" &a = %06X, &b = %06X\n", &a,&b);
Swap_V(a, b);
printf("\n *=== after swap in main ===* \n");
printf(" a = %6d, b = %6d\n", a, b);
printf(" &a = %06X, &b = %06X\n", &a,&b);
return 0;
}
執行結果:
*=== before swap in main ===*
a = 10, b = 5
&a = 12FF60, &b = 12FF54
=== swap_v function initial ===
a = 10, b = 5
&a = 12FE7C, &b = 12FE80
=== swap_v function swap end ===
a = 5, b = 10
&a = 12FE7C, &b = 12FE80
*=== after swap in main ===*
a = 10, b = 5
&a = 12FF60, &b = 12FF54
說明:
1. 在Swap_V(a, b);之前,記憶體配置圖如下
儲存值 |
5 |
10 |
|
…….. |
…….. |
…….. |
記憶體位址 |
12FF54 |
12FF60 |
…….. |
…….. |
…….. |
…….. |
|
主函b |
主函a |
|
|
|
|
2. 在剛進入 Swap_V(a, b)時,OS將會再配置二個空間,分別接主函式的a, b 值,記憶體配置圖如下
儲存值 |
5 |
10 |
|
…….. |
5 |
10 |
記憶體位址 |
12FF54 |
12FF60 |
…….. |
…….. |
12FF7C |
12FF80 |
|
主函b |
主函a |
|
|
副函a |
副函b |
3. 當 Swap_V(a,b) 執行完,準備要返回 main() 時,副函式的 a, b值的確有交換過
儲存值 |
5 |
10 |
|
…….. |
5 |
10 |
記憶體位址 |
12FF54 |
12FF60 |
…….. |
…….. |
12FF7C |
12FF80 |
|
主函b |
主函a |
|
|
副函a |
副函b |
4. Swap_V(a,b) 執行完回到 main()後,剛剛由 OS 配置的記憶體釋放回系統,但是可以明顯發現,從頭到尾 main() 的a, b值都沒有動過,有動過的只是OS配出出來新的變數而已。
儲存值 |
5 |
10 |
|
…….. |
…….. |
…….. |
記憶體位址 |
12FF54 |
12FF60 |
…….. |
…….. |
…….. |
…….. |
|
主函b |
主函a |
|
|
|
|
所以,如果要交換 a, b二值的話,使用 call by value 是沒用的