C 中的左值右值

2021-06-23 03:42:20 字數 2157 閱讀 2544

對於 c++ 中的左值和右值,我們通常的說法是:當乙個物件被用作右值的時候,用的是物件的值(內容);當物件被用作左值的時候,用的是物件的身份(在記憶體中的位置),這句話來自於 《c++ primer 第五版》 第 121 頁,那麼,對於這句話,該作何理解呢?下面我想來談談我的看法:

iso c++03規定表示式必須是左值或右值之一,而在iso c++11中,左值性被正式地擴充為更複雜的值類別,對於乙個變數來說,與它相關的有兩個部分:一是變數在記憶體中的位址,二是這個變數在記憶體中的位址中所儲存的資料。當我們使用變數在記憶體中的位址的時候,譬如給變數賦值,實際上使用的是變數的身份,而不是變數的值(內容),此時,變數是被用作左值的;當我們使用變數的值(內容)的時候,譬如把變數的值賦給另乙個物件的時候,變數是被用作右值的。由此可見,變數既可以被用作左值也可以被用作右值,那麼變數究竟是左值還是右值呢?《c++ primer 第五版》 第 121 頁中又寫到, 乙個重要的原則(有一種例外)是在需要右值的地方可以用左值代替,但是不能把右值當作左值 ,由此可見,乙個變數表示式是左值。

以上說了那麼多其實還沒有說到判斷乙個表示式究竟是左值還是右值的方法,那麼,該怎樣判斷乙個表示式是左值還是右值呢?對於「當物件被用作左值的時候,用的是物件的身份(在記憶體中的位置)」這句話,我們是不是可以這樣理解,當乙個表示式 在自身所在的表示式結束之後有持久的身份(在記憶體中的位置) 可以使用的時候,它就是乙個左值,即 可以對這個表示式執行結束之後取得持久的位址的時候,說明這個表示式是乙個左值,否則是乙個右值,為什麼我們要強調 在自身所在的表示式結束之後有持久的身份(在記憶體中的位置) 這句話呢?因為我們使用乙個表示式作為左值的時候早已經超出了這個表示式範圍本身來使用它,如果離開這個表示式自身的範圍就得不到這個表示式的位址的話,用表示式作為左值就沒有任何意義了,下面通過乙個例子來細細剖析這段內容:

對於前置遞增(遞減)運算子和後置遞增(遞減)運算子的表示式,究竟哪乙個是左值哪乙個是右值呢?針對前置遞增和後置遞增的情況,我們來分析一下,前置遞減和後置遞減可以同理分析:

++i這個前置遞增表示式,是把 i 的值加 1 然後返回 i 的值,這個表示式的返回值是 i,對 i 取位址可以得到持久的位址,因此,對於前置遞增表示式,它是乙個左值;

i++這個後置遞增表示式,是把 i 值的副本返回後再把 i 加 1,這個表示式返回的實際上是乙個 i 的副本(臨時量),而不是 i 本身(i 本身已加 1),所以,在這個表示式執行結束的時候,我們對這個表示式取位址,將得不到乙個持久的位址,因為這個臨時量隨著表示式的結束已經不復存在了,因此,對於後置遞增表示式,它是乙個右值;

對於前置遞增和後置遞增運算子,它們操作物件究竟是乙個左值還是右值呢?++i這個前置遞增表示式,最後返回的是 i 本身,它使用的是 i 的身份,因此此處的 i 是作為左值使用的,i++這個後置遞增表示式,最後返回的是 i 的副本,它使用的是 i 的內容,因此此處的 i 是作為右值使用的。

我們來看看對於表示式++i--加上括號,變成++(i--)之後,這個表示式是不是合法的呢?通過上面的分析我們知道,前置遞增(遞減)運算子的操作物件是乙個左值,後置遞增(遞減)運算子的操作物件是乙個右值,但是i--這個表示式是乙個右值,而前置遞增(遞減)運算子的操作物件是乙個左值,所以,++(i--)這個表示式是不合法的。

通過以上的分析我相信對於 c++ 中的左值和右值能有乙個深刻地理解了,其實說到底就一句話,這裡最後再強調一下: 可以對這個表示式執行結束之後取得持久的位址的時候,說明這個表示式是乙個左值,否則是乙個右值

++x 和 x++ 的區別的語義上的區別: 當寫 int i = 10 ; 時, i 是乙個 lvalue,它實際代表乙個記憶體裡的位址,是持久的。 表示式 ++x 也是乙個 lvalue,它修改了 x 的值,但還是代表原來那個持久物件。但是,表示式 i++ 卻是乙個 rvalue,它只是拷貝乙份i的初值,再修改i的值,最後返回那份臨時的拷貝,那份拷貝是臨時物件。 ++i 和 i++ 都遞增i,但 ++i 返回i本身,而 i++ 返回臨時拷貝。這就是為什麼 ++i 之所以是乙個 lvalue,而 i++ 是乙個 rvalue。

lvalue 與 rvalue 之分不在於表示式做了什麼,而在於表示式代表了什麼(持久物件或臨時產物)。 判斷乙個表示式是不是 lvalue 的直接方法就是「能不能對表示式取址?」,如果能夠,那就是乙個 lvalue;如果不能,那就是乙個 rvalue。

c 左值 右值 右值引用 左值引用

c 裡一切值必須屬於左值 右值兩者之一。左值 一切變數 包括用const修飾的變數 物件 包括引用都屬於左值 右值 一切字面值 可以是巨集 臨時無名物件 函式返回值 表示式 如a n 說明一下 函式返回值,返回的是某乙個型別的值,並不是返回變數。左值並不是說能放在 左邊的值就是左值 雖然用const...

c 左值 右值 左值引用 右值引用

在c語言中,左值認為是賦值語句的左側,右值認為是賦值語句的右側。在c 中,意義稍有不同。c 中,每乙個表示式會產生乙個左值或者右值,相應的,該表示式也就被稱作 左值表示式 右值表示式 乙個左值表示式的求值結果是乙個物件或者是乙個函式。左值可以當右值使用,而右值不能當左值使用。c prime 中這麼簡...

C 左值 右值 左值引用 右值引用

就變數而言,對於一些變數,我們只會讀取並使用它們的值,而不會改變他們的值 唯讀 對於其餘的變數,我們既會讀取它們的值,有的時候還會改變它們的值 讀寫 這是很常見的。在c 中,前一種變數稱為右值,後一種變數稱為左值,例如 int a 1 a是左值,1是右值稍稍不同的一點是,在c 中,乙個變數是左值還是...