C++ - call by value、call by pointer、Call by reference (C++軟體開發 - 傳值、傳址、傳參考 概念與實例)

◎基本概念
  • 引數 Argument 又叫做 actual parameter (實際參數)
  • 參數 Parameter 通常指 formal parameter (形式參數)


當我們呼叫function時,有時會需要傳入Arguments(actual parameter),而function需要宣告他會如何接受這些Arguments(actual parameter),而這些用來宣告的Variables我們稱作function的formal parameters。

C++的參數傳遞方式主要有三種:傳值( call by value)、傳址(call by address)、傳參考(call by reference)。 在C語言裡裡,傳遞參數的2種方式,分別是Call by value、Call by pointer,而在C++裡多了一個Call by reference的方法。



◎call by value

  • formal parameters為一integer,接受某個值。
  • 當傳遞Argument時,複製actual parameter的到formal parameters。
  • actual parameter與formal parameters各別佔有自己的記憶體,互不相干。
  • formal parameter的變動,並不影響我們用來呼叫function傳入的actual parameter。

#include "stdafx.h"
#include <iostream>
using namespace std;

void EqualToY(int a, int b) {

    cout << " Before a = b , a :" << a << " Addres : " << &a << endl;
    cout << " Before a = b , b :" << b << " Addres : " << &b << endl << endl;

    a = b;

    cout << " After a = b , a :" << a << " Addres : " << &a << endl;
    cout << " After a = b , b :" << b << " Addres : " << &b << endl << endl;

}
int main() {

    int x, y;
    x = 10 ;
    y = 5 ;

    cout << " Before EqualToY() , x :" << x <<" Addres : "<< &x << endl;
    cout << " Before EqualToY() , y :" << y <<" Addres : "<< &y << endl << endl;

    EqualToY(x, y);

    cout << " After EqualToY() , x :" << x << " Addres :" << &x << endl;
    cout << " After EqualToY() , y :" << y << " Addres :" << &y << endl << endl;

    return 0;
}

 
------------------------------------------------------------------









◎call by pointer 

  • formal parameters為一pointer指向某個integer變數,儲存位址。
  • 當傳遞Argument時,複製actual parameter的地址到formal parameters。
  • 在呼叫function內可以利用傳入的actual parameter的address(*a、*b)去指向到actual parameter的位址進行操作。
  • formal parameter的變動,不會直接影響actual parameter。a與b只是存x,y的位址(actual parameter的位址),因此可以利用*a 、*b到x,y的記憶體去進行actual parameter的變動,藉此可以影響我們用來呼叫function傳入的actual parameter。


#include "stdafx.h"
#include <iostream>
using namespace std;

void EqualToY(int *a, int *b) {

    cout << " Before a = b , a :" << *a << " Addres : " << a << endl;
    cout << " Before a = b , b :" << *b << " Addres : " << b << endl << endl;

    *a = *b;

    cout << " After a = b , a :" << *a << " Addres : " << a << endl;
    cout << " After a = b , b :" << *b << " Addres : " << b << endl << endl;

}
int main() {

    int x, y;
    x = 10 ;
    y = 5 ;

    cout << " Before EqualToY() , x :" << x <<" Addres : "<< &x << endl;
    cout << " Before EqualToY() , y :" << y <<" Addres : "<< &y << endl << endl;

    EqualToY(&x, &y);

    cout << " After EqualToY() , x :" << x << " Addres :" << &x << endl;
    cout << " After EqualToY() , y :" << y << " Addres :" << &y << endl << endl;

    return 0;
}
-----------------------------------------------------









◎call by reference
  • 當傳遞Argument時,複製actual parameter的參考到formal parameters。
  • 在呼叫function傳入的formal parameter與actual parameter共享相同位址相同變數,只是名稱不同。
  • formal parameters又稱為actual parameter的alias(別名)。
  • actual parameter與formal parameters相互影響。
  • formal parameter的變動,會直接影響我們用來呼叫function傳入的actual parameter。 
  • 在初始化時就指向實體,而且不能改變。如下例 : 進入function後,a已經為x,不能再做更動。
  • 呼叫端希望保留actual parameter在function內的變動,適合使用Call by reference。
  • 大型物件的傳遞,適合使用Call by reference,不會產生額外大量的記憶體消耗。
#include "stdafx.h"
#include <iostream>
using namespace std;

void EqualToY(int &a, int &b) {

    cout << " Before a = b , a :" << a << " Addres : " << &a << endl;
    cout << " Before a = b , b :" << b << " Addres : " << &b << endl << endl;

    a = b;

    cout << " After a = b , a :" << a << " Addres : " << &a << endl;
    cout << " After a = b , b :" << b << " Addres : " << &b << endl << endl;

}

int main() {

    int x, y;
    x = 10 ;
    y = 5 ;

    cout << " Before EqualToY() , x :" << x <<" Addres : "<< &x << endl;
    cout << " Before EqualToY() , y :" << y <<" Addres : "<< &y << endl << endl;

    EqualToY(x, y);

    cout << " After EqualToY() , x :" << x << " Addres :" << &x << endl;
    cout << " After EqualToY() , y :" << y << " Addres :" << &y << endl << endl;

    return 0;
}
-----------------------------------------









◎By the way

&擺在值類型宣告後面 如: int &x,則為參考 ; &擺在等號後面 如 : int *x = &a,則為取址。

留言