对于涉及普通变量的简单表达式,
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 中为 as _Atomic
)的变量,访问也算作一个有趣的副作用。因此,如果 variablea
具有这些限定符之一,则不是“涉及普通变量的简单表达式”,毕竟a = a + b
它可能与 不完全相同。a += b