具體解釋C 引用 帶你走進引用的世界

2021-09-08 12:53:33 字數 4094 閱讀 7148



一、介紹引用

首先說引用是什麼,大家能夠記住,引用就是乙個別名,比方小王有個綽號叫小狗。他的媽媽喊小狗回家吃飯。那就是在喊小王回家吃飯。

接下來我們用兩行**來宣告乙個引用(就拿小王和小狗來說吧):

int xiaow;

int &xiaog=xiaow;

上面就是乙個引用,說明幾點要注意的地方:

1.&不是取位址符。而是引用運算子;

2.xiaog是xiaow的別名,所以這兩個變數的值和位址都是一樣的;

3.引用僅僅能初始化。而不能先宣告再賦值,由於引用就相當於乙個常量;

4.在宣告乙個引用時必須同一時候對其進行初始化。

引用是很忠心的,假設你定義了乙個變數的別名。那麼這個別名永遠屬於這個變數。它的位址始終和變數的位址同樣,當改變別名的值也會改變這個變數的值。

相同,對物件的引用也與對變數的引用相同。但須要注意的是不能對類引用,由於類是一種型別,沒有記憶體位址。

關於引用的介紹就到這裡。以下我們來學習一下引用的使用。

二、三種傳參方式的比較

函式的傳參方式有三種:按值傳遞、按位址傳遞及按別名傳遞(按別名傳遞也是按位址傳遞的一種。這裡我為了方便解說把它單列出來)。接下來我們用三個程式來對三種方式作下比較。程式的功能是交換兩個變數的值。

1.按值傳遞。

#include

using namespace std;

void swap(int i,int j)

int main()

程式的執行截圖例如以下:

從結果我們能夠看出,變數a和b的值分別傳給i和j,函式內的i和j的值是交換了的。而a和b的值並未交換。這是怎麼回事呢。

這是由於,當把a和b的值傳遞到函式中時,這種傳遞方式就是按值傳遞。編譯器會自己主動在棧中建立a和b的副本。然後再將a和b的副本傳遞給函式。這樣在函式中交換的是a和b的副本,而不是a和b本身。解決這種問題就要引入指標了。

2.按位址傳遞。

#include

using namespace std;

void swap(int *i,int *j)

int main()

程式的執行截圖例如以下:

能夠看到,這樣就能夠交換a和b的值了。由於程式傳遞的是a和b的位址,所以在函式中能夠通過位址直接訪問a和b,交換它們的值。

指標儘管能夠實現交換的功能,可是使用起來比較麻煩,又不易閱讀,使用引用看起來就會直觀得多。

3.按別名傳遞

#include

using namespace std;

void swap(int &i,int &j)

int main()

程式的執行截圖例如以下:

結果也是成功交換,程式看起來易懂,並且操作也方便不少。

三、傳遞物件

物件和變數一樣能夠作為引數傳遞。而不一樣的是。物件可能包括有大量的資料,那麼用上述的三種方式分別傳遞物件是什麼樣子呢。

1.按值傳遞物件

當按值傳遞的引數是乙個物件時,編譯器相同會建立乙個物件的副本,函式中返回物件時,相同會建立物件的副本,當該物件的資料非常多時。那對記憶體的消耗就非常大了,我們先來看按值傳遞的程式。

#include

using namespace std;

class a

;

a func(a a)

int main()

程式執行結果截圖例如以下:

由程式執行結果能夠看出。執行了一次建構函式,兩次複製建構函式,三次析構函式,接下來我們對比程式結果和**分析一下(此處知識對新手十分重要,大家務必牢記!

),main函式中建立了乙個物件a。所以呼叫了建構函式。再將a傳遞到func函式中,這時會自己主動呼叫複製建構函式來建立物件a的副本。也就是說傳進func函式的是a的副本而不是a本身。func函式的返回值是物件,返回的方式也是按值返回,此時又自己主動呼叫複製建構函式建立返回值的副本,所以我們看到呼叫一次建構函式和兩次複製建構函式,對應也會呼叫三次析構函式釋放記憶體。

2.按位址傳遞物件

從按值傳遞物件的程式結果能夠看出,這樣的方式的系統開銷是很大的,而按位址傳遞則攻克了這一問題。

#include

using namespace std;

class a

;

a func(a *a)

int main()

程式執行結果截圖例如以下:

能夠看出。上面的程式避免了兩次複製建構函式的呼叫,由於在將物件a傳遞給func函式時傳進的是位址,func函式返回的相同也是個位址。

3.按別名傳遞物件

#include

using namespace std;

class a

;

a &func(a &a)

int main()

程式執行結果截圖例如以下:

能夠看出,按別名傳遞物件與按指標傳遞有相同的效果。而實現起來又簡單的多,這裡給新手朋友們做出個小提示,就是func函式返回的型別是別名。假設想在main函式中接收這個別名,相同也要用引用型別的資料接收,比方a &aa=func(a),而不能用乙個a型別的物件接收。這點大家要注意。

四、究竟該用指標還是引用

既然引用能夠實現指標的功能。又比指標使用方便,那是不是僅僅用引用就能夠了呢。答案是否定的。由於指標的某些功能引用是無法實現的,先說一下引用和指標的差別。

1.指標能夠為空。而引用不能為空;

2.指標能夠被賦值,而引用不可改變;

3.在堆中建立一塊記憶體區域時,必須使用指標來指向這塊區域。否則是無法訪問的。而不能用引用來指向

五、使用引用需慎重

引用是不能為空的,否則是得不到正確的結果。我們通過以下的程式來感受一下。

#include

using namespace std;

class a

int get()

private:

int j;

};

a &func()

int main()

程式執行結果截圖例如以下:

從執行結果能夠看出。我們並沒有得到正確的j值(100),這是為什麼呢,原因是。func函式中的a是乙個區域性物件,在func函式執行後,a就沒有了,所以func函式返回的是乙個並不存在的物件的別名。因此無法正確得到j的值,解決問題非常easy,僅僅要將func函式的引用型別返回值改為a型別。就能夠的到正確的結果,由於這樣會建立乙個物件a的副本。

六、寄語

我剛開始學習c++時對引用就特別頭疼,但僅僅要清晰的了解了它的工作方式,學習起來還是比較簡單的,所以我以我的親身體驗寫出這篇博文。以供剛開始學習的人朋友參考。當然,引用的知識比較混亂並且極easy與指標混淆,須要在應用的過程中才幹逐漸掌握,所以建議朋友們還是去多讀多寫**。祝朋友們都能學到足夠的知識。在實踐中進步。成為合格的網際網路人才。

因為我也是剛入門不久,所以紕漏之處在所難免,請各位多包涵。假設對本文有不論什麼意見或建議,歡迎與我qq交流,謝謝!

帶你了解C 初階之引用

目錄 引用不是新定義乙個變數,而是給已存在變數取了乙個別名,語法理解上程式不會為引用變數開闢記憶體空間,它和它引用的變數共用同一塊記憶體空間 比如 李逵,在家稱為 鐵牛 江湖上人稱 黑旋風 型別 引用變數名 物件名 引用實體 int main 注意int main void testconstref...

C 中指標的引用 的具體使用

指標和引用形式上很好區別,但是他們似乎有相同的功能,都能夠直接引用物件,對其進行直接的操ydolap作。首先,引用不可以為空,但指標可以為空。前面也說過了引用是物件的別名,引用為空 物件都不存在,怎麼可能有別名!故定義乙個引用的時候,必須初始化。因此如果你有乙個變數是用於指向另乙個物件,但是它可能為...

c 的引用 常量引用

c 中的引用不用考慮太多解引用的東西 include using namespace std void func int ref intmain 在c 中,int ref a等價於int const ref a,也就是說ref直接存的是a的位址。但是實際上想要對ref的值進行修改的話,是不需要解引用...