天天看點

C++學習筆記——引用變量、參數傳遞、傳回值1.引用變量2.函數參數、函數傳回值傳遞

1.引用變量

(1)什麼是引用變量?為什麼要引入引用變量?

(1)應用變量是已定義變量的一個别名。

(2)引用變量的底部實際上有一根指針,引用的傳遞資料的速度與指針的傳遞資料速度一樣快,都是四個位元組。但是引用傳遞比指針傳遞更好用,因為它的形式更好。

(2)如何定義引用變量?

如下面的例子:

int x; 
int &y=x; 
           

(3)引用變量與正常變量有什麼不同之處?

  • 正常變量在作為函數參數傳遞時,操作的是資料的副本,而引用變量作為函數參數傳遞時操作的是原始資料。
  • 正常變量作為函數參數或傳回值傳遞時,傳遞的是整包資料,而引用變量傳遞的其實相當于一個指針,故其速度很快。
  • 另外使用引用變量的限制比正常變量多。

(4)引用變量作為函數參數傳遞有什麼限制?

傳遞引用變量的限制比較嚴格。普通變量作為函數參數傳遞,實參可以以表達式或字面值的形式傳遞,而引用變量則不行。也就是C++不允許将表達式傳遞給引用。但是可以将字面值和表達式傳遞給const引用。

注意:如果将表達式或者可轉為正确類型的字面值傳遞給引用标量,C++将會給出警告。而早期的C++其實是允許将表達式傳遞給引用的,它采取的方案是,首先建立一個臨時變量,然後将表達式的值存儲到臨時變量中,然後臨時變量可以傳遞給引用變量。在現在的C++用,隻有參數為const引用時,C++才會采取上述方案。對于形參為 const引用的C++函數,如果實參不比對,其行為類似于按值傳遞,為確定原始資料不被修改,将建立臨時變量來存儲值。

(5)如果函數參數确實為const引用,編譯器什麼情況下才會建立臨時變量呢?

  • 實參類型正确,但非左值。(例如:函數接受傳遞的引用變量為int型,但是實際傳遞的是一個字面值5或者 x+3,其中x是int型。字面值和表達式就不屬于左值。)
  • 實參類型不正确,但是可轉換為正确類型。(例如:函數接受傳遞的引用變量為int型,但是實際傳遞的是一個double型變量,因為double型變量可以轉為int型。)

(6)什麼是左值?

左值包括正常變量和const變量,左值原本應該是可以改變的值,引入const後,其概念變為可通過指針通路的值。

(7)引用變量與指針的差別與聯系?

(1)相似之處:
  • 定義非常相似。
  • 作為函數參數傳遞都是操作原始資料(位址概念)。
(2)不同之處:
  • 二者的表示方法不同。
  • 引用變量必須在聲明時初始化,而指針變量則不需要。(引用的概念更接近于const指針)。
  • 引用隻是一個别名,而指針變量具有實體。
  • 引用變量不需要使用解引用運算符,而指針需要。
  • 引用必須在聲明時初始化,而且綁定變量後不可更改。但是指針在聲明時可以不進行初始化,而且可以指向别的同類型變量。
  • 指針和引用使用自增自減運算符時,其二者意義不同。
  • 傳遞引用和指針,程式員可以通過是否設定const來決定接受改變資料是否影響原始資料。
  • 如果想要達到的效果是想改變原始資料的,則不需要添加const。
  • 如果想要達到的效果是不想要改變原始資料,那麼應該添加const,這樣接受者即使改變了傳遞的對象中的資料,也不影響原始對象中的資料。
  • 若引用變量作為函數傳回值,傳遞者無需知道接受者以什麼形式接受傳回對象。這是引用變量的優點之一。(例如:return一個value值(非local變量),接受可以通過引用變量接受)

(8)引用變量适用的場景有哪些?

主要适用于函數參數函數傳回值傳遞。具體說來:

(1)從函數參數的資料類型的角度來說

  • 用于結構
  • 用于類對象
(2)從位置的角度來說
  • 用于函數形參
  • 用于函數傳回值(什麼情況下傳回引用?)

(9)為什麼要盡可能将函數引用形參設為const?

  • 避免無意中修改(本不該)資料
  • 能夠處理const和非const實參(非const參數隻能接受非const資料)
  • 能夠處理實參為非左值的情況

2.函數參數、函數傳回值傳遞

(1)作為函數參數和函數傳回值,使用值傳遞、指針傳遞、還是引用傳遞依據的原則是什麼?

  • 傳遞的資料為數組時,隻能通過指針傳遞,原始資料允許被改變的使用普通指針,不允許被改變的使用const指針。
  • 傳遞的資料允許修改原始資料時:小型資料(内置資料類型)使用指針,大型資料(大型結構、類對象)使用指針或引用。
  • 傳遞的資料不允許修改原始資料時:小型資料按值傳遞,大型資料按const指針或const引用傳遞。 
  • 函數參數傳遞盡量以通過引用變量傳遞。
  • 函數傳回值傳遞如果可以的話盡量以通過引用變量傳遞。
注:後兩點采用的是侯捷老師的觀點。                           

(2)什麼情況下函數傳回值傳遞不可以通過引用變量傳遞?

要通過函數結果存放的位置判斷是否能夠使用引用變量傳遞資料。

情況一:函數的運算結果放在原來已有的空間用。(發起此函數調用前,變量(資料的存儲記憶體)已經存在。)

情況二:運算結果存儲在被調函數建立的内容空間中。(發起函數調用後,在執行此函數時,在函數内部建立的變量(申請的棧記憶體)。這裡建立的對象為local對象)

情況一可以通過引用變量傳遞資料,因為當函數執行完以後,隻是通路了原本已經存在的記憶體空間,并且在函數執行完以後該記憶體空間還沒有被回收,可以繼續通路。是以可以傳回引用該記憶體空間中資料的引用變量

而情況二不能夠通過引用變量傳遞資料。因為,資料存儲在函數運作過程中配置設定的記憶體空間中,當函數執行完以後,期間配置設定的記憶體就自動回收了。相當于引用了一塊已經回收的記憶體空間中的資料,這些資料顯然是沒有意義的。

說明:上述觀點整理自《C++ primer plus》書籍和侯捷老師C++視訊。

繼續閱讀