C++中的引用和指針

參考自以下內(nèi)容输枯,侵刪:

原文1

原文2

不同之處

  • 不存在空引用铅鲤。引用必須連接到一塊合法的內(nèi)存。存在空指針NULL。
  • 一旦引用被初始化為一個(gè)對(duì)象谐宙,就不能被指向到另一個(gè)對(duì)象。指針可以在任何時(shí)候指向到另一個(gè)對(duì)象分衫。
  • 引用必須在創(chuàng)建時(shí)被初始化据德。指針可以在任何時(shí)間被初始化。

函數(shù)參數(shù)傳遞

  • 值傳遞傳遞的是變量的拷貝蔽豺。
  • 引用傳遞傳遞的是同一個(gè)變量区丑。
  • 指針傳遞傳遞的是變量的地址的拷貝(本質(zhì)上也是值傳遞)。

可以看到值傳遞和指針傳遞都會(huì)發(fā)生拷貝修陡,而引用傳遞避免了拷貝沧侥。

復(fù)雜一點(diǎn):

#include "stdio.h"

void f1( int*&p){  
  printf("\n---f1---\n");
  printf("指針p的地址:%p",&p);  
  printf("\n指針p的值%p",p);  
  printf("\n指針p指向的內(nèi)容:%x\n",*p);  
  *p=0xff;  
}  

void f2( int* p){  
  printf("\n---f2---\n");
  printf("指針p的地址:%p",&p);  
  printf("\n指針p的值%p",p);  
  printf("\n指針p指向的內(nèi)容:%x\n",*p);  
  *p=0xff;  
} 

int main()  
{  
  int a=0x10;  
  printf("a的地址:%p\n",&a);  
  printf("a的值:%x\n\n",a);  
  int *b=&a;  
  printf("指針b的地址:%p\n",&b);  
  printf("指針b的值:%p\n",b);  
  printf("指針b指向的內(nèi)容:%x\n",*b);  
  f1(b);  
  printf("\n試圖在函數(shù)f1中改變a的之后a的值:%x\n",a);  

  a = 0x10;
  f2(b);  
  printf("\n試圖在函數(shù)f2中改變a的之后a的值:%x\n",a); 
} 

執(zhí)行的結(jié)果是:

a的地址:0x7fff50d8bbac
a的值:10

指針b的地址:0x7fff50d8bba0
指針b的值:0x7fff50d8bbac
指針b指向的內(nèi)容:10

---f1---
指針p的地址:0x7fff50d8bba0
指針p的值0x7fff50d8bbac
指針p指向的內(nèi)容:10

試圖在函數(shù)f1中改變a的之后a的值:ff

---f2---
指針p的地址:0x7fff50d8bb68
指針p的值0x7fff50d8bbac
指針p指向的內(nèi)容:10

試圖在函數(shù)f2中改變a的之后a的值:ff

雖然f1和f2都可以改變a的值。但是魄鸦,函數(shù)f1由于傳入的是指針的引用宴杀,所以從b到p沒有發(fā)生指針的復(fù)制。而f2由于傳入的是指針本身号杏,所以還是會(huì)復(fù)制指針(b和p的地址不一樣)婴氮。

舉個(gè)栗子

#include "stdio.h"
class A{
public:
  A(int value):m_value(value)
  {}
  int m_value;
};

void f(A /*這里寫什么?*/_a) { //這里參數(shù)傳遞使用什么呢盾致?
  // 我們希望可以創(chuàng)建在main函數(shù)中聲明的實(shí)例 a
    _a = new A(5);
    printf("%d\n", _a->m_value);
}
int main() {
  A* a;
  f(a); //傳入指針
  printf("%d\n", a->m_value);
}
  • (A* _a)可否主经?答案是:不行!因?yàn)檫@時(shí)候指針_a是a的復(fù)制庭惜,兩個(gè)指針的地址是不同:
5
-125990072
  • (A*& _a)可否罩驻?答案是:可以!因?yàn)檫@時(shí)候傳入的是指針的引用护赊,即指針本身惠遏,所以沒有問題。
5
5

從上面的例子發(fā)現(xiàn)骏啰,可以在主函數(shù)中聲明一個(gè)實(shí)例的空指針节吮,然后通過其他函數(shù)來對(duì)它進(jìn)行創(chuàng)建和銷毀。(有什么用判耕?)

為什么使用指針/引用透绩?

參數(shù)傳遞中,如果參數(shù)是大型對(duì)象,引用和指針相比于直接傳值有效率優(yōu)勢(但引用和指針的優(yōu)劣我不太明白帚豪,個(gè)人感覺指針只是復(fù)制了一遍指針的大刑季埂(32位機(jī)子就是4個(gè)字節(jié)的空間),還可以接受吧……):

  • 引用不產(chǎn)生副本
  • 指針只復(fù)制指針本身狸臣,而不是整個(gè)對(duì)象

另外莹桅,因?yàn)楹瘮?shù)只能返回一個(gè)數(shù)值。如果使用引用或指針作為參數(shù)烛亦,則可以在函數(shù)中改變多個(gè)變量(可變參數(shù))诈泼。

函數(shù)參數(shù)傳遞用指針?還是引用此洲?

只能使用引用

有些函數(shù)只能傳遞引用厂汗,如重載運(yùn)算符。因?yàn)?strong>指針的運(yùn)算符是語言預(yù)定義好的呜师,無法重載娶桦。比如:

const maxCard=100; 
Class Set 
{
  int elems[maxCard]; // 集和中的元素,maxCard 表示集合中元素個(gè)數(shù)的最大值汁汗。 
  int card; // 集合中元素的個(gè)數(shù)衷畦。 
  public:
  Set () {card=0;} //構(gòu)造函數(shù)
  friend Set operator * (Set ,Set ) ; //重載運(yùn)算符號(hào)*,用于計(jì)算集合的交集 用對(duì)象作為傳值參數(shù)知牌,復(fù)制連個(gè)set祈争,效率低下
  // friend Set operator * (Set & ,Set & ) 重載運(yùn)算符號(hào)*,用于計(jì)算集合的交集 用對(duì)象的引用作為傳值參數(shù)角寸,不發(fā)生復(fù)制菩混,效率很高!
  ...
}
先考慮集合交集的實(shí)現(xiàn)
Set operator *( Set Set1,Set Set2)
{
  Set res;
  for(int i=0;i<Set1.card;++i)
  for(int j=0;j>Set2.card;++j)
  if(Set1.elems[i]==Set2.elems[j])
  {
    res.elems[res.card++]=Set1.elems[i];
    break;
  }
  return res;
}

其他情況下的一些準(zhǔn)則

來自這里:
相比起引用扁藕,指針有這些特點(diǎn):

  • 指針變量可以被重復(fù)賦值或更改(引用則不行沮峡,一經(jīng)賦值不能再改)
  • 指針變量可以為空(可以傳入一個(gè)空的指針)

里面還有于洋的神的回答,因?yàn)椴蛔屴D(zhuǎn)載亿柑,就不貼了邢疙,想看再點(diǎn)鏈接吧。大概就是想要改變變量的數(shù)值望薄,使用指針疟游;如果傳入不可變的變量,用const+引用痕支。

函數(shù)返回引用

通過使用引用來替代指針颁虐,會(huì)使Cpp程序更容易閱讀和維護(hù)。Cpp函數(shù)可以返回一個(gè)引用卧须,方式與返回一個(gè)指針類似另绩。

當(dāng)函數(shù)返回一個(gè)引用時(shí)瞬痘,則返回一個(gè)指向返回值的隱式指針。這樣板熊,函數(shù)就可以放在賦值語句的左邊

double &max(double &d1,double &d2)
{
  return d1>d2?d1:d2;
}

由于max()函數(shù)返回一個(gè)對(duì)雙精度數(shù)的引用察绷,那么我們就可以用max() 來對(duì)其中較大的雙精度數(shù)加1:
max(x,y)+=1.0;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末干签,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子拆撼,更是在濱河造成了極大的恐慌容劳,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件闸度,死亡現(xiàn)場離奇詭異竭贩,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)莺禁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門留量,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人哟冬,你說我怎么就攤上這事楼熄。” “怎么了浩峡?”我有些...
    開封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵可岂,是天一觀的道長。 經(jīng)常有香客問我翰灾,道長缕粹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任纸淮,我火速辦了婚禮平斩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘萎馅。我一直安慰自己双戳,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開白布糜芳。 她就那樣靜靜地躺著飒货,像睡著了一般。 火紅的嫁衣襯著肌膚如雪峭竣。 梳的紋絲不亂的頭發(fā)上塘辅,一...
    開封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音皆撩,去河邊找鬼扣墩。 笑死哲银,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的呻惕。 我是一名探鬼主播荆责,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼亚脆!你這毒婦竟也來了做院?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤濒持,失蹤者是張志新(化名)和其女友劉穎键耕,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體柑营,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡屈雄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了官套。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酒奶。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖奶赔,靈堂內(nèi)的尸體忽然破棺而出讥蟆,到底是詐尸還是另有隱情,我是刑警寧澤纺阔,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布瘸彤,位于F島的核電站,受9級(jí)特大地震影響笛钝,放射性物質(zhì)發(fā)生泄漏质况。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一玻靡、第九天 我趴在偏房一處隱蔽的房頂上張望结榄。 院中可真熱鬧,春花似錦囤捻、人聲如沸臼朗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽视哑。三九已至,卻和暖如春誊涯,著一層夾襖步出監(jiān)牢的瞬間挡毅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來泰國打工暴构, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留跪呈,地道東北人段磨。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像耗绿,于是被迫代替她去往敵國和親苹支。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • 指針和引用在C++中很常用误阻,但是對(duì)于它們之間的區(qū)別很多初學(xué)者都不是太熟悉沐序,下面來談?wù)勊麄?者之間的區(qū)別和用法。 1...
    起個(gè)名字真難啊2015閱讀 4,727評(píng)論 0 4
  • 今天在面試的時(shí)候被問到C++和C#中的引用堕绩,之前都在復(fù)習(xí)英語,突然被問起來這些東西邑时,感覺對(duì)這些基礎(chǔ)知識(shí)都有點(diǎn)模糊了...
    曉夢蟬君閱讀 573評(píng)論 0 1
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,511評(píng)論 1 51
  • 原文地址:C語言函數(shù)調(diào)用棧(一)C語言函數(shù)調(diào)用棧(二) 0 引言 程序的執(zhí)行過程可看作連續(xù)的函數(shù)調(diào)用奴紧。當(dāng)一個(gè)函數(shù)執(zhí)...
    小豬啊嗚閱讀 4,598評(píng)論 1 19
  • 12年,二月晶丘。我和朋友將我現(xiàn)在的妻子送到學(xué)校黍氮,她讀師范,彼時(shí)我在離她約兩個(gè)小時(shí)的車程的市里另一端念書浅浮。 送她來之...
    Bear有熊閱讀 242評(píng)論 0 0