指针是左值还是右值?
Posted
技术标签:
【中文标题】指针是左值还是右值?【英文标题】:Is a pointer an lvalue or rvalue? 【发布时间】:2011-12-09 19:08:03 【问题描述】:在其他帖子中,我遇到了
(5.2.9/8) “指向 cv1 T 类型 D 成员的指针”类型的右值可以 转换为“指向 cv2 类型 B 成员的指针”类型的右值 T",其中 B 是 D 的基类(第 10 条),
请从语言标准中注意这一点。所以我的问题,
int i = 0;
int *p = &i;
*p = 1;
指针在所有情况下都是左值吗?什么时候作为右值处理?
【问题讨论】:
在程序的第二行中,表达式&i
是int*
类型的表达式,因此是指针被视为右值的示例。您要求获取表达式 &i
的结果并将其用作赋值运算符的右值,int *p
作为所述运算符的左值。
【参考方案1】:
指针不是那种可以是右值或左值的东西。指针是一个类型。唯一可以是右值或左值的是 表达式。
考虑这个类似的问题:“整数是左值还是右值”。好吧,也不是。 “3”是一个整数,也是一个右值。 “3=我;”是非法的。但是“i=3;”如果 'i' 是整数,则合法。所以'i'是一个整数和一个左值。 '3' 是一个整数和一个右值。
【讨论】:
你能用我的例子来说明发生了什么吗?为什么语言标准这么说?谢谢。 我不确定你到底在问什么。指针是左值还是右值的规则与任何其他表达式的规则相同。正如“3”是一个右值一样,“new foo(3)”是一个右值。正如“j”是一个左值如果“j”是一个整数类型的变量,那么“j”是一个左值如果“j”是一个指针类型的变量。正如整数类型的 const 引用是右值一样,指向整数的指针类型的 const 引用也是。类型无关紧要。 据了解,您写道:指针不能是左值或右值。所以在我的例子中:'p'不是左值吗?因为我可以把它的地址当作 &p。 是的,表达式p
是一个左值。它也是指针类型的。你的问题就像“一个想法有四个字母吗?”当我说“想法不是那种可以有四个字母的东西”时,你会回答“但是 idea 确实有四个字母!”。 表达式 可以是左值或右值。指针不能。指针类型的表达式可以是左值或右值,就像 word 可以有四个字母,无论是不是单词“idea”。
我认为正如@DavidSchwartz 指出的那样,应该意识到左值和右值是表达式的属性。在表达式中 x = 5; x 是左值,5 是右值,考虑另一个表达式 x = y,这里 x 是左值,y 是右值。 (如果我在这里犯了错误,请有人纠正我-> int x; 不是一个表达式,它更像是一个语句。左值和右值的属性只作为表达式的属性出现。【参考方案2】:
根据c standard 2011:
除了当它是 sizeof 运算符的操作数时,_Alignof 运算符、一元 & 运算符、++ 运算符、-- 运算符或 的左操作数。运算符或赋值运算符,一个 没有数组类型的左值被转换为存储的值 在指定对象中(不再是左值);这就是所谓的 左值转换。
...
名称“左值”最初来自赋值表达式 E1 = E2,其中左操作数 E1 必须是(可修改的)左值。将其视为表示对象可能更好 ''定位器值''。
因此,由可修改的指针变量组成的表达式绝对可以充当左值,指向指针的指针也是如此:
int i = 0;
int *p;
p = &i; // 'p' is lvalue
int *q = p; // 'p' is rvalue, lvalue conversion
*p = i; // '*p' is lvalue
i = *p; // '*p' is rvalue, lvalue conversion
int **pp;
pp = &p; // 'pp' is lvalue
int **qq = pp; // 'pp' is rvalue, lvalue conversion
int ***ppp;
ppp = &pp; // 'ppp' is lvalue
int ***qqq = ppp; // 'ppp' is rvalue, lvalue conversion
【讨论】:
以上是关于指针是左值还是右值?的主要内容,如果未能解决你的问题,请参考以下文章