C++中的引用和指針
★ 相同點: 1. 都是地址的概念;
指針指向一塊內存,它的內容是所指內存的地址;引用是某塊內存的別名(java中的引用其實也是別名的意思)。
★ 區別: 1. 指針是一個實體,而引用僅是個別名;
2. 引用使用時無需解引用(*),指針需要解引用;
3. 引用只能在定義時被初始化一次,之后不可變;指針可變; 引用“從一而終”
4. 引用沒有 const,指針有 const,const 的指針不可變;
5. 引用不能為空,指針可以為空;
6. “sizeof 引用”得到的是所指向的變量(對象)的大小,而“sizeof 指針”得到的是指針本身(所指向的變量或對象的地址)的大小;typeid(T) == typeid(T&) 恒為真,sizeof(T) == sizeof(T&) 恒為真,但是當引用作為成員時,其占用空間與指針相同(沒找到標準的規定)。
7. 指針和引用的自增(++)運算意義不一樣;
★ 聯系
1. 引用在語言內部用指針實現(如何實現?)。
2. 對一般應用而言,把引用理解為指針,不會犯嚴重語義錯誤。引用是操作受限了的指針(僅容許取內容操作)。
引用是C++中的概念,初學者容易把引用和指針混淆一起。一下程序中,n 是m 的一個引用(reference),m 是被引用物(referent)。
n 相當于m 的別名(綽號),對n 的任何操作就是對m 的操作。例如有人名叫王小毛,他的綽號是“三毛”。說“三毛”怎么怎么的,其實就是對王小毛說三道四。所以n 既不 是m 的拷貝,也不是指向m 的指針,其實n 就是m 它自己。
引用的一些規則如下:
(1)引用被創建的同時必須被初始化(指針則可以在任何時候被初始化)。
(2)不能有NULL 引用,引用必須與合法的存儲單元關聯(指針則可以是NULL)。
(3)一旦引用被初始化,就不能改變引用的關系(指針則可以隨時改變所指的對象)。
以下示例程序中,k 被初始化為i 的引用。語句k = j 并不能將k 修改成為j 的引用,只是把k 的值改變成為6。由于k 是i 的引用,所以i 的值也變成了6。
上面的程序看起來象在玩文字游戲,沒有體現出引用的價值。引用的主要功能是傳遞函數的參數和返回值。C++語言中,函數的參數和返回值的傳遞方式有三種:值傳遞、 指針傳遞和引用傳遞。
以下是“值傳遞”的示例程序。由于Func1 函數體內的x 是外部變量n 的一份拷貝,改變x 的值不會影響n, 所以n 的值仍然是0。
以下是“指針傳遞”的示例程序。由于Func2 函數體內的x 是指向外部變量n 的指 針,改變該指針的內容將導致n 的值改變,所以n 的值成為10。
以下是“引用傳遞”的示例程序。由于Func3 函數體內的x 是外部變量n 的引用,x 和n 是同一個東西,改變x 等于改變n,所以n 的值成為10。
對比上述三個示例程序,會發現“引用傳遞”的性質象“指針傳遞”,而書寫方式象 “值傳遞”。實際上“引用”可以做的任何事情“指針”也都能夠做,為什么還要“引用” 這東西? 答案是“用適當的工具做恰如其分的工作”。 指針能夠毫無約束地操作內存中的如何東西,盡管指針功能強大,但是非常危險。 就象一把刀,它可以用來砍樹、裁紙、修指甲、理發等等,誰敢這樣用? 如果的確只需要借用一下某個對象的“別名”,那么就用“引用”,而不要用“指針”, 以免發生意外。比如說,某人需要一份證明,本來在文件上蓋上公章的印子就行了,如 果把取公章的鑰匙交給他,那么他就獲得了不該有的權利。
注意:若定義string s1(“abc”);string * p=&s1;那么p值為s1的地址(即指針p內的內容),所以cout<<p1輸出值等于cout<<&s1,;p值為指針p所指地址內存放的內容,所以cout<<p等于abc;&p為指針p自己本身所在的地址,該地址內存放的值為所指內容的地址,cout<<&p等于指針p自身所在內存的地址
可敲入如下代碼驗證:(并可驗證“引用不可變,指針可變”)
#include<iostream>
#include<conio.h>
using namespace std;
void main()
{
string s1("Nancy");
string s2("Clancy");
string &rs=s1;
string *ps=&s1;
cout<<&rs<<" "<<ps<<"/n";
rs=s2;
ps=&s2;
cout<<rs<<" "<<*ps<<"/n";
cout<<&rs<<" "<<&s2<<" "<<ps<<" "<<&ps;
//引用rs的地址同之前相同,還是等于s1的地址,未發生改變,
//而指針ps的地址發生了改變,且指向了s2,引用rs內的值和
//指針ps所指地址內存放的值都變為了s2
_getch();
}
新聞熱點
疑難解答
圖片精選