C++參考運算子(reference operator)
指標和參考之所以難懂,其原因是&既能用於取址又能用於參考,容易造成初學者的混淆。
- 若&前面有資料型態 (eg: int &),則為參考
- 若&前面有等號或沒有資料型態時 (eg: int* p = &a),則為取址。
- 注意參考型態一定要初始化,否則編譯時會出現錯誤,因為參考初始化後就不能改變它所代表的物件,任何指定給參考的值,就相當於指定給原來的物件。
C++中才有reference。
指標與參考(pointer and reference)
- 指標: 其實也只是一個變數,只是這個變數之值為某個記憶體位址。
- 參考:為變數的別名,即兩個變數指向同一個位址。
int *p1 = &a;
int &p2 = b;
p1是一個指向a的指標。
- 其中的&a,稱為address of (取址)。即,p1 = address of a。
- int *p1應解讀為:p1 is a pointer points to an integer。
- 因此 int *p1 = &a; 可以看成p1 is a pointer points to integer variable a,即:p1是一個指標,指向整數變數a。
p2是b的參考。
- 參考可以想像成是一個變數或物件的別名 (alias)。
- 通常,當函式 (function) 的參數 (parameter) 在函式中會被修改,而且要把這個修改結果讓呼叫函式的部份繼續使用,我們會用參考來當參數傳入函式中。
void swap(int &a, int &b){
int tmp = a;
a = b;
b = tmp;
}
const與參考
- const與參考的解釋類似於指標。
- const int& ref = 10; : 指向常數的參考,但要注意的是指標在這種情形下是可以指向其它的元素,但是參考不行。
int tmp = 10, tmp2 = 20;
const int* ptr = &tmp;
ptr = &tmp2; //指標可指向其它元素
const int& ref = tmp;
// ref = 20; //編譯時會出現錯誤,因為ref指向常數
// 但是tmp可改值,此時ref也會跟著變
tmp = 30;
// int& const &ref = tmp; // c++不支援此宣告
指標型態的參考
- 語法 type *& ref_of_ptr = ptr;
- 事實上很少會直接如上的方式來使用參考,因為參考的目的是減少指標的使用;
- 常用於函式傳遞時一種「傳參考」(Pass by reference)方式,目的在於可於函式中直接操作目標變數或物件,或者是避免複製一個大型物件。
int var = 10;
int *ptr = &var;
int *&ref = ptr;
const int var = 10;
const int *ptr = &var;
const int *&ref = ptr;
// 用於修改傳入函式的陣列address,如realloc等
void foo(double *&bar);
使用參考傳遞陣列至函式
當使用pointer傳進function時,compiler只對array的型態做檢查,就算傳進function時指定了array size,compiler也會忽略,但若使用reference,compiler則會對array size做檢查。
傳入的參數 int (&arr)[10] 表示傳入一個reference,其reference到具有10個int元素的陣列。
- 若不加入括號的話: int &arr[10] 表示傳入一個長度為10的陣列,每一個元素型態皆為int &。
/* 只能傳長度為10,且type為dobule的陣到到函式
* &bar一定要括號,因為[]比&優先權高
*/
void foo(double (&bar)[10]) {...}
double arr[10];
foo(arr); //ok
// 若不指定長度時,可傳任意長度的陣列到函式
void foo2(double (&bar)[]){...}
void foo3(std::vector<double>& bar){...}