不少編程老手對傳值,傳地址,傳引用的區別搞的也不會很清楚,今天我就花一點時間再次介紹一下這些概念的本質。編程
其實,不用分爲三類,只有兩類便可。傳值和傳引用。爲何會出現傳地址(即傳指針)呢?本質就是你們一致對傳值和傳地址概念的理解錯誤致使,也是對指針的概念的理解錯誤致使。
函數
指針:(簡單補充一下)其實很簡單,指針就是一個變量,若是非要說是一個特殊的變量也不爲過,由於指針的初始化和解引用等不一樣的操做方式而已。就內存的分佈來講,指針和一個變量在內存中存放是沒有任何區別的,無非指針存放的是變量的地址,就是這麼簡單。spa
定義:
指針
傳值:可能不少人都據說,傳值無非就是實參拷貝傳遞給形參。這句話沒有錯,可是理解起來仍是有點抽象。一句話,傳值就是把實參賦值給形參,賦值完畢後實參就和形參沒有任何聯繫,對形參的修改就不會影響到實參。
對象
傳地址:爲何說傳地址也是一種傳值呢?由於傳地址是把實參地址的拷貝傳遞給形參。仍是一句話,傳地址就是把實參的地址複製給形參。複製完畢後實參的地址和形參的地址沒有任何聯繫,對實參形參地址的修改不會影響到實參, 可是對形參地址所指向對象的修改卻直接反應在實參中,由於形參指向的對象就是形參的對象。
內存
傳引用:傳引用本質沒有任何實參的拷貝,一句話,就是讓另一個變量也執行該實參。就是兩個變量指向同一個對象。這是對形參的修改,必然反映到實參上。
io
區別:效率
(1):傳遞引用給函數與傳遞指針的效果是同樣的。這時,被調函數的形參就成爲原來主調函數中的實參變量或對象的一個別名來使用,因此在被調函數中對形參變量的操做就是對其相應的目標對象(在主調函數中)的操做。變量
(2):使用引用傳遞函數的參數,在內存中並無產生實參的副本,它是直接對實參操做;而使用通常變量傳遞函數的參數,當發生函數調用時,須要給形參分配存儲單元,形參變量是實參變量的副本;若是傳遞的是對象,還將調用拷貝構造函數。所以,當參數傳遞的數據較大時,用引用比用通常變量傳遞參數的效率和所佔空間都好。構造函數
(3):使用指針做爲函數的參數雖然也能達到與使用引用的效果,可是,在被調函數中一樣要給形參分配存儲單元,且須要重複使用"*指針變量名"的形式進行運算,這很容易產生錯誤且程序的閱讀性較差;另外一方面,在主調函數的調用點處,必須用變量的地址做爲實參。而引用更容易使用,更清晰。
本質: 傳值和傳指針都是傳值方式,除了傳引用以外