1:C++的引用,引用和指針的區別? 1:從彙編指令角度上看,引用和指針沒有區別,引用也是通過地址指針的方式訪問指向的記憶體 int &b=a ; 是需要將a的記憶體地址取出並存下來, b=20;(通過引用修改值時,也是先取出指向的地址,然後訪問該地址的值並修改它,和通過指針修改值一樣) 在定義引用的時 ...
1:C++的引用,引用和指針的區別?
1:從彙編指令角度上看,引用和指針沒有區別,引用也是通過地址指針的方式訪問指向的記憶體
int &b=a ; 是需要將a的記憶體地址取出並存下來, b=20;(通過引用修改值時,也是先取出指向的地址,然後訪問該地址的值並修改它,和通過指針修改值一樣)
在定義引用的時候,必須初始化,並能夠對a取地址。所以 int &c=20 編譯錯誤的,因為20取不了地址.
2:引用只有一級引用沒有多級引用,指針有一級指針和多級指針
3:定義一個引用變數和定義一個指針變數,其彙編指令是一樣的.通過引用變數修改所引用記憶體的值和通過指針修改所指向記憶體的值其底層指令也是一樣的.
4:
int array[5]={};
int *p=array;
cout<<sizeof(array)<<endl; //20
cout<<sizeof(p)<<endl; //4
2:怎麼定義一個引用變數
第1步:先對要引用的變數 取地址即&, &a ,然後定義一個指針來接, 所以就變成了 int *p=&a;
第2步: 用&符號取代 * ,所以變成了 int &p=a;
那麼又怎麼定義一個引用變數來引用一個數組呢?
第1步: 對數組名取地址 &array, 對數組取地址要怎麼接能? int (*p)[5]=&array;
第2步:用& 取代 *, 所以就變成了 int (&p)[5]=array;
如果列印 sizeof(p) ,值也是20,就是數組的大小.
3:引用有什麼好處?
void swap(int a, int b){
int c=a;
a=b;
b=c;
}
上面的代碼是實現不了值交換的,需改為如下方式
void swap(int *a ,int b){
int c =a;
a =b;
*b=c;
}
另外一種方式,通過引用
void swap(int &a,int &b){
int c=a;
a=b;
b=c;
}
上面通過引用的方式整體在使用上更簡潔更自然.其實引用的方式在底層指令實現上,仍然是通過傳遞地址,
只是編譯器幫我們在後臺做了很多轉換的工作.
4:關於左值引用和右值引用
左值: 它有記憶體,有名字,值可以修改
例如 int a=10;
就可以定義引用 int &b=a;
但是 int &c=20;//不可以 20內有記憶體,無法取值,20 是右值
右值:沒有記憶體,沒名字
C++11 以後,提供了右值引用 如下
int &&m=20;
也還可以 m =30;
上面代碼底層彙編的實現方式,其實是將20存儲在棧記憶體中的一個臨時量上,然後把臨時量的記憶體地址給 m
int &&m=20;//通過右值引用來引用右值
那麼
int a=10;
int &b =a;
和
int &&c=20
左值引用和右值引用在彙編指令上的實現是怎麼樣的?
一個右值引用變數本事是一個左值,這個右值引用本身也是有名字,也占存儲空間,也是可以取地址的,而且只能用左值引用變數來引用它,如下,
int &&m=20;
int &n=m;
不能用一個右值引用變數來引用一個左值,如下
int c=100;
int &&m=c;
上面編譯報錯,右值引用,編譯器是要為右邊的值生產臨時量的, c已經有記憶體空間了,還需要為他生成臨時量做啥呢?所以右值引用只能專門用來引用右值的,
指令上是通過產生臨時量的方式實現的.
5:為什麼 const int &m =20 可以通過編譯?
實現方式是
int temp=20;
int &m =temp;
編譯器定義了一個臨時量,只是不可以 m=100; 因為 m 是const