Для простых выражений, включающих обычные переменные, разница между
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 */
Наконец (спасибо Йенсу Густедту за напоминание об этом), мы должны вернуться назад и подумать немного более тщательно о том, что мы имели в виду, когда сказали: «Что становится интересным, так это когда левая часть задания представляет собой выражение, включающее побочные эффекты." Обычно мы думаем о модификациях как о побочных эффектах, а доступы — как о «бесплатных». Но для переменных, определяемых как volatile
(или, в C11, как _Atomic
), доступ также считается интересным побочным эффектом. Таким образом, если переменная a
имеет один из этих квалификаторов, a = a + b
не является «простым выражением, включающим обычные переменные», и, в конце концов, оно может быть не таким уж идентичным a += b
.
person
Steve Summit
schedule
19.04.2018
1 + 2
в C, это будет скомпилировано во что-то вродеmove 1,a
иadd 2,a
. - person SeverityOne   schedule 19.04.2018