關於C 左值和右值區別有沒有什麼簡單明瞭的規則可以一眼辨別?

時間 2021-05-31 11:34:41

1樓:caelum

其實吧,變數都是位址。

變數裡面的資料還是存放在其它空間。

如果儲存空間中的值有指標(變數)指向它,那麼這個變數就是乙個左值。

如果這個空間的資料沒有變數指向它,那麼它就是乙個右值。

大概是這樣吧。。。。。。有沒特例我也不清楚。。。。。

不過說實話,我也有點懵。

比如:int a=10;

如果反彙編的話,這個10是立即數,根本就沒有空間去存它,為什麼它也是右值?

如果寫成

int &&a=10;

那也是給10新建了乙個空間,把10放裡面,然後用a指向這個空間。

按理來說這兩個10不一樣啊。。。。。。

上面的10就是一條指令中的立即數,下面的10有儲存它的空間。。。。搞不懂。

所以,我覺得右值應該是下面那個10類似的,有自己的空間。

希望大佬能指點一下。

2樓:d41d8c

以前我也指望有簡單規則,直到我發現對於

string s;

string t = true ? s : throw;

GCC 9以前認為true ? s : throw 是右值。

GCC 9以後認為它是左值。GCC 9.1和9.

2不僅認為它是右值還認為s 和t 是同乙個物件(這是bug)……

3樓:

看了書和別人的答案後自己的見解,有錯麻煩提一下

準確定義

左值和右值有沒有準確的定義? - d41d8c的回答 - 知乎 https://www.

左值和右值有沒有準確的定義? - nnnn123456789的回答 - 知乎 https://www.

快速判斷

c++ primer提到:roughly speaking,when we use an object as an rvalue,we use object's value(its content),when we use an object as an lvalue.we use the object's identity(its location in memory)

與顧露答案裡方法一:來自 Scott Meyers 的方法 ,即是否有自己的位址

左右值和底層的關係

[1][2],提到的與暫存器的關係..但是看了[3]發現沒有絕對的關係

再引用[3]中的兩條答案:

1. 左值也可以沒有對應的記憶體位址,右值變數也不見得就不能在記憶體中,左右值和是否在記憶體中沒有任何決定性的關係

2. 左值右值和暫存器沒有絕對的關係。左值右值是從語言角度定義的,標準並沒有涉及和底層實現有關的規定(比如什麼暫存器,cache,棧,堆…的概念)。

既左值右值的儲存細節是和cpu,指令集,ABI,編譯器等有關的。

總結

所以要快速區分的話還是把常用的幾種型別記下來,比如:博海和vczh說的,變數肯定是左值(包括物件和built-type),字面常量是右值

因為沒有嚴格的底層定義,沒辦法推..所以要嚴格區分還是看cpp定義的文件了吧..https://

參考:

[1]c++中的左值跟右值怎麼區分? - Eric Qiang的回答 - 知乎 https://www.

[3]C++中左值、右值與暫存器的關係是怎樣的? - 知乎 https://www.

4樓:Comedy40

MSDN上的解釋,個人感覺蠻清楚的

Every C++ expression is either an lvalue or an rvalue. Anlvaluerefers to an object thatpersists beyond a single expression. You can think of an lvalue as an object that has a name.

All variables, including nonmodifiable (const) variables, are lvalues. Anrvalueisa temporary valuethat does not persist beyond the expression that uses it.

5樓:

定義了 operator= 的object就可以當左值了,沒有定義的最多就只能當右值了。

#include

struct X;

int main()

6樓:

其實,簡單來說,左值必須是變數,所以你看到變數就知道一定可以做左值,比如a, name的之。

右值可以是變數,常量,表示式,所以一看到a, 123, "abc", (3+56+a)*b這類的都可以當右值,但注意後兩個不能是左值。

左值引用你可以理解為變數的「外號」,或者「暱稱」,跟引用的變數是同樣的,共享相同記憶體,定義的方法就是類似 int &a=b; a=3; //這時b也為3

到此為止一切都很完美,就是出了個右值引用把水搞渾了,簡直罪大惡極,建議大家都別管了╮(╯▽╰)╭

哈哈,開個玩笑,其實右值引用的基本訴求還是很好的,就是當我們辛辛苦苦的計算了乙個表示式以後,這個表示式所佔的內存在下一句就消失了,釋放掉了,那麼如果有一種機制能不需要複製,直接使用這個資源,那就提高了效率,所以這就是右值引用的意義。

舉個非常經典的例子,假設有matrix類,編寫乙個函式計算兩個matrix相加,傳統的做法如下

matrix operator +(matrix & a, matrix &b)

matrix d ,m,n;

//給m,n賦值

d=m+n;

這裡我們假設someproceed沒有消耗資源,但是建立c的時候分配了記憶體,當return c的時候,會臨時建立乙個臨時變數把c的內容複製到這個臨時量,c最後沒用了,而這個臨時量在賦值後也沒用了。

在上面d=m+n中,這樣的重複資源複製進行了,如果每個matrix都是很大的資料,那麼這種操作會帶來很大的資源浪費。

在傳統的處理中,有兩個辦法,乙個是編譯器的返回值優化,能不建立臨時變數直接返回c的記憶體位置,節省一次資源複製,但是很不可靠,因為你如果return不是最後一句有可能不會被優化,另一種是不返回變數值,而是返回指標,但是這就無法實現如 a+b+c+d這樣的表示式了,所以現在就推出了右值引用,直接表示自己是表示式的記憶體引用,這樣可以節省了複製的開銷。

上面的例子可以改寫如下

matrix && operator +(matrix & a, matrix &b)

matrix d ,m,n,p,q;

//給m,n,p,q賦值

d=m+n+p+q;

上面定義函式返回值是右值引用,這樣就可以解決上面的問題

7樓:丁冬

Every expression belongs to exactly one of the fundamental classifications in this taxonomy: lvalue, xvalue, or prvalue. This property of an expression is called its value category.

[ Note: The discussion of each built-in op e rator in Claus e 5 indicates the category of the value it yields and the value categories of the operands it expects. For example, the built-in assignment operators expect that the left operand is an lvalue and that the right operand is a prvalue and yield an lvalue as the result.

User-defined operators are functions, and the categories of values they expect and yield are determined by their parameter and return types. — end

note ]

C++11開始,表示式一般分為三類:左值(lvalue)、消亡值(xvalue)、純右值(prvalue),其中左值和消亡值統稱泛左值(glvalue),消亡值和純右值統稱右值(rvalue)。

8樓:573xmcgcg

left-hand side of an assignment expression) designates a function or an

object.

An rvalue (so called, historically, because rvalues could

a temporary object or subobject thereof, or a value that is not

associated with an object.

左值和右值有沒有準確的定義

Byron 首先,在C 11中所有的值必屬於左值 右值兩者之一。在C 11中可以取位址的 有名字的就是左值,反之,不能取位址的 沒有名字的就是右值 將亡值expiring value或純右值pure Rvalue 這裡的有名字是值得注意的,由於Move semantic perfect forwar...

c 把左值賦給左值和把右值賦給左值有什麼區別?

劉雲賓 後者會呼叫移動賦值運算子,前者只會呼叫普通複製運算子,即,後者 y 的值會改變,當然是在有移動賦值運算子的情況下 下面的程式,會測試兩者的不同 include include include int mainstd string y 123456 std string x x y std c...

c 中如何理解「左值」和 「右值」 左值是不是儲存在stack上,而右值是儲存在heap上?

AlseinX 從字面意思理解,左值和右值是指出現在賦值等號的左邊和右邊的值。右值只能出現在等號右邊,而左值只能出現在等號的左邊。左值是指變數或具有變數語義的表示式,是記憶體空間中 無論是堆還是棧 分配出來的一段用於儲存值的空間。而右值是乙個具體的,可以被計算 被得出 被儲存的資料。例如,有乙個in...