C 左值和右值概念

2021-05-24 15:49:12 字數 2037 閱讀 5514

本文主要就c++中左值和右值的一些概念進行討論。如果文中有錯誤或遺漏之處,敬請指出,謝謝!

讓我們先看看一些常見的左值和右值舉例:

int var = 6;          // var is a lvalue

const int var = 6;    // var is a (nonmodifiable) lvalue

"hello, world";       // the expression is string literal,

it's a rvalue

char str = "hello, world"; // str is a rvalue

string("hello, world");  // the expresion is a (modifiable) rvalue

對於每乙個表示式,其要麼是乙個左值(lvalues),要麼是乙個右值(rvalue)。

左值這個概念最初**於賦值語句:e1 = e2;,這裡要求左運算元e1是乙個(可修改的)左值。現在,左值這個概念的含義已不侷限於此。而右值是相對於左值出現的,非左即右。

雖然左值和右值的內涵和外延有了很大變化,但仍滿足這條規則:右值只能出現在賦值運算子的右邊,不能出現在它的左邊。

乙個左值對應於(refer to)乙個物件或者函式(注:函式不是物件)[注1]。

注1:物件型別為非函式、非引用、非void的型別;左值所對應的物件不一定實際存在。例如:char* p; *p這個左值所對應的物件目前是不存在的。

部分右值表示式也可以對應物件。例如,那些呼叫建構函式和呼叫那些返回類物件的函式的表示式,這些表示式可以呼叫相應物件的成員函式,但這些表示式是右值(此時,該右值可能是可修改的右值)。

右值的型別總是完整型別或者void型別。注意兩點:(1)void型別(非完整型別)是右值;(2)當右值的型別不是void型別時,其必須是完整型別,因為需要計算它的值。由此可知,非void的非完整型別是左值。

如果在左值被計算時還沒有指定乙個物件,那麼該計算行為是未定義的。例如:char* p;此時計算*p的結果是未知的。

函式呼叫是左值,當且僅當返回型別是引用。[注2]

注2:自定義運算子是函式,這類運算子是否需要或者產生左值取決於它們的引數和返回值型別。

在任何時候,當乙個左值出現在需要右值的地方,左值會被轉換成右值。[注3]       

注3:當左值型別t為非函式、非陣列型別時,左值可以被轉換為右值。如果t是非void的非完整型別,那麼此時左值不應該被轉化為右值來使用;如果該左值所對應的物件不是型別t的物件,也不是由t派生的型別的物件,或者該物件沒有被初始化,那麼發生這種轉換的程式將產生未定義行為。

如果t是非類型別,那麼轉換得到的右值的型別是t的cv-qualified版本;否則,右值型別是t。

左值所對應的物件所包含的值就是右值的結果。 在發生這種轉換時,左值的值並不是一定被計算。例如:當運算子sizeof的運算元發生這種轉換時,並不需要訪問左值的值,因為該運算子不需要計算它的運算元。

左值分為可修改的左值(modifiable)和不可修改的左值(nonmodifiable)。

如果要修改乙個物件,該物件必須是左值;例外情況是,類型別的右值也可以在某些情形下修改它所對應的物件。例如,函式呼叫返回的類是右值,但可以呼叫其成員函式修改該物件。

由const限定的表示式不可以被修改;除非這是乙個類型別,並且擁有mutable成員,那麼該mutable成員可以被修改。

非類型別的右值總是由cv-qualifiers限定,類型別的右值可以沒有cv-qualifiers。

部分內建運算子需要左值運算元。例如,所有內建賦值運算子要求它們的左運算元是乙個左值(此時還是乙個可修改的左值)。

部分內建運算子需要右值運算元,並且產生右值。例如,一元運算子和二元運算子「+」要求運算元為右值,並且它們產生的結果也為右值。

部分內建運算子和函式呼叫產生左值。例如,如果e是乙個指標型別的表示式,那麼*e是乙個左值表示式(注:*運算子的運算元是左值,產生乙個左值)。又如,函式 int& f();產生乙個左值,因此f()的呼叫是乙個左值表示式。

如果乙個程式試圖通過乙個左值的非下列型別去訪問儲存在物件中的值,那麼該行為是未定義的。

C 左值和右值,左值引用和右值引用

c 對於左值和右值沒有標準定義,但是有乙個被廣泛認同的說法 可見立即數,函式返回的值等都是右值 而非匿名物件 包括變數 函式返回的引用,const物件等都是左值。從本質上理解,建立和銷毀由編譯器幕後控制,程式設計師只能確保在本行 有效的,就是右值 包括立即數 而使用者建立的,通過作用域規則可知其生存...

C 左值和右值

c 左值與右值概念 變數和文字常量都有儲存區,並且有相關的型別,區別在於變數是可定址的 1 資料值,儲存在某個記憶體位址中,也稱右值 rvalue 右值是被讀取的值 read value 文字常量和變數都可被用於右值。2 位址值,即儲存資料值的那塊記憶體位址,也稱左值 lvalue 文字常量不能被用...

C 左值和右值

左值 lvalue 和右值 rvalue 是 c c 中乙個比較晦澀基礎的概念,有的人可能甚至沒有聽過,但這個概念到了 c 11 後卻變得十分重要,它們是理解 move,forward 等新語義的基礎。左值與右值這兩概念是從 c 中傳承而來的,在 c 中,左值指的是既能夠出現在等號左邊也能出現在等號...