鑑於本人學完就忘的特殊體質,決定把一些有意義的知識進行簡單的記錄。
在本篇中,重點介紹c++關於引用的相關知識。
這裡我們綜合對比三種函式引數設定方式,分別為:
所用**如下:
// arrayone.cpp -- small arrays of integers
#include
using
namespace std;
//值傳遞
void
swap01
(int a,
int b)
//位址傳遞
void
swap02
(int
*a,int
*b)//引用傳遞
void
swap03
(int
&a,int
&b)int
main()
引用可以理解為,為變數起乙個別名,別名和原名指向同乙個記憶體空間,從而對二者的操作完全等價。
典型的引用初始化如下:
int a =10;
int&b = a;
這樣,a與b完全等價。
在**中,我們使用了交換兩個變數的值來觀察函式呼叫效果。
其中,值傳遞只改變了形參,位址和引用傳遞均改變了實參,所以在主函式中列印a和b的值,就會出現交換的效果。
對比位址傳遞和引用傳遞,引用傳遞只需要在函式定義時採用對變數加乙個&符號構成引用傳遞,就可以實現和位址傳遞相同的功能,相比位址傳遞反覆的解引用和複雜的定義,要簡便很多。
函式執行效果如下:
這裡主要有兩個主要的關注點:
不要返回區域性變數的引用
函式的呼叫可以作為左值
廢話不多說,直接上**!
// arrayone.cpp -- small arrays of integers
#include
using
namespace std;
//引用做函式的返回值
//1.不要返回區域性變數的引用
int&
test01()
//這裡是用引用的方式做返回值定義函式
//2.函式的呼叫可以作為左值
int&
test02()
//這裡是用引用的方式做返回值定義函式
intmain()
對於第一點,不要返回區域性變數做引用值,可以參考子函式test01(),這裡的函式定義方式是把引用作為函式返回值,即可用於乙個引用(別名)賦給這個返回的變數。
由於這個操作是把乙個變數起乙個別名,所以原名不能是區域性變數,因為它存在於棧區,函式呼叫結束就被釋放掉了,所以test01()中的返回是非法操作。
對於第二點,對於返回引用的函式,函式的呼叫可以作為左值,觀察子函式test02(),其變化之處在於定義的變數是乙個靜態變數,靜態變數存在於程式的全域性區,是在程式結束時釋放,所以在程式生命週期中一直存在,可以作為函式返回值。
這裡我們用乙個引用ref作為a的別名。
所謂函式呼叫可以作為左值,可以這樣理解,這裡就是靜態變數a賦值為1000,證明方式為輸出ref(a的別名),可以看出,ref已經變成了1000。
函式執行結果如下:
另外,a實際上不能拿到子函式之外,例如這樣就會報錯:
test02()
=1000
;//這裡返回了a的引用,相當於就是a,ref是a的別名
cout <<
"a = "
<< a << endl;
//不能這麼使用
// arrayone.cpp -- small arrays of integers
#include
using
namespace std;
//引用的本質
int ref =0;
//自己沒事找事看看會出現什麼現象
//發現是引用,轉換為 int* const ref = &a;
void
func
(int
&ref)
intmain()
簡單介紹一下**:
從主函式定義a開始(先忽略其他的顯示),當我們建立ref引用時,編譯器將該**:
int
&ref = a;
識別為指標常量的初始化**:
int
*const ref =
&a;
所謂指標常量,就是定義了乙個指向位址固定,指向位址所在記憶體的值可以變化的指標,但是由於c++自動識別了引用,所以能夠在一定程度上降低**的輸入複雜度(肯定還有別的作用)。
之後凡是用到引用ref時,系統均自動識別為:
ref =10;
//引用的用法
*ref =10;
//編譯器識別到的
這樣我們就對引用有了更加深入的理解。
對於建立的子函式,本身沒有引起我的太大興趣,僅僅是引用作為函式引數進行傳遞,但對於程式執行產什麼了一些疑問:
如果有乙個同名的全域性變數,反覆定義和使用引用,會有什麼效果?
於是筆者建立了乙個名為ref的全域性變數,具體程式執行結果如下:
由此可見,在定義ref引用前,程式輸出全域性變數定義的資料。
在定義ref引用後,似乎覆蓋了ref這個全域性變數,之後的操作一直是作為引用了。
具體是什麼原因有待**???
引用作為一種「起別名」的方式,如果我們不希望這個別名不能改變原名的數值,應當怎麼做呢?
這裡就要用到常量引用了。
先說一下定義常量引用的方法,**如下:
//int &ref = 10;//非法引用,引用要引向合法的記憶體空間
//該行程式相當於:int temp = 10; const int &ref = temp;
intconst
&ref =10;
//沒有原名(一般不這麼用)
第一行展示了錯誤的定義方式,因為沒有給引用合法的記憶體空間(找不到記憶體)。
第三行展示了正確的定義方式,可以看到,它相當於:
int temp =10;
const
int&ref = temp;
不過這個temp並不顯示在程式中(不存在),是編譯器內部完成的等效動作。
至於常量引用,實際上一般用於函式呼叫,從而防止子函式修改實參,錯誤**如下:
void
showvalue
(const
int&temp)
這裡,形參設定為了常量引用,所以在子函式中不可以修改其數值,否則會報錯。
以上就是關於引用的簡單總結,後續會繼續補充der!
有關物件引用的淺學習
就不講什麼堆啊棧啊什麼的了,首先把基本資料型別和非基本資料型別區分開,這裡叫引用物件把。test public void test03 public people update object b,people p 輸出結果 1.update before p1people 2.update in p...
Python有關模組學習記錄
首先安裝搭建好jupyter notebook,執行成功後的截圖如下 安裝使用步驟 ps 確定python安裝路徑和安裝路徑裡面scripts資料夾路徑已經配置到環境變數中去,即pip所在路徑已經配置到環境變數中去 以下說明是在windows環境下 安裝 pip install jupyter no...
有關軟引用,弱引用,虛引用的問題
public class bitmapcache private bitmapcache 取得快取器例項 public static bitmapcache getinstance return cache 以軟引用的方式對乙個bitmap物件的例項進行引用並儲存該引用 private void a...