10

我是 C++ 世界(以及 C 语言)的新手。并且不知道它的所有细节。但有一件事真的让我很困扰。它是这样的结构: 。据while (a=b) {...}我了解,这种魔术之所以有效,是因为 C 和 C++ 中的赋值运算符会返回一些东西。所以问题是:它返回什么?这是记录在案的事情吗?它在 C 和 C++ 中的工作方式相同吗?非常感谢有关赋值运算符及其在 C 和 C++ 中的实现(如果有区别)的低级细节!

我希望这个问题不会被关闭,因为从低层次的角度来看,我找不到关于这个主题的全面解释和好的材料。

4

4 回答 4

17

对于 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 之间的这种差异在很大程度上不会被注意到。

于 2013-02-04T23:39:41.063 回答
7

赋值运算符(在 C 中)被定义为返回被赋值的变量的值 - 即表达式(a=b)的值是a表达式计算后的值。

对于 C++ 中用户定义的运算符重载,可以将其定义为不同的(相同类型),但我怀疑大多数人会认为这是对运算符重载的非常不愉快的使用。

while由于类型转换,您可以在 a (或 an等)中使用此(非布尔)值if- 在条件上下文中使用值会导致它被隐式转换为在条件上下文中有意义的东西。在 C++ 中,这是bool,您可以通过重载定义自己的转换(针对您自己的类型)operator bool()。在 C 中,除此之外的任何内容0都是正确的。

于 2013-02-04T23:50:02.603 回答
1

要理解这样的表达式,你首先要明白,正整数被认为是“真”,而 0 被认为是假。

赋值运算将运算符的左侧=作为其值。因此,while(a=b) { }这意味着,while(1 /*true*/)如果a在被分配给之后b评估为非零。否则,它被认为是while(0 /*false*/)

同理,with 运算符(a=b)?1:0aafter 赋值给b.. 的值,如果非零则取值为 as true,执行后面?的语句,或者执行后面的语句:

赋值通常计算为运算符左侧的值,=其中逻辑运算符(例如==&&等)计算为 1 或 0。

注意:对于 C++,它取决于某个运算符是否被重载.. 它还取决于重载运算符的返回类型。

于 2013-02-04T23:36:32.973 回答
0

C 和 C++ 中的赋值运算符返回被赋值的变量的值,即它们的左操作数。在您的 示例中a = b,整个表达式的值是分配给a的值(这是b转换为 的类型的值a)。

因此,您可以说赋值运算符“返回”其左操作数的值。

在 C++ 中它稍微复杂一些,因为您可以=使用实际的用户定义函数重载运算符,并让它返回左操作数的值(和类型)以外的东西。

于 2013-02-04T23:41:42.963 回答