1. 指針和引用
1.1 指針和引用概述
1.1.1 指針
對於char* ptr,ptr爲指向char的指針,即char*類型的變量ptr保存的是一個char對象的地址,而char可加限定詞const、volatile等。(char可換爲其他類型)
如下所示,p中存儲的是c的地址,c中存儲的是‘A’字符
char c = 'A';
char* p = &c;
通過*可取p所指向的內容,通過&可取p的地址,即:
*p == c的內容 == 'A'
p == c的地址 == &c
&p == p的地址
1.1.2 引用
引用相當於一個對象的別名,主要用於函數參數和返回值類型。int&表示對int類型的引用(int可換爲其他類型)
int i = 1;
int& r = i; // r指向了i的空間,此時對i和r的操作將是相同的
i = 2;
cout << r << endl; // 輸出 2
r = 3;
cout << i << endl; // 輸出 3
可以認爲引用就是將 i 和 r 相關聯(綁定)了,使得 i 和 r 代表了相同的一塊空間
1.1.3 引用與指針的區別
- 引用一旦指向某一對象就不可更改:
如上面程序,引用後的 r 就和普通的整形變量沒有什麼區別(若不考慮 i 的存在,完全可以把int i = 1; int& r = i;
當成int r = 1;
來看待)。引用即是將兩個變量進行了綁定,而指針僅僅是存儲了指向內存的地址,所以通過引用名(如r
)可以直接訪問指向的內存,而通過指針名(如p
)卻只能訪問到地址,要通過*(如*p
)才能訪問到地址所指的內存 - 對引用的操作將與所指對象同步,而不是像操作指針一樣會改變指針的指向:
如引用的++操作將直接使得指向內容+1,而指針的++會讓指針指向下一個地址。如int i = 1; int& r = i; int* p = &r;
此時 r 和 p 都指向了 i 所在的空間,但其意義是完全不同的,p是開闢了一個內存來存儲 i 的地址,而 r 就是 i - 引用不可以爲空,但指針可以爲空:
正因如此指針在使用前都需要進行判空操作,而引用變量若不進行初始化甚至無法通過編譯
雖說引用和指針有許多區別,但兩者在本質上是相同的,可以根據彙編代碼看出:
引用int& ref = i;
8048727: 8d 44 24 1c lea 0x1c(%esp), %eax // esp寄存器裏的變量i的地址傳給eax
804872b: 89 44 24 18 mov %eax, 0x18(%esp) // 將寄存器eax中的內容(i的地址)傳給寄存器中的變量ref
指針int* p = &i;
8048777: 8d 44 24 1c lea 0x1c(%esp), %eax // esp寄存器裏的變量i的地址傳給eax
804877b: 89 44 24 10 mov %eax, 0x10(%esp) // 將寄存器eax中的內容(i的地址)傳給寄存器中的變量p
引用和指針在彙編上的實現是完全相同的,即是說引用的本質其實就是指針,只是比指針更加安全。
1.1.4 const關鍵字
相信很多人會有疑問,引用和const指針是不是幾乎是相同的呢?前面已經說了引用的本質其實就是指針,只是在指針上增加了一些規則,使得它更加安全。實際上,若不考慮賦空值,那麼:
- 引用
type& x
等於 const指針const type* x
- const引用
const type& x
等於 指向const的const指針const type* const x
1.2 值傳遞、指針傳遞、引用傳遞
1.2.1 值傳遞
值傳遞是形參對實參的拷貝,即將實參賦值到了形參上,改變形參的值並不會影響外部實參的值。從被調用函數的角度來說,值傳遞是單向的,參數的值只能傳入,不能傳出。當函數內部需要修改參數,並且不希望這個改變影響調用者時,採用值傳遞。
1.2.2 指針傳遞
形參爲指向實參地址的指針,當對形參的指向操作時,就相當於對實參本身進行的操作,但對於形參的操作並不會改變實參的值(改變形參存儲的地址不會改變實參的指向),因爲指針傳遞的本質也是值的傳遞(將指針變量存儲的地址複製給形參的變量)
1.2.3 引用傳遞:
形參相當於是實參的“別名”,對形參的操作其實就是對實參的操作,在引用傳遞過程中,被調函數的形式參數雖然也作爲局部變量在棧中開闢了內存空間,但是這時存放的是由主調函數放進來的實參變量的地址。被調函數對形參的任何操作都被處理成間接尋址,即通過棧中存放的地址訪問主調函數中的實參變量。正因爲如此,被調函數對形參做的任何操作都影響了主調函數中的實參變量。
參考文獻:
https://blog.csdn.net/listening_music/article/details/6921608
https://www.cnblogs.com/yanlingyin/archive/2011/12/07/2278961.html
二級指針