詳談C++引用&和指針在作為形參時的區(qū)別
int n;
int &m = n;
在C++中,多了一個C語言沒有的引用聲明符&,如上,m就是n的引用,簡單的說m就是n的別名,兩者在內(nèi)存中占同樣的位置,不對m開辟新的內(nèi)存空間,對m的任何操作,對n來說是一樣的。
對于引用,有以下三條規(guī)則:
(1)引用被創(chuàng)建的同時必須被初始化(指針則可以在任何時候被初始化)。
(2)不能有NULL 引用,引用必須與合法的存儲單元關(guān)聯(lián)(指針則可以是NULL)。
(3)一旦引用被初始化,就不能改變引用的關(guān)系(指針則可以隨時改變所指的對象)。
假如在一個函數(shù)中動態(tài)申請內(nèi)存空間,用指針和用引用作形參會得到不同的結(jié)果,如下面的例子:
void fun(int* &b){ //用引用做形參
b = (int*)malloc(sizeof(int)*3);
for(int i=0; i<3; i++){
b[i] = i;
}
}
如果在main函數(shù)中定義了一個int型的空指針并分別作為實參傳入,如下:
int main(){
int *a = NULL;
fun(a);
for(int i=0; i<3; i++){
cout << a[i] << " ";
}
cout << "/n";
return 0;
}
結(jié)果用指針的函數(shù)會出現(xiàn)內(nèi)存訪問出錯,用引用的函數(shù)則運(yùn)行正常并正確輸出1 2 3.
這是因為:
1. 指針雖然是地址傳遞,但實際上也是在函數(shù)中又定義了一個新的指針讓其與傳入的指針指向同一地址。但兩個指針本身作為變量在內(nèi)存中的存放地址是不同的,就是說這是兩個不同的變量,只是內(nèi)容(即所指地址)相同。
2. 在函數(shù)中對新定義的指針動態(tài)申請內(nèi)存,但是當(dāng)函數(shù)結(jié)束后,申請的內(nèi)存的生命周期也就結(jié)束了,所以當(dāng)回到主函數(shù)時,作為實參的指針地址和內(nèi)容都沒有變化。仍然是個空指針,對其進(jìn)行訪問自然出現(xiàn)了內(nèi)存讀錯誤了。
假如在main函數(shù)中這樣寫:
int *a = (int*)malloc(sizeof(int)*3);
就不會出現(xiàn)內(nèi)存讀錯誤了,但是輸出結(jié)果還是錯誤的,道理也是一樣的。
3. 用引用作為實參傳入時,fun函數(shù)中的b其實就是主函數(shù)中a的別名(或者叫外號),反正就是操作完全相同,地址相同,內(nèi)容相同的一個變量,所以當(dāng)fun函數(shù)返回時,對b的操作在主函數(shù)中對a同樣有效。
再看一個例子:
int *a = NULL; char* b = (char*)a; int *a = NULL; char* &b = (char*)a;
這一次是在編譯階段的區(qū)別:
用指針可以通過編譯,而用引用則不可以,提示類型轉(zhuǎn)換出錯。
通過這兩個例子可以看出,指針比引用靈活,也更加危險。
摘自『高質(zhì)量c++編程』
條款一:指針與引用的區(qū)別
指針與引用看上去完全不同(指針用操作符'*'和'->',引用使用操作符'.'),但是它們似乎有相同的功能。指針與引用都是讓你間接引用其他對象。你如何決定在什么時候使用指針,在什么時候使用引用呢?
首先,要認(rèn)識到在任何情況下都不能用指向空值的引用。一個引用必須總是指向某些對象。因此如果你使用一個變量并讓它指向一個對象,但是該變量在某些時候也可能不指向任何對象,這時你應(yīng)該把變量聲明為指針,因為這樣你可以賦空值給該變量。相反,如果變量肯定指向一個對象,例如你的設(shè)計不允許變量為空,這時你就可以把變量聲明為引用。
PS:引用在定義時不可加const,否則編譯出錯,在形參前面則可以加const以確保在函數(shù)中該變量不會被修改。
以上這篇詳談C++引用&和指針在作為形參時的區(qū)別就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
c#基礎(chǔ)系列之System.String的深入理解
這篇文章主要給大家介紹了關(guān)于c#基礎(chǔ)系列之System.String的深入理解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09
C#十六進(jìn)制字符串轉(zhuǎn)十進(jìn)制int的方法
這篇文章主要介紹了C#十六進(jìn)制字符串轉(zhuǎn)十進(jìn)制int的方法,涉及C#操作數(shù)制轉(zhuǎn)換的技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-03-03
詳解C#用new和override來實現(xiàn)抽象類的重寫區(qū)別
本篇文章主要介紹了詳解C#用new和override來實現(xiàn)抽象類的重寫區(qū)別,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧。2017-02-02
C#探秘系列(一)——ToDictionary,ToLookup
這個系列我們看看C#中有哪些我們知道,但是又不知道怎么用,又或者懶得去了解的東西,比如這篇我們要介紹的toDictionary和ToLookup。2014-05-05

