2016-09-14 88 views
3

好吧,所以我一直在学习左值和右值 - 有人可以精通C/C++告诉我,如果我的思想是正确的?C++左值和右值

考虑代码:

int i = 3; 
int j = i; 

在这里,我们有两个左值ij,当i被分配到j因为i一个副本存储在j它成为一个隐含的右值。然而,如果代码看起来像:

int i = 3; 
int j = &i; 

既能j&i是左值,因为它们在内存物理地址?我理解的方式是右值是临时数据,而左值具有物理/可参考内存地址。

对此的任何澄清将是伟大的!

+3

我推荐[Strachey(1967)](http://www.itu.dk/courses/BPRD/E2009/fundamental-1967.pdf),第2部分。 – molbdnilo

+0

谢谢@molbdnilo - 我会检查该参考现在 – Alex

回答

1

在这里,我们有两个左值ij

没错

i分配给j它成为一个隐含的右值,因为i一个副本存储在j

不是,i仍然是一个左值,但它被转换为右值以读取其值。这被称为左值到右值的转换。 j仍然是一个左翼。

j&i是否都是左值,因为它们都是内存中的物理地址?

j是一个左值,但是&i是一个右值;特别是类型int*的价值。

+0

有趣 - 感谢对'&i'变成'int *'这一事实的解释。 – Alex

4

变量i永不停止作为左值。如果你可以将address-of运算符应用于某些事物(就像你在第二个例子中那样),那么它就是一个左值。

此外,在第二示例&i指针i,并具有类型int*。在j的声明和要用其初始化的值之间存在类型不匹配。

最后,虽然i本身是一个左值表达式&i左值,因为你不能应用地址的运营商给它(即你不能做&&i)。

+0

,这是非常有意义的 - 谢谢:) – Alex

3

作为左值右值是表达式的属性。通常,构成一个非const限定的标识符的所有表达式是修改左值

int i = 5; 
i; // the expression "i" is an lvalue and is modifiable 

const int j = 3; 
j; // the expression "j" is still an lvalue, but not modifiable 

左值表达式(除非合格与const)可通过任何分配时,或++运营--进行改性。您也可以在这样的表达式上应用&“address-of”运算符。

一些运算符,如一元运算符*,数组下标运算符[].->运算符也产生左值。这意味着您可以说,例如,*p = 3a[i] = 5b.c++&c->d

另一方面,不是左值的表达式是右值(它们是临时值,不能被修改)。如果您编写类似3 = 57++的东西,编译器会抱怨37子表达式不是左值。

+0

“他们是暂时的,不能修改”,这不一定是真实的。像'std :: string {} =“hi”'是完全有效的。 – TartanLlama