2012-06-19 50 views
1

在C中,有没有一种方法来识别右值和左值?C如何识别右值和左值?

其中有些是容易的身份说,在分配,左值是左值,并在右边的值是右值。

但是其他情况下,使用这种规则进行识别是困难的。

例如:*p++i++(其中p是指向整数的指针,i是整数) - 如何识别它是右值还是左值? 上下文是++*p++作品而++i++不会因为i++是一个右值(如告诉严重的家伙)。

如何识别一个表达式右值和左值?

+0

我觉得这是一个很好的问题,但你所说的“识别”的意思?你想要一个全面的操作列表,以及它们是否返回l或r值?从函数sig中告诉的一种方法?一种查看每行代码是否有左值或右值的方法? – djechlin

+0

@djechlin,通过“识别”我的意思是,我是否可以通过查看源代码(无需补充)来确定代码片段是否工作正常。没有一个全面的清单,是否有方法可以用来识别右值和左值?但是,如果有一个全面的列表存在,这对我来说很有用。 –

+0

我想你应该从忘记“右值=右值”开始,这显然是错误的。 – qdii

回答

2

左值(从左手侧(左轴)值)的东西,是指一个存储器(或寄存器)存储,以及是否可以将值分配给。 *p++左值,因为它是一个解除引用的指针(即,指的是在存储器中的位置即ptr点而ptr本身的值是该位置的地址)和++*ptr++实际上意味着:*ptr = *ptr + 1; ptr = ptr + 1; - 它递增的值指向通过ptr,然后递增指针值本身。 i++不是左值因为它是i递增1的值,而不是指一个位置在存储器中。您可以将这些值视为最终值 - 它们不能进一步修改,只能用作值赋予左值。这就是为什么他们被称为右值(从右侧(RHS)值)。

LHS和RHS指赋值表达式A = B;的两侧。 A是LHS,B是RHS。

0

从的Deitel和Deitel公司:

变量名被说成是左值(为“左值”),因为它们可以在赋值运算符的左侧被使用。据说常量是右值(对于“正确的值”),因为它们只能在赋值运算符的右侧使用。请注意,左值也可以用作右值,但反之亦然。

x = 3; /* here, x is an lvalue */ 
c = x; /* and in the next line it is an rvalue */ 
+0

听起来像他知道这一点,并想知道更全面的方法来识别它们。 – djechlin

2

术语左值已与C(和结转到C++和稍后展开)。没有右值开始。我的草案(N1570)确实列出了两次出现的术语右值 - 脚注#64中的一次,并且在索引中一次。

简而言之:在C世界中,您有两种类型的对象 - 左值以及其他所有内容。

注意脚注是不是标准的一部分,但他们能提供一些有用的见解。这里不用脚注64:

64)名称“‘左值’”从分配表达E1 = E2,其中,所述左操作数 E1需要是一个(可修改)的左值来最初。它可能更好地被认为是代表对象的'定位器值'的 。有时称为“右值”的是在该国际标准中将 描述为“表达式的值”。

左值的一个明显的例子是一个对象的标识符。作为进一步的例子,如果E是一个一元 表达式是一个指针到一个对象,* E是一个左值,指定的对象,其中E点。

这给出了一个良好的开端。现在,请记住,表达式是从对象(和操作符)构建而成的,但我们会稍微介绍一下),并且在处理对象时需要担心两件基本的事情:类型和值。让我们看看是什么的标准说一下那么类型限制(6.3.2.1/p1):

左值是潜在 指定的一个对象中的表达(与空隙比其他的对象类型);如果64)一个左值在评估时不会指定一个对象,其行为是未定义的。

此外,请注意下一行是很重要的:

当对象被说成具有特定的类型,类型是由用于指定该对象的左值指定 。

所以,一个左值可以用作类型的替代品(我们会看到这太)。接下来,就让我们一起来看看上下文,其中一个对象左值(6.3.2.1/2):

当它是sizeof操作符,该_Alignof操作者的操作,在 一元运算符&,++运算符, - 操作符或左操作数。运营商 或转让运营商

因此,这些是您需要密切关注的运营商。在所有其他情况:

不具有阵列类型被转换为存储在指定对象中的 值(并且不再左值)左值;这被称为左值 转换。

有两种特殊类型:数组和功能指示器。这些衰变即被转换为与类型的表达式“指向 到阵列对象的初始元素,是不是左值/“指针函数返回类型”‘指针为类型’”。(请记住,我们已经暂停的事实,左值可以作为类型的工作 - 这是他们做什么与sizeof_Alignof!)