【C++】C++中的引用與指針
想必大家對C++中的指針都有所了解,但是什麽是引用呢?C++11標準引入了“引用”的新功能。
引用
引用(reference):給對象起了另外一個名字,引用類型引用(refers to)另外一種類型,通過將聲明符寫成&d的形式來定義引用類型,其中d是聲明的變量名:
int val = 1024; int &d = val;
可以認為變量名就是一個可以操控內存的標簽,那麽引用就可以理解為另一個標簽。新定義的標簽和原來的標簽都可以訪問存放在內存中的數據。
例如:
#include <iostream> #include <cmath> usingnamespace std; //聲明 void add(int &a,int b); bool& isZero(float f); int main(){ double dval = 0.1; double &d = dval; d+=0.1; cout << "d is " << d << endl; //使用引用作為函數參數 int val = 20; add(val,5); cout << "val is " << val << endl;//使用引用作為函數返回值 bool &v = isZero(0.000000004); if(v) cout << "0.000000004 is zero" << endl; else cout << "0.000000004 is not zero" << endl; return 0; } //定義 void add(int &a,int b){ a+=b; } bool& isZero(float f){ bool b = false; if(abs(f) < 0.0000001) b = true; bool &rb = b; return rb; }
輸出結果為:
d is 0.2
val is 25
0.000000004 is zero
C++官方推薦使用引用以一種更安全的方式向函數傳遞數據和獲取返回值。
可以使用常量引用引用一個常量,
比如:
const int &i = 10;
指針
指針(pointer):是可以指向(point to)另外一種數據類型的數據類型,通過將聲明符寫成*d的形式定義指針,其中d是變量名。
取地址符(&):獲取對象的地址。
解引用符(*):獲取指向所指向的對象。
int v = 10; int *p = &v; int **m = &p;
p是一個int類型的指針,指向一個int類型,上面的例子中指向了變量v。
m是一個int*類型的指針,指向一個int*類型,上面的例子中指向了變量p。
這裏說指向某個對象就是指存放某個對象的地址。指針就是指地址,地址就是指針。指針變量就是存放內存單元編號的變量,或者說指針變量就是存放內存地址的變量。
這張圖片解釋了上面這段代碼的地址指向問題,變量p存放了變量v的內存地址,變量m存放了變量p的內存地址。
在判斷某個對象的類型的時候,應該從右向左閱讀(離變量名最近的符號對變量類型有最直接的影響),比如
int ****p; int ****&r = p;
上面的int ****p;離p最近的是第四個*,所以p是一個指針,剩余的部分確定該指針指向的類型,第四個*號左邊是int ***,所以指針p指向一個int ***類型。再看變量r,離r最近的是&,所以r是引用,剩余的部分確定該引用引用的類型,剩余的是int ****,所以r引用了一個int ****類型的變量。
空指針不指向任何對象,使用字面值NULL表示,c++11標準還提供了字面值nullptr也可以獲得空指針。
void*是一種特殊的指針類型,可用於存放任意對象的地址。一個void*指針存放著一個地址,這一點和其他指針類似。但是不能直接操作void *指針所指的對象,因為並不知道對象到底是什麽類型。如果要使用void *所指的對象,應該使用強制類型轉化。
引用與指針
引用和指針的比較:
1.引用不能引用NULL。
2.一旦引用被初始化引向某一個對象後,它就不能再引向另一個對象。指針可以多次改變指向的對象。
3.引用在創建的時候,必須初始化。指針可以在被創建時不被初始化,可以等需要的時才初始化。
4.引用不是對象,沒有實際的地址。指針是一個對象,有實際的地址。指針不能指向引用(因為引用不是對象)。
【C++】C++中的引用與指針