C++左值和右值學(xué)習(xí)筆記
來看一行簡(jiǎn)單的代碼
int a = 10;
這行代碼,"=" 左邊就是左值,"="右邊的則為右值,那他們到底有什么不同呢?
如果是Java、PHP等后端同學(xué),會(huì)稱以左邊的"a"為變量,右邊的"10"為字面量,而到了C++這里,我們就需要對(duì)他理解更多一點(diǎn)。
這行代碼運(yùn)行起來,是在系統(tǒng)內(nèi)存中申請(qǐng)了一塊空間,命名為"a",然后把"10"這個(gè)值裝入了這個(gè)單內(nèi)存空間中,內(nèi)存中的空間是有地址的,并且和"a"這個(gè)名字綁在一起,當(dāng)我們提到"a",就能知道他所代表的內(nèi)存地址,這也是所謂的"可尋址"。
在C++中,每個(gè)表達(dá)式都具有一個(gè)值和一個(gè)類型。左值和右值描述了表達(dá)式的可尋址性和持久性。
首先,讓我們來看一下左值的概念。左值是指可以被取地址的表達(dá)式,或者說具有標(biāo)識(shí)符的表達(dá)式。左值表示一個(gè)內(nèi)存位置,它具有持久性,可以在程序的不同部分訪問和修改。簡(jiǎn)而言之,左值可以出現(xiàn)在賦值運(yùn)算符的左邊。
左值的特點(diǎn)
int x = 10; // 'x' 是一個(gè)左值,可以被賦值 int* p = &x; // '&x' 是一個(gè)左值,可以取其地址 int arr[5]; // 'arr' 是一個(gè)左值,可以被訪問和修改
接下來,我們來看一下右值的概念。右值是指不可被取地址的表達(dá)式,或者說臨時(shí)生成的表達(dá)式。右值表示一個(gè)臨時(shí)的值,它通常只能用于賦值或傳遞給函數(shù),沒有持久性。簡(jiǎn)而言之,右值可以出現(xiàn)在賦值運(yùn)算符的右邊。
右值的特點(diǎn)
int a = 5; // '5' 是一個(gè)右值 int b = a + 3; // 'a + 3' 是一個(gè)右值 int* ptr = new int(10); // 'new int(10)' 返回一個(gè)右值
需要注意的是,C++11引入了右值引用的概念,即可以對(duì)右值進(jìn)行引用的類型。右值引用允許我們更有效地管理資源,如移動(dòng)語義和完美轉(zhuǎn)發(fā)。
綜上所述,左值表示持久的可尋址表達(dá)式,而右值表示臨時(shí)的不可尋址表達(dá)式。理解左值和右值的概念對(duì)于理解C++中的賦值、函數(shù)調(diào)用和參數(shù)傳遞等操作是非常重要的。
函數(shù)返回值
那么,一個(gè)函數(shù)返回值,應(yīng)該是左值還是右值?
當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),它會(huì)在棧上創(chuàng)建一個(gè)新的幀來存儲(chǔ)該函數(shù)的局部變量、參數(shù)以及其他信息。該幀在函數(shù)返回時(shí)銷毀。
因?yàn)楹瘮?shù)返回值通常是通過寄存器或者特殊寄存器(如eax)返回的,它們的地址在棧幀被銷毀后就不能再訪問了。所以不能直接對(duì)函數(shù)返回值取址。
但是,如果你需要返回一個(gè)指向已經(jīng)存在的內(nèi)存塊的指針,然后在函數(shù)外使用該指針訪問內(nèi)存塊,那么是可以的。例如:
int* foo() { int x = 10; return &x; } int main() { int* p = foo(); std::cout << *p; // undefined behavior return 0; }
上述代碼中的foo()函數(shù)返回了一個(gè)指向局部變量x的指針。
這會(huì)導(dǎo)致undefined behavior,因?yàn)閤在函數(shù)返回時(shí)就被銷毀了,所以p指向的內(nèi)存塊中可能包含任意的值。
所以,不能直接對(duì)函數(shù)返回值取址,函數(shù)返回值是一個(gè)右值。
但如何函數(shù)返回的是指向已經(jīng)存在的內(nèi)存塊的指針,即不是函數(shù)內(nèi)定義的東西,那么取址是沒有問題的。
以上就是C++左值和右值學(xué)習(xí)筆記的詳細(xì)內(nèi)容,更多關(guān)于C++左值 右值的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C語言實(shí)現(xiàn)將彩色bmp圖像轉(zhuǎn)化為灰圖、灰度圖像反色
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)將彩色bmp圖像轉(zhuǎn)化為灰圖、灰度圖像反色,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10C++算法之在無序數(shù)組中選擇第k小個(gè)數(shù)的實(shí)現(xiàn)方法
這篇文章主要介紹了C++算法之在無序數(shù)組中選擇第k小個(gè)數(shù)的實(shí)現(xiàn)方法,涉及C++數(shù)組的遍歷、判斷、運(yùn)算等相關(guān)操作技巧,需要的朋友可以參考下2017-03-03C語言實(shí)現(xiàn)選擇題標(biāo)準(zhǔn)化考試系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)選擇題標(biāo)準(zhǔn)化考試系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06C++ vector容器 find erase的使用操作:查找并刪除指定元素
這篇文章主要介紹了C++ vector容器 find erase的使用操作:查找并刪除指定元素,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-05-05在Visual Studio Code中使用CSSComb格式化CSS文件的教程
這篇文章主要介紹了在Visual Studio Code中使用CSSComb格式化CSS文件,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03C++命名空間?缺省參數(shù)?const總結(jié)?引用總結(jié)?內(nèi)聯(lián)函數(shù)?auto關(guān)鍵字詳解
這篇文章主要介紹了C++命名空間?缺省參數(shù)?const總結(jié)?引用總結(jié)?內(nèi)聯(lián)函數(shù)?auto關(guān)鍵字詳解的相關(guān)資料,需要的朋友可以參考下2023-01-01C++實(shí)現(xiàn)設(shè)計(jì)模式之裝飾者模式詳解
這篇文章主要介紹了C++設(shè)計(jì)模式之裝飾模式,裝飾模式能夠?qū)崿F(xiàn)動(dòng)態(tài)的為對(duì)象添加功能,是從一個(gè)對(duì)象外部來給對(duì)象添加功能,需要的朋友可以參考下2021-09-09