2011年4月19日 星期二

Call by value , Call by pointer , and Call by reference

  • Call by Value
    • 參數會在函式中建立一個獨立的物件
    • 不論在函式中如何改變這個參數的值,都不會影響呼叫端的物件
    • 在該函式結束之後,所有的臨時物件都會清除,包括 call by value 所產生的參數
    int main() { 
        int x = 5; 
        foo(x); 
    }
    
    void foo(int y) {    // 建立一個新的物件等同於傳入的物件
        y++;    //不會改變到原呼叫端的物件
    }
    
  • Call by Pointer
    • 參數不會建立物件的複本
    • 以物件的產生、呼叫的成本考慮,傳參考與傳指標是十分類似。但傳指標與傳參考最大的分別是,參考是常數,而指標是變數
    • 因此這個指標可以指向另一個位置,另一個更明顯的分別是所有的陣列傳遞都是以傳指標的方式達成
    int main() {
        int a = 5;
        int *x;
        x = &a;
        foo(x);
    }
    
    void foo(int *y) {   // 建立一個指標指向傳入物件的記憶體位置
        (*y)++;    // 修改此*y就是修改main的*x
        int b = 9;
        int *c;
        c = &b;
        y = c;    // Thinking:compare with " *y = *c " here, how about the variables in main()?
    }
    
  • Call by Reference
    • 參數不會建立物件的複本,它只會建立一個指向呼叫端物件的參考
    • 所以如果在函式中改變這個參數的內容(先決條件是這個參數未被宣告為 const),就會改變呼叫端參數的內容
    • 特別要注意的是,Call by reference的方式,一定要在初始化時就有指向的實體,而且不能改變
int main() { 
    int x = 5; 
    foo(x);    // 不用加& 
}

void foo(int &y) {    // 建立一個參考指向傳入物件的記憶體位置
    y++;    // 修改此y就是修改main的x,無法改變y所指向的記憶體位置
}