程式設計 微知識(八)C/C++ Call by value、Call by address、Call by reference

Call by value: 參數以數值方式傳遞,複製一份到另一個呼叫此參數的副程式予以使用。

Call by address(Call by value of pointer): 將參數以記憶體位置的方式傳到呼叫此參數的副程式,副程式需要有一個指標來指到這個參數的記憶體位置,但call by addres本質上也是call by value,只不過那個value剛好就是address而已。

Call by reference: 將參數以數值的方式傳遞到呼叫此參數的副程式,副程式需要有一個參考來接收這個參數,這是只有C++才有的,C是沒有的; 且因為call by address的內容為指向的位置,所以傳址的指標本身然仍然有記憶體位置,但是傳參考是不會有的。也因此C++的Call by reference本質上不是call by value,這也是和call by address之間的差別。

本文以C++實作執行。


Call by value: 由於是main裡面的變數被複製到副程式去,所以這兩個變數是不同記憶體空間的,所以在副程式裡執行過後的結果不會影響到原本main主程式裡的數值。



Call by pointer: 由於是將參數以記憶體位置的方式傳到呼叫此參數的副程式,同時副程式以指標來指到到這個參數的記憶體位置,所以主程式和副程式是使用相同記憶體位置的內容,所以當副程式的內容更改時,同時也會影響到主程式的數值,但是傳指標仍然是call by value,只是那個value是指標本身,複製的內容也是指標本身,只不過那個value剛好就是address而已。


Call by reference: C++才有的,call by reference 和 call by address的差別主要在於後者的指標它的內容為指向的位置,所以他本身仍然有記憶體位置但是前者是不會有的。

實作程式碼:

#include <iostream>
using namespace std;

void CallByValue_Plus(int a)
{
    a++;
	cout << "a in the CallByValue_Plus:" << a << endl;
	cout << "address of a in the CallByValue_Plus:" << &a << endl;
}

void CallByAddress_Plus(int* b)
{
    (*b)++;
	cout << "*b in the CallByAddress_Plus:" << *b << endl;
	cout << "address of b in the CallByAddress_Plus:" << &b << endl;
}
void CallByReference_Plus(int& c)
{
    c++;
	cout << "c in the CallByReference_Plus:" << c << endl;
	cout << "address of c in the CallByReference_Plus:" << &c << endl;
}

int main()
{
	int a = 10;
	int b = 100;
	int c = 1000;

	cout << "a: " << a << endl;
	cout << "b: " << b << endl;
	cout << "c: " << c << endl;

	CallByValue_Plus(a);
	CallByAddress_Plus(&b);
	CallByReference_Plus(c);
	cout << "After CallByValue_Plus(a), a in the main "<< a << endl;
	cout << "After CallByAddress_Plus(b), b in the main: " << b << endl;
	cout << "After CallByReference_Plus(c), c in the main: " << c << endl;
	cout << "After CallByValue_Plus(a), address of a in the main " << &a << endl;
	cout << "After CallByAddress_Plus(b), address of b in the main: " << &b << endl;
	cout << "After CallByReference_Plus(c), address of c in the main: " << &c << endl;

	system("pause");
	return 0;
}

執行結果如下:

從結果可以看到:
Call by value: 參數在被副程式呼叫之後,主程式的參數的值不會受到副程式的影響,以及副程式和主程式所使用的參數的記憶體位置是不同的。

Call by address:參數在被副程式呼叫之後,主程式的值會受到副程式的影響,但副程式和主程式所使用的參數的記憶體位置是不同的。

Call by reference:參數在被副程式呼叫之後,主程式的值會受到副程式的影響,以及副程式和主程式所使用的參數的記憶體位置是相同的。

有夢最美 築夢踏實

活在當下 認真過每一天

我是阿夢 也是Ace