在以下代码中,*a
是左值还是右值?
#include <stdio.h>
void main()
{
int b=2;
int *a=NULL;
a=&b;
*a=3;
printf("%d",*a);
}
答案 0 :(得分:1)
在[{3}}中公开:
Lvalues具有可由运行程序以编程方式访问的存储器地址(例如,通过某些操作符地址,如C / C ++中的“&amp;”),这意味着它们是对某个存储器位置的变量或解引用引用。 Rvalues可以是左值(见下文)或非左值(
)
所以,* a是左值
答案 1 :(得分:1)
它是一个l值,可以在r值的上下文中使用。见例子;
int i, j, *p, *q;
p = &i;
q = &j;
*p = 1; // *p is l-value
*q = 2; // *q is l-value
*p = *q // *q is r-value
正如Charles Bailey在评论中指出: - 子表达式*q
仍为l值,经历l值到r值转换因为它用于需要r值的上下文中。
现在有人可能会认为为什么*q
仍然是l值?
因为根据r值 的定义,r值是一个临时值,不会超出使用它的表达式。
在这种情况下,*q
的值仍然超出表达式*p = *q
。
注意:
“*”运算符 - deference / indirection运算符 - 对指针变量进行操作,并返回与指针地址处的值等效的 l-value 。
答案 2 :(得分:0)
根据p197§A5上的K&R第二版:
...左值是引用对象的表达式...例如, 如果
E
是指针类型的表达式,则*E
是左值 表示E
指向的对象的表达式。
另外,斯科特·迈耶斯(Scott Meyers)在他的《有效现代C ++,简介-术语和约定》中提出了另一种确定左值/右值的简单方法:
确定表达式是否为左值的有用启发式是 询问您是否可以使用它的地址。如果可以,通常是这样。如果 您不能,通常是右值。这种启发式方法的一个不错的功能是 它可以帮助您记住表达式的类型是 与表达式是左值还是右值无关。
因此,当*p
表达式出现在左侧时,它是lvalue
,而右边是rvalue
。