C ++左值和右值

时间:2016-09-14 09:19:30

标签: c++

好的,所以我一直在学习左撇子和右撇子 - 有没有精通C / C ++的人告诉我,我的想法是否正确?

考虑代码:

int i = 3;
int j = i;

此处我们有两个左值ij,当i分配给j时,它变为隐式右值,因为存储了i的副本在j。但是,如果代码看起来像:

int i = 3;
int j = &i;

j&i都是左值,因为它们都是内存中的物理地址吗?我理解它的方式是rvalues是临时数据,而lvalues有一个物理/可引用的内存地址。

对此的任何澄清都会很棒!

3 个答案:

答案 0 :(得分:4)

变量i永远不会成为左值。如果你可以将地址操作符应用于某些东西(就像你在第二个例子中那样),那么它就是一个左值。

同样在第二个示例&i中,{em>指针指向i,其类型为int*j的声明与您要初始化它的值之间存在类型不匹配。

最后,虽然i本身是左值,但表达式&i 不是左值,因为您无法对其应用地址运算符(即你无法做&&i)。

答案 1 :(得分:3)

作为左值 rvalue 是表达式的属性。通常,构成非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

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

答案 2 :(得分:2)

  

此处我们有两个左值ij

是的

  

i分配给j时,它变为隐式右值,因为i的副本存储在j

实际上,i仍然是左值,但它已转换为右值以读取其值。这称为左值到右值的转换。 j仍然是左值。

  

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

j是左值,但&i是左值;特别是int*类型的prvalue。