標籤:c++參數傳遞
一般的變數聲明時就建立相應的記憶體空間,該空間用於儲存該變數的值。函數進行按值傳遞時,是將該變數值的拷貝傳給函數,因此在函數中將傳進來的值改變也不能改變變數的值。
指標變數和按指標傳遞。指標類型的變數在聲明後,根據作業系統的不同建立相應大小的記憶體空間,該空間上儲存的是一個地址,該地址指向一個變數。如果函數按指標進行傳遞參數,也是將變數的拷貝傳進來,但該變數是一個指向某記憶體單元的地址,對該變數進行解引用操作,改變其記憶體單中繼存放區的值,即可改變變數解引用後的值。
引用和按引用傳遞。引用是變數的別名。在聲明引用時,不對該引用分配記憶體空間,只是一個指向變數的別名。對引用操作既是對變數操作,所以函數在按引用傳遞變數時,如果改變引用的值,既是改變變數的值。
Void fun1(int& nTemp);
Void fun2(const int& nTemp);
fun1(100);
fun2(100);
函數fun1的參數是int型的引用變數,需要指向一塊記憶體空間,而100是常量,常量是不允許複製和修改的也不佔用記憶體空間,所以這個函數調用是錯的。(系統在傳遞參數是建立臨時變數,而臨時變數不能作為非const引用參數)
函數fun2的參數是const型的int引用變數,該變數在函數內部不能被修改,甚至不能有修改的風險,是唯讀。而系統這是會產生一個int型的臨時變數,臨時變數可以傳遞const型的參數,所以該函數可正確調用。
(C++編譯器的一個關於文法的限制,如果一個參數是以一個非const引用傳入的,那麼C++編譯器就有理由相信我們傳入的參數是可以在函數中修改的,並且這個修改的變數還是在函數外也是可以使用的,但是如果我們把一個臨時變數當成非const引用參數傳進來,則由於臨時變數的特殊性,程式員是不能操作臨時變數的,而且臨時變數在使用完成後會釋放,所以如果我們修改一個臨時變數實際上沒有意義的,所以C++編譯器就加入了臨時變數時不能作為非const引用的這個語意限制的,主要是限制這個非常規的用法的潛在錯誤。臨時變數實際上是可以作為左值的,這點在Thinking in C++的第一卷中的7.3節是有介紹的。非const引用只能指向非const同類型的對象,但是const引用可以初始化為不同但相關的類型的對象或者初始化為右值。)
(臨時變數:在C/C++中,其實從真正的意義上的臨時變數是看不見的,就是說它們不會出現在你的代碼中。臨時變數並不是我們臨時建立的變數,而是,由編譯器在程式需要的時候自動產生的臨時性變數,它們並不在代碼中出現,但是它們又是確實存在的,而臨時變數的產生時機通常是在函數參數傳遞時發生類型轉換,以及函數傳回值時被建立。)
Int* pPrint = new int;
Void fun3(int* pTemp){pTemp= new int(); }
Void fun4(int* &pTemp){pTemp = new int(); }
fun3(pPrint);
fun4(pPrint);
函數fun3獲得實參pPrint的拷貝,該變數的內容是地址,而函數體又賦給一個新的地址,由於是實參的拷貝,所以不能改變實參的值,即pPrint的值不變。
函數fun4參數是int型指標的引用,是int指標本身,通過函數體改變該值,可以改變實參pPrint的值。
返回引用。如果函數返回的是局部變數,局部變數在函數結束後銷毀,引用指向一個被銷毀的記憶體空間是不允許的,所以返回局部變數的引用是錯誤的。
C++參數傳遞(引用,臨時變數)