C/C++ 赋值运算符实现的低级细节。它返回啥?
Posted
技术标签:
【中文标题】C/C++ 赋值运算符实现的低级细节。它返回啥?【英文标题】:Low level details of C/C++ assignment operator implementation. What does it return?C/C++ 赋值运算符实现的低级细节。它返回什么? 【发布时间】:2013-01-19 19:06:27 【问题描述】:我完全是 C++ 世界(以及 C)的新手。并且不知道它的所有细节。但有一件事真的让我很困扰。
它是这样的结构:
while (a=b) ...
。据我了解,这种魔法之所以有效,是因为 C 和 C++ 中的赋值运算符会返回一些东西。
所以问题是:它返回什么?这是记录在案的事情吗?它在 C 和 C++ 中的工作方式相同吗?非常感谢有关赋值运算符及其在 C 和 C++ 中的实现(如果有区别)的低级细节!
我希望这个问题不要被关闭,因为从低层次的角度我找不到关于这个主题的全面解释和好的材料。
【问题讨论】:
***.com/questions/4421706/operator-overloading @chris 谢谢,但我想要更广泛的解释 返回分配给a
的内容。除非运算符被重载以返回其他内容。
@modifiablelvalue 不知道是不是误会你了,不过签名大多都是T &operator =(T &left, const T &right)
,返回left
。否则你不能使用a = b = c
。
C++ 中的@Kay returning
与C 中的evaluating
不同。
【参考方案1】:
对于 C++ 中的内置类型,对赋值表达式求值会产生一个左值,它位于赋值表达式的左侧。在结果可以使用之前赋值是排序的,所以当结果转换为右值时,你会得到新分配的值:
int a, b=5;
int &c = (a=b);
assert(&c==&a);
b=10;
assert(10==(a=b));
C 几乎但不完全相同。 C 中赋值表达式的结果是一个右值,与新分配给赋值左侧的值相同。
int *c = &(a=b); // not legal in C because you can only take the address of lvalues.
通常,如果完全使用赋值的结果,它会被用作右值(例如,a=b=c
),因此 C++ 和 C 之间的这种差异基本上不会被注意到。
【讨论】:
【参考方案2】:赋值运算符被定义为(在 C 中)返回分配给的变量的值 - 即表达式 (a=b)
的值是表达式计算后的 a
的值。
对于 C++ 中用户定义的运算符重载,可以将其定义为不同的(相同类型),但我怀疑大多数人会认为这是对运算符重载的非常不愉快的使用。
由于类型转换,您可以在 while
(或 if
等)中使用此(非布尔)值 - 在条件上下文中使用值会导致它被隐式转换为使有条件的语境中的意义。在 C++ 中,这是bool
,您可以通过重载operator bool()
来定义您自己的转换(针对您自己的类型)。在 C 中,0
以外的任何内容都是 true。
【讨论】:
【参考方案3】:要理解这样的表达,你首先要明白,正整数被认为是“真”,0被认为是假。
赋值运算以运算符=
的左侧作为其值。因此,while(a=b)
意味着,如果 a
在分配给 b
后评估为非零,则 while(1 /*true*/)
。否则视为while(0 /*false*/)
类似地,(a=b)?1:0
运算符是a
赋值给b
后的值。如果它不为零,则该值被视为true
,?
后面的语句将被执行,或者:
后面的语句被执行。
赋值通常计算为运算符 =
左侧的值,其中逻辑运算符(例如 ==
、&&
等)计算为 1 或 0。
注意:在 C++ 中,它取决于某个运算符是否被重载。它还取决于重载运算符的返回类型。
【讨论】:
三元运算符的优先级高于赋值。a=b ? 1 : 0
被解析为a = (b ? 1 : 0)
。
@Aniket:在 C++ 中,默认的复制赋值返回对左侧的引用,即使它没有重载。【参考方案4】:
C 和 C++ 中的赋值运算符返回被赋值变量的值,即它们的左操作数。在您的a = b
示例中,整个表达式的值是分配给a
的值(这是b
的值转换为a
的类型)。
所以你可以说赋值运算符“返回”其左操作数的值。
在 C++ 中它稍微复杂一些,因为您可以使用实际的用户定义函数重载 =
运算符,并让它返回左操作数的值(和类型)以外的东西。
【讨论】:
以上是关于C/C++ 赋值运算符实现的低级细节。它返回啥?的主要内容,如果未能解决你的问题,请参考以下文章