- 引用:引用(&)與類型結合在一起,相當于給變量起别名,(引用不參與類型)底層以指針的方式來支援使用,在引用使用的地方,系統自帶解引用的過程。
例:
int a=10;
int &b=a;//給變量a起别名叫b, 相當于int *b=&a;b也要開辟記憶體,因為底層實作時p是一個指針
b=20; //自帶解引用 相當于*b=20;
引用的注意事項:
一.引用一定要初始化
例 :int &a; 錯誤
二.引用所引用的變量一定要能取位址
例;
int a=10;
int &b=a; //正确
int &c=10;// 錯誤,因為底層用指針支援,相當于 int *c=&10 ,這是錯誤的
三.引用不可改變
例:
#include<iostream>
using namespace std;
int main()
{
int a=10;
int b=20;
int &c=a;
c=b;
c=100;
cout<<a<<endl;
cout<<b<<endl;
return 0;
}
結果:

可見當改變c的指向後指派,結果改變原指向的變量的資料
四.隻能通路引用變量所引用的記憶體塊的内容
因為所有用到引用的地方自帶解引用
不能傳回局部變量的位址或引用
例:
int &get()
{
int tmp=10;
return tmp;
}
int main()
{
int rt1=get();
cout<<rt1<<endl;
int &rt2=get();
cout<<rt2<<endl;
return 0;
}
結果:
發現結果符合我們的需求,如果在 int &rt2=get()函數後調用其他函數呢?
int &get()
{
int tmp=10;
return tmp;
}
void set()
{}
int main()
{
int rt1=get();
cout<<rt1<<endl;
int &rt2=get();
set();
cout<<rt2<<endl;
return 0;
}
我們隻在 int &rt2=get()函數後調用set()函數,rt2的數值就發生了改變,可見傳回局部變量的引用并不安全
因為函數傳回了局部變量的位址, int &rt2=get()是給局部變量tmp的位址起别名rt2,在get()函數清棧後,我們又調用了set()函數,set()函數開棧時會初始化記憶體,将tmp的位址的記憶體資料修改,導緻rt2通路資料時出錯。
- const 和引用結合
常引用引用的變量可以不能取位址
例: int &a=10; //錯誤,
const int &a=10;//正确
因為先将10存放到臨時量的記憶體中,常引用a引用臨時量的記憶體單元
内置類型生成的臨時量是常量(不能被修改)
例:
int a=10;
int *&p=&a; //錯誤,因為&a(a的位址)是常量
改為:int * const &p=&a;//正确
- const 和**(const 和指針結合主要防止間接通路修改常量記憶體塊的值)
例:
int a=10;
int *p=&a;
const int**q=&p;//錯誤
因為第四行const int **q=p;
const 修飾的變量是**q ,類型是int
相當于a是常量
直接通路 a
間接通路 *p, **q, *(*q)==*p
const 修飾**q 可以通過*p或 *(*q)修改a的值
用const修飾*p或*q即可避免錯誤
即
int a=10;
int *p=&a;
int const *const*q=&p;
避免通過**q或*(*q)來間接通路修改常量記憶體塊a的值,但可以通過p間接通路修改a的值(*p=20)
但const 定義在第三行,隻看第三行和其以下的代碼是否會修改常量記憶體塊的值,并不關心const定義上方的變量間接通路是否會修改常量記憶體塊的值。
或
int a=10;
const int *p=&a;
const int **q=&p;
避免通過*p,**q,*(*q)來間接通路修改常量記憶體塊a的值
- const和形參結合
一.防止實參被修改
例:
int add(int *a,int *b)
{
*a=20;
return *a+*b;
}
int main()
{
int a=10;
int b=20;
cout<<add(&a,&b)<<endl;
cout<<a<<endl;
cout<<b<<endl;
return 0;
}
add()函數隻是為了計算a+b的值,并不修改a和b的值,但函數中卻修改了a的值,為了避免函數修改實參,給形參加上const
即 int add(const int*a,const int *b)
二.接收臨時量
void swap(int &a,int &b)
{
int tmp=a;
a=b;
b=tmp;
}
int main()
{
int a=10;
int b=20;
swap(a,b);
cout<<a<<endl;
cout<<b<<endl;
return 0;
}
上面代碼中swap()函數實作了兩個數的交換功能,但如果直接調用swap(10,20)時,程式崩潰,
因為int &a=10,int &b=20,不符合引用的規則(引用引用的變量一定要能取位址)
為了解決這個問題改為常引用,即 void swap(const int &a,const int &b)
當直接調用swap(10,20)時,先将20存放到臨時量中,再将臨時量的位址賦給b,再将10存放到臨時量中,再将臨時量的位址賦給a