close

現在,假設我要寫一個函數,這個函數是交換二個整數,也就是 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 是沒用的

arrow
arrow
    全站熱搜

    Edison 發表在 痞客邦 留言(1) 人氣()