需要左值作为递增操作数 - + 一元运算符
lvalue required as increment operand - + unary operator
谁能解释一下:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
int i = 0,j;
j=(+i)++;
return 0;
}
应该是
turning lvalue into rvalue example
据此:What is the purpose of the unary plus (+) operator in C?,
并给出错误:lvalue required as increment operand
。
+
一元运算符如何工作?
还有我在此站点中发现的另一种用法:
little known: The unary plus operator can be used as an "decay
operator": Given int a[10]; int b(void);, then +a is an int pointer
and +b is a function pointer. Useful if you want to pass it to a
template accepting a reference
有人也可以解释一下吗?
The result of the unary +
operator is the value of its
(promoted) operand. The integer promotions are performed on the
operand, and the result has the promoted type.
所以基本上,效果几乎总是 无操作 除了对其操作数的 int
类型提升之外。例如,
char a = 6;
size_t size_pre_promotion = sizeof(a);
size_t size_post_promotion = sizeof(+a);
由于从 char
到 int
的 type
提升, 操作数 a
的 大小从1
到 4
。操作数的 value 原样返回。
来自评论: "turning lvalue into rvalue",就是我不明白...
(+1)
两边加括号的效果
int j = (+i)++;
在此表达式 (+i)++
中,括号 ()
强制执行优先顺序以执行 i
(来自表达式 +i
)的转换lvalue
到 rvalue
,词法后跟 ++
运算符,试图增加 i
的值。 ( lexically
因为这个表达式永远不会超出编译时间进入 运行 时间。)在这一点上, i
不再是左值,因此它不再是可分配的,因此不能接受如果操作数仍然是左值通常会发生的 increment 操作。
有趣的是,下面的表达式是完全合法的:
int j = (+i);//Not attempting to assign value (increment) the operand
//so the _value_ returned from the operand is successfully assigned
//to the lvalue `j`;
int j = +i++;//Assigns the i + 1 to j
//in this case the `++` adds `1` to the operand, then the `+` unary operator returns the incremented value (essentially a no-op at this point), which in turn is assigned to the _lvalue_ `j`.
一元运算符 +
将 lvalue
转换为 rvalue
。
这些术语基本上可以分别被认为是 可分配 和 不可分配。
这些表达式也表明:
int j;
&j; //address of an lvalue
是合法的。但是:
&(+j);//cannot _take_ the address of an rvalue
不是。
How does + unary operator work?
我相信一元 -
更容易理解,因为它实际上 "does" 是 "visible"。我的意思是,让 int k = 5
然后 -k
很简单——它将正值 5
变成负值 -5
。一元 -
"calculates" 它的操作数的负数。
内置一元+
只是returns其操作数的值。结束。它什么都不做。但是,应用一元运算符会执行 promotions on its argument that are specified in the standard. From cppreference operators:
The built-in unary plus operator returns the value of its operand. The
only situation where it is not a no-op is when the operand has
integral type or unscoped enumeration type, which is changed by
integral promotion, e.g, it converts char to int or if the operand is
subject to lvalue-to-rvalue, array-to-pointer, or function-to-pointer
conversion.
因此 short
值提升为 int
。左值变为右值。数组类型退化为指针。函数类型衰减为函数指针。 Cppreference value transformations.
左值 ("left value") 是您可以分配给的东西。在你的代码中 i
是一个变量,你可以 i = 1
将值 1
赋值给 i
。 2 + 2
是一个右值 ("right value"),其值为 4
- 你不能 "assign" 任何 2 + 2
, 它已经有一个值。
+i
是一元 +
应用于 i
的结果 - i
经历了整数提升和左值到右值的转换以及一元 +
操作的结果在这些转换后与 i
具有相同的值和类型。
lvalue 是一个可能指定对象(内存中的字节)的表达式。最常见的左值形式只是一个名称:给定 int x
、float y
或 char z[10]
,然后 x
、y
和 z
是左值。左值的另一种形式是一元*
的结果:给定double *p;
,那么*p
是一个左值。1
当我们使用左值来计算表达式时,它们会变成它们对象的值:x+3
比 x
中的任何值多产生三个。在此表达式中,x
用于其 值 。相比之下,在x = 7;
中,直接使用x
作为它的左值; 7 被写入内存中的字节,无论它们之前包含什么值。
由于 C 标准必须在技术细节上指定编译器的行为方式,因此它指定,当在表达式中我们需要其值的地方使用左值时,该左值将转换为值。为了强调这个结果只是一个数字或类似的东西,不再是对内存的引用,它可能被称为rvalue.
一元 +
是一个运算符。当应用于算术值时,它会产生相同的值。但是,它只产生一个值,而不是左值。因此,将 +
应用于左值会产生右值。
脚注
1 这就是为什么一个左值 可能 指定一个对象:*p
是一个左值并且在编译,但是,当程序执行时,p
可能被设置为空指针,因此 *p
实际上不是一个对象。那将是程序中的错误,但它是 运行 时间错误。
++
运算符期望它的操作数是一个 左值 - 基本上,一个可以指定对象的表达式(在 C 意义上,一块内存可用于存储值)。
然而,一元运算符 +
的结果不是左值。在这种情况下,+i
的结果只是值 0
,因此表达式等同于写 0++
。您不能将 ++
运算符应用于 0
,就像您不能编写 0 = 1
一样 - 您不能将值分配给一个值,您只能将一个值分配给一个对象到一个左值。
请注意,以下会起作用:
j = +(i++); // or just +i++, precedence is the same
您将 +
运算符应用于 i++
的结果,即 0
(后缀 ++
的计算结果为 i
的当前 值,并且作为 副作用 递增 i
)。 i++
的结果也不是左值,但 +
不要求其操作数是左值。
谁能解释一下:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
int i = 0,j;
j=(+i)++;
return 0;
}
应该是
turning lvalue into rvalue example
据此:What is the purpose of the unary plus (+) operator in C?,
并给出错误:lvalue required as increment operand
。
+
一元运算符如何工作?
还有我在此站点中发现的另一种用法:
little known: The unary plus operator can be used as an "decay
operator": Given int a[10]; int b(void);, then +a is an int pointer
and +b is a function pointer. Useful if you want to pass it to a
template accepting a reference
有人也可以解释一下吗?
The result of the unary
+
operator is the value of its (promoted) operand. The integer promotions are performed on the operand, and the result has the promoted type.
所以基本上,效果几乎总是 无操作 除了对其操作数的 int
类型提升之外。例如,
char a = 6;
size_t size_pre_promotion = sizeof(a);
size_t size_post_promotion = sizeof(+a);
由于从 char
到 int
的 type
提升, 操作数 a
的 大小从1
到 4
。操作数的 value 原样返回。
来自评论: "turning lvalue into rvalue",就是我不明白...
(+1)
int j = (+i)++;
在此表达式 (+i)++
中,括号 ()
强制执行优先顺序以执行 i
(来自表达式 +i
)的转换lvalue
到 rvalue
,词法后跟 ++
运算符,试图增加 i
的值。 ( lexically
因为这个表达式永远不会超出编译时间进入 运行 时间。)在这一点上, i
不再是左值,因此它不再是可分配的,因此不能接受如果操作数仍然是左值通常会发生的 increment 操作。
有趣的是,下面的表达式是完全合法的:
int j = (+i);//Not attempting to assign value (increment) the operand
//so the _value_ returned from the operand is successfully assigned
//to the lvalue `j`;
int j = +i++;//Assigns the i + 1 to j
//in this case the `++` adds `1` to the operand, then the `+` unary operator returns the incremented value (essentially a no-op at this point), which in turn is assigned to the _lvalue_ `j`.
一元运算符 +
将 lvalue
转换为 rvalue
。
这些术语基本上可以分别被认为是 可分配 和 不可分配。
这些表达式也表明:
int j;
&j; //address of an lvalue
是合法的。但是:
&(+j);//cannot _take_ the address of an rvalue
不是。
How does + unary operator work?
我相信一元 -
更容易理解,因为它实际上 "does" 是 "visible"。我的意思是,让 int k = 5
然后 -k
很简单——它将正值 5
变成负值 -5
。一元 -
"calculates" 它的操作数的负数。
内置一元+
只是returns其操作数的值。结束。它什么都不做。但是,应用一元运算符会执行 promotions on its argument that are specified in the standard. From cppreference operators:
The built-in unary plus operator returns the value of its operand. The only situation where it is not a no-op is when the operand has integral type or unscoped enumeration type, which is changed by integral promotion, e.g, it converts char to int or if the operand is subject to lvalue-to-rvalue, array-to-pointer, or function-to-pointer conversion.
因此 short
值提升为 int
。左值变为右值。数组类型退化为指针。函数类型衰减为函数指针。 Cppreference value transformations.
左值 ("left value") 是您可以分配给的东西。在你的代码中 i
是一个变量,你可以 i = 1
将值 1
赋值给 i
。 2 + 2
是一个右值 ("right value"),其值为 4
- 你不能 "assign" 任何 2 + 2
, 它已经有一个值。
+i
是一元 +
应用于 i
的结果 - i
经历了整数提升和左值到右值的转换以及一元 +
操作的结果在这些转换后与 i
具有相同的值和类型。
lvalue 是一个可能指定对象(内存中的字节)的表达式。最常见的左值形式只是一个名称:给定 int x
、float y
或 char z[10]
,然后 x
、y
和 z
是左值。左值的另一种形式是一元*
的结果:给定double *p;
,那么*p
是一个左值。1
当我们使用左值来计算表达式时,它们会变成它们对象的值:x+3
比 x
中的任何值多产生三个。在此表达式中,x
用于其 值 。相比之下,在x = 7;
中,直接使用x
作为它的左值; 7 被写入内存中的字节,无论它们之前包含什么值。
由于 C 标准必须在技术细节上指定编译器的行为方式,因此它指定,当在表达式中我们需要其值的地方使用左值时,该左值将转换为值。为了强调这个结果只是一个数字或类似的东西,不再是对内存的引用,它可能被称为rvalue.
一元 +
是一个运算符。当应用于算术值时,它会产生相同的值。但是,它只产生一个值,而不是左值。因此,将 +
应用于左值会产生右值。
脚注
1 这就是为什么一个左值 可能 指定一个对象:*p
是一个左值并且在编译,但是,当程序执行时,p
可能被设置为空指针,因此 *p
实际上不是一个对象。那将是程序中的错误,但它是 运行 时间错误。
++
运算符期望它的操作数是一个 左值 - 基本上,一个可以指定对象的表达式(在 C 意义上,一块内存可用于存储值)。
然而,一元运算符 +
的结果不是左值。在这种情况下,+i
的结果只是值 0
,因此表达式等同于写 0++
。您不能将 ++
运算符应用于 0
,就像您不能编写 0 = 1
一样 - 您不能将值分配给一个值,您只能将一个值分配给一个对象到一个左值。
请注意,以下会起作用:
j = +(i++); // or just +i++, precedence is the same
您将 +
运算符应用于 i++
的结果,即 0
(后缀 ++
的计算结果为 i
的当前 值,并且作为 副作用 递增 i
)。 i++
的结果也不是左值,但 +
不要求其操作数是左值。