本文是筆者在C++學(xué)習(xí)過程中挫剑,對引用語法的總結(jié)記錄,如有不隊的地方柱衔,歡迎大家指正樊破!
一、 什么是引用
??引用(reference)唆铐,是C++對C語言的一項擴充哲戚,作用是給變量起別名,換句話說艾岂,就是將多個變量名指向同一個地址顺少,從而使對其中的任意一個變量名的操作,都是對同一地址的操作。而在這種情況下脆炎,被聲明為引用類型的變量名梅猿,就是實際變量名的一個別名。
二秒裕、引用的基本語法與注意事項
1袱蚓、 聲明語法
??引用的聲明語法:數(shù)據(jù)類型 &引用變量名 = 原變量名;
eg:
#include <iostream>
using namespace std;
int main() {
//語法:數(shù)據(jù)類型 &引用變量名 = 原變量名几蜻;
int a=10;
int &reference_a=a;
cout<<"a="<<a<<endl; //a=10
cout<<"reference_a="<<reference_a<<endl; //reference_a=10
a+=10;
cout<<"a="<<a<<endl; //a=20
cout<<"reference_a="<<reference_a<<endl; //reference_a=20
reference_a+=10;
cout<<"a="<<a<<endl; //a=30
cout<<"reference_a="<<reference_a<<endl; //reference_a=20
return 0;
}
2喇潘、 注意事項
對引用進行操作,實際上就是對被引用的變量進行操作梭稚。
聲明引用時颖低,必須對其進行初始化。
引用在初始化之后弧烤,不可以再進行修改忱屑。
-
引用變量在編譯器的底層實現(xiàn)是指針常量,即一個指針指向不可以發(fā)生更改的指針扼褪,所以引用占用內(nèi)存空間的大小想幻,和指針其實是一樣的。
但是话浇,和指針不同的是脏毯,引用實際上不能算是一個變量,所以對引用變量求地址幔崖,與對實際變量求地址食店,結(jié)果是相同的。
#include <iostream>
using namespace std;
int main() {
int a=10;
int &reference_a=a;
//對引用變量求地址,與對實際變量求地址赏寇,結(jié)果是相同的
cout<<"對引用變量求地址"<<endl;
cout<<"a的地址:"<<&a<<endl;
cout<<"reference_a的地址:"<<&reference_a<<endl;
return 0;
}
運行結(jié)果:
-
不能建立引用的數(shù)組吉嫩,即數(shù)組中的元素不能是引用。因為引用使勁上并不能算是一個變量嗅定,所以在聲明引用的數(shù)組時自娩,并不能分配內(nèi)存,也就無法聲明和定義引用數(shù)組渠退。
但是忙迁,可以建立數(shù)組的引用,這是沒有問題的碎乃。
#include <iostream>
using namespace std;
int main() {
//不能建立引用的數(shù)組姊扔,但是,可以建立數(shù)組的引用
int arr[]={0,1,2,3,4};
// int &re_arr=&arr;
// 編譯錯誤
// error: invalid conversion from ‘int (*)[5]’ to ‘int’
//數(shù)組的引用
int (&re_arr)[5]=arr;
return 0;
}
三梅誓、引用作為函數(shù)參數(shù)
??引用在C++中的一個重要作用恰梢,就是可以作為函數(shù)的參數(shù)使用佛南。
??在C語言之中,函數(shù)參數(shù)傳遞使用的方法是值傳遞嵌言,而在有大量數(shù)據(jù)作為參數(shù)傳遞時嗅回,往往采用的是地址傳遞,即使用指針呀页,來避免在函數(shù)調(diào)用時有大量數(shù)據(jù)壓入棧中÷璋瑁現(xiàn)在,C++中可以使用引用作為函數(shù)參數(shù)蓬蝶,以此來代替指針作為函數(shù)參數(shù)尘分,這種方法可以使代碼更易閱讀和維護。
eg:
#include <iostream>
using namespace std;
//引用作為函數(shù)參數(shù)
void fun1(int &a,int &b);
int main() {
int a=10;
int b=20;
cout<<"a="<<a<<",b="<<b<<endl;
fun1(a,b);
cout<<"a="<<a<<",b="<<b<<endl;
return 0;
}
//引用作為函數(shù)參數(shù)
void fun1(int &a,int &b){
int temp=a;
a=b;
b=temp;
}
運行結(jié)果:
??可以看出丸氛,在使用引用作為函數(shù)參數(shù)時培愁,與使用指針作為函數(shù)參數(shù)的效果一致,也就是在調(diào)用方法的時候缓窜,可以用形參修飾實參定续。
四、引用作為函數(shù)返回值
??C++支持將引用作為函數(shù)的返回值返回禾锤。
eg:
#include <iostream>
using namespace std;
//引用作為函數(shù)返回值
int& fun2(int &a);
int main() {
int b=10;
cout<<"fun2()前,b="<<b<<endl;
cout<<"fun2()后,b="<<fun2(b)<<endl;
return 0;
}
int& fun2(int &a){
a*=a;
return a;
}
運行結(jié)果:
注意事項
1. 不要返回局部變量的引用
??因為局部變量是存放在棧區(qū)的私股,在函數(shù)返回后,局部變量就會被銷毀恩掷,所以返回的引用就會像懸空指針一樣倡鲸,指向一個未知的空間。
eg:
#include <iostream>
using namespace std;
int& func2_local();
int main() {
int &ref_locol=func2_local();
// cout<<"ref_locol="<<ref_locol<<endl; //編譯錯誤
cout<<"ref_locol的地址為:"<<&ref_locol<<endl; //輸出地址為0
return 0;
}
// 不要返回局部變量的引用
int& func2_local(){
int a=10; //棧區(qū)黄娘,函數(shù)調(diào)用結(jié)束后釋放
return a; //Reference to stack memory associated
// with local variable 'a' returned
}
運行結(jié)果:
2. 函數(shù)調(diào)用可以作為左值
eg:
#include <iostream>
using namespace std;
int& func2_left();
int main() {
int left=func2_left();
cout<<"left="<<left<<endl;
cout<<"func2_left()作為左值峭状,修改為100"<<endl;
func2_left()=100;
cout<<"left="<<left<<endl;
return 0;
}
//函數(shù)調(diào)用可以作為左值
int& func2_left(){
static int a=10; //全局區(qū),程序結(jié)束后由系統(tǒng)釋放
return a;
}
運行結(jié)果:
3. 不要返回函數(shù)內(nèi)部使用 new 分配的內(nèi)存的引用
??這種編程習(xí)慣是非常不好的逼争,因為每個用 new 產(chǎn)生的指針都要調(diào)用 delete 釋放优床,否則就會造成內(nèi)存泄漏。而在被函數(shù)返回的引用作為一個臨時變量時誓焦,我們很容易未對其進行釋放胆敞,從而造成內(nèi)存泄漏。
eg:
#include <iostream>
#include <string>
using namespace std;
string& func2_new();
int main() {
string &str=func2_new(); //如果調(diào)用后沒有用 delete 釋放杂伟,就會造成內(nèi)存泄漏
cout<<"str="<<str<<endl;
delete &str; //釋放
return 0;
}
//不要返回函數(shù)內(nèi)部使用 new 分配的內(nèi)存的引用
string& func2_new(){
string* str=new string("hello world");
return *str;
}
??由代碼可以看出竿秆,返回函數(shù)內(nèi)部使用 new 分配的內(nèi)存的引用時,極易引起內(nèi)存泄漏稿壁,尤其是在形如以下代碼的情況下:
string str="hello world"+func2_new();
五、常量引用/常引用
??聲明方式:const 數(shù)據(jù)類型 &引用名 = 目標(biāo)變量名歉备;
eg:
#include <iostream>
using namespace std;
string& func3();
int main() {
func3(a);
return 0;
}
//常量引用/常引用
void func3(const int &a){
cout<<"a="<<a<<endl;
}
??常引用主要用于修飾形參傅是,防止函數(shù)中誤操作。另外,在引用作為函數(shù)參數(shù)時應(yīng)該盡量定義為 const 喧笔。