在 C/C++ 中使用复合赋值的真正优势是什么(或者也可能适用于许多其他编程语言)?
#include <stdio.h>
int main()
{
int exp1=20;
int b=10;
// exp1=exp1+b;
exp1+=b;
return 0;
};
我查看了一些链接,如 microsoft site 、 SO post1 、 SO Post2 。
但优点是 exp1 在复合语句的情况下只评估一次。在第一种情况下,exp1 如何真正评估两次?我知道首先读取 exp1 的当前值,然后添加新值。更新的值被写回相同的位置。在复合语句的情况下,这是如何在较低级别真正发生的?我试图比较两种情况的汇编代码,但我没有看到它们之间有任何区别。
最佳答案
对于涉及普通变量的简单表达式,
a = a + b;
和
a += b;
只是语法。这两个表达式的行为完全相同,并且很可能生成相同的汇编代码。 (你是对的;在这种情况下,询问
a
是否被评估一次或两次甚至没有多大意义。)有趣的是,赋值的左侧是一个涉及副作用的表达式。所以如果你有类似的东西
*p++ = *p++ + 1;
相对
*p++ += 1;
它有更大的不同!前者尝试将
p
增加两次(因此未定义)。但后者只计算 p++
一次,并且是明确定义的。正如其他人所提到的,符号方便和可读性也有优势。如果你有
variable1->field2[variable1->field3] = variable1->field2[variable2->field3] + 2;
可能很难发现错误。但是如果你使用
variable1->field2[variable1->field3] += 2;
甚至不可能有那个错误,后来的读者不必仔细检查条款来排除这种可能性。
一个小优势是它可以为您节省一对括号(或者如果您不使用这些括号,则可以避免错误)。考虑:
x *= i + 1; /* straightforward */
x = x * (i + 1); /* longwinded */
x = x * i + 1; /* buggy */
最后(感谢 Jens Gustedt 提醒我这一点),我们必须回过头来更仔细地思考我们所说的“有趣的地方是当作业的左侧是一个涉及副作用。”通常,我们认为修改是副作用,而访问是“免费的”。但是对于限定为
volatile
(或在 C11 中为 _Atomic
)的变量,访问也被视为一个有趣的副作用。因此,如果变量 a
具有这些限定符之一,那么 a = a + b
就不是“涉及普通变量的简单表达式”,毕竟它可能与 a += b
不太相同。关于c - 使用复合赋值的优势,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49922133/