在 C/C++ 中使用复合赋值的真正优势是什么(或者也可能适用于许多其他编程语言)?

#include <stdio.h>

int main()
{
    int exp1=20;
    int b=10;
   // exp1=exp1+b;
    exp1+=b;

    return 0;
};

我查看了一些链接,如 microsoft siteSO post1SO 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/

10-13 06:16