2-5:C++快速入门之引用,引用和指针的区别
文章目錄
- (1)引用的概念
- (2)引用的特點
- (3)常引用
- (4)引用的應用場景
- A:做參數
- B:做返回值
- (5)引用和指針
在第一次學習C語言指針時,許多教材上都會給出一個交換兩個變量值的例子,開始我們認為這樣交換就可以成功
void swap(int a,int b) {int temp=a;a=b;b=temp; }int main() {int a=1;int b=2;swap(a,b); }但學習完指針后,就明白了這樣的操作是不行的,因為每當調用函數時就會為該函數開辟一個新的空間,函數結束之后,空間也就被銷毀了,所以不可能交換成功。于是正確的寫法應該是這樣
void swap(int* x,int* y) {int temp=*x;*x=*y;*y=temp; }int main() {int a=1;int b=2;swap(&a,&b); }而在C++中我們引入一個新的概念——引用
- 但是請放心,引用的底層實現依然依靠的是指針
(1)引用的概念
簡單點來說:引用就是起別名,這一片內存空間名字叫a,然后再給它額外起一個名字,叫做b,a和b操控的是同一片內存空間。
從下面的這個動態調試的過程中,大家可以深刻的體會到取別名的意思
(2)引用的特點
(3)常引用
在C語言中我們知道,如果定義一個常整形,表示這個整形變量內容是不可以修改的,所以如果用普通引用去引用就會出錯
int main() {const int a=10;int& b=a;//錯誤,權限被放大,之前只可讀,賦值后卻可讀可寫了 }那么面對這樣的變量,如果仍然使用之前的引用方式是不可行的。這涉及到一個權限問題:變量a自身只能可讀,但是它被int& b引用后,反倒可以修改了,這就矛盾了。所以要解決這種權限問題,必須使用常引用
int main() {const int a=10;const int& b=a;//常引用 }- 指針和引用在賦值時,權限不能放大,但是可以縮小(這也就是為什么 int strlen(const char* str)中形參是const類型的)
- 常數具有常性,所以引用常數時,必須使用常引用
- C語言中,浮點型轉換為整型時,有一個中間過程,會涉及到一個中間變量,這個中間變量具有常性,必須使用常引用
關于常引用,確實C++在這方面有點麻煩,但是這個常引用也是有好處的,尤其體現在引用做形參。我們一般使用常引用作為形參,此時實參可以是變量也可以是常量,即便實參和形參存在類型轉換也是無妨的
void test(const DataType& x) {//形參使用常引用好處多多 }(4)引用的應用場景
A:做參數
我們現在就可以使用引用的方式交換兩個變量了
void Swap(int& x,int &y) {int temp=x;x=y;y=temp; }int main() {int a=1;int b=2;Swap(a,b); }B:做返回值
實參傳給形參時,如果不用指針或引用,那么形參就要拷貝一份,這一點相信大家是很明白的。但我們容易忽略的一點是——函數的返回值也屬于傳值,也就是說它不會將內容直接返回給調用該函數并接受返回值的變量,而是先給寄存器或內存(如果數據大的話要開辟更多空間)
- ret先給“臨時空間”,然后“臨時空間”再給receive
所以,引用也可以用于返回值。函數返回設為引用,然后在調用它的地方也進行引用,相當于只進行一次拷貝。
通過調試可以發現,receive和ret地址是一樣的,他們都是那一片內存空間的別名。
這里我們在后面再調用一次sum函數,最終輸出結果為7
使用調試,感受到這個過程
而如果再加入一句毫不相干的代碼,會發現最后輸出的竟然是一個隨機值?其實這是因為到這里的時候ret早就還給系統了。
所以:如果函數返回時,已經出了作用域,但此時假如返回對象還未歸還給系統,那么可以使用引用返回,但是如果已經還給系統了,則必須使用傳值返回。
(5)引用和指針
語法角度上講,引用是實體的別名,與實體共用統一內存空間,而從底層實現角度上講,引用其實是按照指針的方式進行的
從匯編角度可以看出這一點
引用和指針的區別如下
| 引用定義必須初始化 | 指針沒有要求 |
| 引用只能一個實體 | 指針在任何時候指向任何同類型的實體 |
| 沒有NULL引用 | 但有NULL指針 |
| 使用sizeof()表示引用類型的大小 | 使用sizeof表示地址空間所占字節數 |
| ++引用表示引用的實體增加1 | ++指針表示指針向后偏移一個類型的大小(字節) |
| 沒有多級引用 | 但有多級指針 |
| 引用較安全 | 指針較不安全 |
總結
以上是生活随笔為你收集整理的2-5:C++快速入门之引用,引用和指针的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 推动Windows的限制:USER和GD
- 下一篇: 8-2:C++继承之父类和子类对象赋值转