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ù)制了一遍指針的大?。?2位機(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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容