【C++ 筆記】參考(Reference) - part 14
【C++ 筆記】參考(Reference) - part 14
很感謝你點進來這篇文章。
你好,我並不是什麼 C++、程式語言的專家,所以本文若有些錯誤麻煩請各位鞭大力一點,我極需各位的指正及指導!!本系列文章的性質主要以詼諧的口吻,一派輕鬆的態度自學程式語言,如果你喜歡,麻煩留言說聲文章讚讚吧!
簡介(Introduction)
參考(Reference)是物件的別名(Alias),也就是替代名稱,對參考名稱存取時該有什麼行為,都參考了來源物件該有的行為,在 C++ 中,「物件」這個名詞,不單只是指類別的實例,而是指記憶體中的一塊資料。
所以參考變數是現存變數的另一個名字,將參考初始化為某個變數,就可以使用該參考名稱或變數名稱來指向變數。
參考常常與指標做比較,原因是他們的性質相同,同樣地,我們先從定義上來看:
:::success
指標(Pointer):
- 指標是一種變數,用來儲存其他變數的記憶體位址。指標可以直接對記憶體進行運算。
- 宣告時使用星號(
*)來表示,例如:int* ptr;表示 ptr 是一個指向整數的指標。
:::
:::info
參考(Reference):
- 參考是另一個變數的別名,並且必須在宣告時初始化。參考可以直接對原始變數進行運算,不需要額外的解參考運算(Deference)。
- 宣告時使用
&符號,例如:int& ref = original;表示ref是original的參考。
:::
筆者列以下表格比較兩者差異:
| Items | Pointer | Reference |
|---|---|---|
| 初始化 | 可以不初始化,後續可重新指向其他變數 | 必須在宣告時初始化,且無法更改指向 |
| NULL | 可以為空(nullptr),表示不指向任何有效地址 | 不能為空,必須始終指向一個有效的變數 |
| 語法 | 使用星號(*)來宣告和解參考 | 使用 & 來宣告,如普通變數一般使用方式 |
| 靈活性 | 可以指向不同型態的變數,包括指標本身 | 只能用作變數的別名,不支援指向其他參考或空值 |
| 效能 | 可能會導致額外的解參考開銷 | 避免了不必要的資料複製,提升效能 |
有關參考的相關應用,如下四點:
- 修改函數中傳遞的參數
- 避免複製大型結構
- 在 For Each 迴圈中修改所有物件
- For Each 迴圈以避免物件的複製
Source:https://www.geeksforgeeks.org/references-in-cpp/
For Each Loop 相關資訊:https://zh.wikipedia.org/zh-tw/Foreach%E5%BE%AA%E7%8E%AF
其實,參考就像是一個人的綽號,一個人可以有很多的綽號,像是:彬彬、呆呆等等,無論有多少個綽號,這些都是指同一個人的意思,同一個人就是最原始的自己,所以是原始變數。
建立參考(Create a Reference)
假設我們有個原始變數叫做 i:
1 | int i = 0; |
那麼我們可以替 i 宣告參考變數:
1 | int& r = i; |
& 運算子放置於資料型態後方可用於定義一個參考。
以下是一個範例:
1 |
|
Source:https://www.geeksforgeeks.org/references-in-cpp/
輸出結果:
1 | x = 20 |
先前我們有談過函數的參數傳遞,其中有所謂的傳參考呼叫,詳情請至我的筆記 part 11,「傳送門點我」。
藉參考回傳(Return by reference)
在 C++ 中,參考也可當成回傳值使用,如同指標的做法一般。
但是必須要注意以下這三點,才能好好使用 reference:
- 作用域(Scope):當函數回傳一個參考時,必須確保被參考的物件在函數結束後仍然有效。回傳局域變數的參考是無效的,因為局域變數在函數結束後會被銷毀。
- 修改原始數據:回傳的參考允許呼叫者直接修改原始數據,可能導致意外的副作用。如果不希望修改原始數據,應使用 const 修飾詞來回傳常數參考。
- 靜態變數(static)的使用:可安全回傳靜態變數的參考,因為靜態變數在整個程式執行期間都存在。
以下是個範例:
1 |
|
輸出結果:
1 | 改變前的值: |
程式碼解釋:
1 | setValues(1) = 20.23; |
由於函數中回傳的是 vals[i] 的參考,呼叫後可以視為以下的程式碼,結果是相同的:
1 | vals[1] = 20.23; |
但是在這邊使用函數回傳參考值,可實現”避免了不必要的資料複製,提升效能”這句話。
總之,setValues 函數回傳 vals 陣列中指定索引的元素的參考。這樣可以直接通過這個參考來修改陣列中的值。
有關於作用域問題,以下是一個錯誤示範:
1 |
|
正確示範如下:
1 |
|
參考資料
Return by reference in C++ with Examples - GeeksforGeeks
C++ 筆記 (Reference & Pointer) - HackMD


