C / C ++赋值运算符实现的低级细节。 它返回了什么?
我总是新手到C ++世界(也是C)。 而且不知道它的所有细节。 但有一件事让我感到困扰。 它是如下构造: while (a=b) {...}
。我理解这种魔法是有效的,因为C和C ++中的赋值运算符返回了一些东西。 所以问题是:它返回了什么? 这是一个记录在案的东西吗?它在C和C ++中的作用是否相同。 关于赋值运算符及其在C和C ++中的实现的低级细节(如果存在差异)将非常感激!
我希望这个问题不会被关闭,因为从低层次的角度来看,我无法找到关于这个主题的全面解释和良好的材料。
对于C ++中的内置类型,评估赋值表达式会生成一个左值,它是赋值表达式的左侧。 在使用结果之前对赋值进行排序,因此当结果转换为rvalue时,您将获得新分配的值:
int a, b=5; int &c = (a=b); assert(&c==&a); b=10; assert(10==(a=b));
C几乎但不完全相同。 C中赋值表达式的结果是与赋值左侧新分配的值相同的rvalue。
int *c = &(a=b); // not legal in C because you can only take the address of lvalues.
通常如果使用赋值的结果它被用作右值(例如, a=b=c
),那么C ++和C之间的这种差异很大程度上没有被注意到。
赋值运算符被定义(在C中)作为返回分配给的变量的值 – 即表达式的值(a=b)
是在计算表达式之后的a
的值。
它可以被定义为C ++中用户定义的运算符重载的不同(相同类型),但我怀疑大多数人会认为这是一个非常不愉快的运算符重载使用。
由于类型转换,您可以在while
(或if
等)中使用此(非布尔)值 – 使用条件上下文中的值会使其隐式转换为在条件上下文中有意义的值。 在C ++中,这是bool
,您可以通过重载operator bool()
来定义自己的转换(对于您自己的类型operator bool()
。 在C中,除0
之外的任何内容都是正确的。
要理解这样的表达式,您必须首先理解,正整数被认为是’真’而0被认为是假的。
赋值评估运算符的左侧=
作为其值。 因此, while(a=b) { }
意味着, while(1 /*true*/)
如果被分配给b
评估为非零。 否则,它被认为是while(0 /*false*/)
类似地,使用运算符(a=b)?1:0
是在分配给b
之后的a
的值…如果它是非零,那么该值被视为true
并且语句跟随?
将被执行,或者执行以下语句:
赋值通常计算为运算符左侧的值=
其中,逻辑运算符(例如==
, &&
etc)计算为1或0。
注意:使用C ++,它将取决于某个运算符是否过载…并且它还将取决于重载运算符的返回类型。
C和C ++中的赋值运算符返回分配给它的变量的值,即它们的左操作数。 在a = b
示例中,整个表达式的值是分配给a
的值(它是转换为b
类型的b
的值)。
所以你可以说赋值运算符“返回”其左操作数的值。
在C ++中,它有点复杂,因为您可以使用实际的用户定义函数重载=
运算符,并使其返回除左操作数的值(和类型)之外的其他内容。