詳解C++中指針和引用的區(qū)別
1、指針和引用的本質(zhì)(是什么)
(1)指針是存放內(nèi)存地址的一種變量,特殊的地方就在它存放的是內(nèi)存地址。因此,指針的大小不會(huì)像其他變量一樣變化,只跟當(dāng)前平臺(tái)相關(guān)——不同平臺(tái)內(nèi)存地址的范圍是不一樣的,32位平臺(tái)下,內(nèi)存最大為4GB,因此只需要32bit就可以存下,所以sizeof(pointer)的大小是4字節(jié)。64位平臺(tái)下,32位就不夠用了,要想內(nèi)存地址能夠都一一表示,就需要64bit(但是目前應(yīng)該沒(méi)有這么大的內(nèi)存吧?),因此sizeof(pointer)是8。
(2)引用的本質(zhì)是“變量的別名”,就是給變量又重新起了一個(gè)名字,既然是“別名”,那么就一定要有本體。
2、聲明和初始化時(shí)的區(qū)別
指針指向的是一個(gè)內(nèi)存地址, 因此可以指向一塊為0x00000000的地址,聲明時(shí)可以暫時(shí)不初始化(不推薦),即pointer = NULL;
引用是變量的別名,別名就一定對(duì)應(yīng)著一個(gè)“本名”,因此必須在聲明時(shí)就初始化,且不能初始化為空。
3、使用時(shí)區(qū)別
(1)根據(jù)聲明和初始化時(shí)二者的區(qū)別,指針在聲明周期內(nèi)隨時(shí)可能會(huì)為Null,所以使用時(shí)一定要做檢查,防止出現(xiàn)空指針、野指針的情況;而引用則不用再操這個(gè)心,只要初始化了,在哪里都可以直接使用,再也不用擔(dān)心它會(huì)不會(huì)為空什么的了。
(2)指針因?yàn)樽约捍娴氖且粋€(gè)內(nèi)存地址,既然可以存初始化(或者賦值)的地址,那么在指針生命周期內(nèi)就可以存其他的地址,只要你是同一類型(不同類型這個(gè)對(duì)應(yīng)的類型偏移不一樣)的變量,對(duì)于指針都OK。
引用作為一個(gè)變量AA的別名,在它的整個(gè)生命周期內(nèi),它只能“從一而終”,始終是第一次初始化它的那個(gè)變量的別名,在這期間任何對(duì)它的操作,都等同于對(duì)變量AA的操作。
Talk is cheap,show you my code.
/** 指針和引用的例子 **/ std::string s1 = "蘿卜"; std::string s2 = "青菜"; std::string s3 = "雞蛋"; std::string s4 = "西紅柿"; /** 指針可以初始化為空 **/ std::string *p_Str = NULL; /** 引用一開(kāi)始必須初始化 **/ std::string& r_Str = s1; p_Str = &s2; std::cout<<"我是指針"<<*p_Str<<std::endl; /** 青菜 **/ std::cout<<"我是引用"<<r_Str<<std::endl; /** 蘿卜 **/ std::cout<<std::endl; std::cout<<"*********分別修改指針和引用***********"<<std::endl; /** 分別修改指針和引用 **/ r_Str = s3; /** 試圖讓r_Str為s3的別名 **/ p_Str = &s4; /** p_Str重新指向了s4 **/ std::cout<<"我是指針"<<*p_Str<<std::endl; /** 西紅柿 **/ std::cout<<"我是引用"<<r_Str<<std::endl; /** 雞蛋 **/ std::cout<<std::endl; std::cout<<"*********查看剛剛的修改對(duì)最初初始化的影響***********"<<std::endl; /** 貌似成功了,都按照意圖修改了,但是,稍等 **/ std::cout<<"我是s1"<<s1<<std::endl; /** 雞蛋 ?。。∽⒁??。?! **/ std::cout<<"我是s2"<<s2<<std::endl; /** 青菜 **/ std::cout<<"我是s3"<<s3<<std::endl; /** 雞蛋 **/ std::cout<<"我是s4"<<s4<<std::endl; /** 西紅柿 **/ /** 發(fā)現(xiàn)s1 "蘿卜" 被變成了和s3一樣的"青菜",這也說(shuō)明了任何對(duì)引用的操作都等同于操作原先的變量本身 相比較之下,指針就自由度很高了,想指向誰(shuí)就指向誰(shuí),并不會(huì)影響任何之前指向過(guò)的變量 驚不驚喜,意不意外 :) **/
4、總結(jié)
一個(gè)不大恰當(dāng)?shù)谋扔魇?,指針就像是一個(gè)可以(注意是可以,但未必一定)到處沾花惹草(可以隨時(shí)指向任意地址)的“渣男”;而引用則像是一個(gè)只能“從一(誰(shuí)初始化就跟誰(shuí))而終”的“老實(shí)人”。
另外,根據(jù)Scott Meyers在《More Effective C++》上所講,只有當(dāng)你確定需要一開(kāi)始就初始化,并且不需要再指向其他類型時(shí) 使用引用,否則你都應(yīng)該使用指針。
小弟認(rèn)識(shí)粗鄙淺薄,有不當(dāng)之處,請(qǐng)大佬輕拍。
以上所述是小編給大家介紹的C++中指針和引用的區(qū)別詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
C++開(kāi)發(fā)之CRC校驗(yàn)實(shí)例詳解
這篇文章主要介紹了C++開(kāi)發(fā)之CRC校驗(yàn)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-07-07C++使用cuBLAS加速矩陣乘法運(yùn)算的實(shí)現(xiàn)代碼
這篇文章主要介紹了C++使用cuBLAS加速矩陣乘法運(yùn)算,將cuBLAS庫(kù)的乘法運(yùn)算進(jìn)行了封裝,方便了算法調(diào)用,具體實(shí)現(xiàn)代碼跟隨小編一起看看吧2021-09-09詳解C++編程中的主表達(dá)式與后綴表達(dá)式編寫基礎(chǔ)
這篇文章主要介紹了C++編程中的主表達(dá)式與后綴表達(dá)式編寫基礎(chǔ),是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-01-01C語(yǔ)言不定長(zhǎng)數(shù)組及初始化方法
今天小編就為大家分享一篇C語(yǔ)言不定長(zhǎng)數(shù)組及初始化方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07ubuntu20.04中vscode使用ROS的詳細(xì)方法
這篇文章主要介紹了ubuntu20.04?vscode使用ROS的詳細(xì)方法,主要包括在vscode安裝擴(kuò)展創(chuàng)建工作文件夾的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10C++數(shù)據(jù)結(jié)構(gòu)之實(shí)現(xiàn)鄰接表
這篇文章主要為大家詳細(xì)介紹了C++數(shù)據(jù)結(jié)構(gòu)之實(shí)現(xiàn)鄰接表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04C++使用map實(shí)現(xiàn)多進(jìn)程拷貝文件的程序思路
這篇文章主要介紹了C++使用mmap實(shí)現(xiàn)多進(jìn)程拷貝文件,通過(guò)本文給大家分享程序思路及完整代碼,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-12-12結(jié)合C++11的新特性來(lái)解析C++中的枚舉與聯(lián)合
這篇文章主要介紹了C++編程中的枚舉與聯(lián)合,結(jié)合了范圍(或強(qiáng)類型)enum class類型等C++11的新特性來(lái)講解,需要的朋友可以參考下2016-01-01Visual Studio 2019安裝使用C語(yǔ)言程序(VS2019 C語(yǔ)言)
這篇文章主要介紹了Visual Studio 2019安裝使用C語(yǔ)言程序,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03