C++中傳值傳指針傳引用的區別

當調用函數時,傳遞的參數有傳值、傳指針、傳引用這三種形式。

直接傳值是直接開闢了一個跟主函數實參一樣的空間(地址不一樣),裏面存放了了跟實參一樣大小的值,就相當於數值大小相同但是位置不同。你在這個調用函數裏使用這個一樣大小的值,完全不影響主函數實參的值。就好比主函數的空間就是一棟樓,裏面的一個房間裏放着一些東西(相當於實參變量值)。現在我調用了一個函數,就相當於我在另一棟樓的另一個房間裏面,把剛纔第一個放東西的房間裏面存的東西完全複製過來,所以你操作現在這個房間裏面的東西,完全不影響原來的房間的東西呀。

傳指針就不一樣了。指針就是地址,我們要去找一個房間裏面的東西,那麼你得先找到門牌號,才能對照着門牌號去找到房間,從而找到你想要的東西,這就是指針的使用原理。傳指針就是把實參的地址傳過去了,而不是像剛纔傳值一樣,直接開闢一個新的空間去複製數值,而是開闢了一個新的空間把實參的地址複製了過去。主函數的空間就是一棟樓,裏面的一個房間放着一些東西(相當於實參變量值),這個房間有個門牌號(也就是實參的地址)。現在調用函數,就好比我把他家的門牌號(實參的指針)給你,跟你說你按照這個門牌號去找這個房間,然後再去找裏面的東西。這樣一來,你根據門牌號找到了原來的房間,一旦修改房間裏面的東西,就一定會產生改變。所以根據指針修改指向的變量時,如果調用函數進行了修改,主函數的變量也就被修改了。

傳引用就是傳指針的升級版。引用可以看成變量的別稱,就好像Tony老師的本名就叫趙鐵柱一樣,名字不一樣但是人就是那一個人。所以你傳引用的時候,修改了調用函數裏的傳遞參數值,主函數的對應變量也會隨之改變。但是原理還是傳遞指針,也就是地址。傳引用的時候實際上是拷貝了實參的地址,然後你在調用函數裏的操作表面上看是對變量的直接賦值,實際上是通過找到地址再改變變量的,這是一種間接尋址。但是爲啥不直接用指針找地址再操作呢?而是封裝成引用的外表了,很大的原因是安全。因爲直接指針操作,那你很可能改變了指針,然後就找不到原來的地址了。就好比,我現在要去找房間(調用了其他函數要去訪問主函數的實參變量值),然後給了你一塊門牌號(相當於指針,也就是地址),萬一你一不小心掉溝裏了,門牌號弄丟了(指針被錯誤的修改),那你就找不到原來的房子了呀,你要是還繼續去找錯誤的房子,把別人家房子裏面的東西改了,等下直接程序就出錯了(走錯家門很危險的…)。所以別人就是怕你亂改,直接就給你封裝好了。引用其實還可以讓代碼更加簡潔清晰,一目瞭然(因爲就相當於同一個變量在操作的感覺)。C語言是沒有傳引用的,C++把它加上了。原因我覺得是更方便了,也更安全了。

下面看一下代碼吧

#include<iostream>
using namespace std;
/*
	author: James-J
	time: 2019/02/28
*/
// 傳值 
void fun_1(int num){
	num = 100;
	cout<<"In function 1 num = "<<num<<endl;
} 
// 傳指針 
void fun_2(int *num){
	*num = 200;  // *num就是根據指針num找原來位置的變量
	cout<<"In function 2 num = "<<*num<<endl;
}
// 傳引用 
void fun_3(int &num){
	num = 300;  // 引用的操作看起來就像是直接賦值一樣
	cout<<"In function 3 num = "<<num<<endl;
}

int main(){
	int num = 0;
	cout<<"num = "<<num<<endl<<endl;
	// 傳值 
	cout<<"Before function 1 num = "<<num<<endl;
	fun_1(num);
	cout<<"After function 1 num = "<<num<<endl<<endl;
	// 傳指針
	cout<<"Before function 2 num = "<<num<<endl;
	fun_2(&num);  // 地址傳過去
	cout<<"After function 2 num = "<<num<<endl<<endl;
	// 傳引用
	cout<<"Before function 3 num = "<<num<<endl;
	fun_3(num);
	cout<<"After function 3 num = "<<num<<endl<<endl;
	return 0;
} 

結果

 

根據上面分析的,直接賦值時,調用函數改變形參值,主函數實參不改變。而傳指針和傳引用會改變,傳指針需要進行取地址(&num)呀、找變量(*num)的操作,而傳引用沒有那麼複雜,看起來就像是直接賦值一樣,但其實傳引用也是一些列地址的操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章