Это выражение (a-- == 10 && a-- == 9) вычисляет слева направо,
Да, в основном, но только потому, что &&
особенный.
и a по-прежнему равно 10 в a-- == 10
Да, потому что a--
возвращает старое значение.
но a равно 9 для a-- == 9.
Да, потому что точка последовательности в &&
гарантирует, что обновление значения a
будет завершено до того, как будет оценена RHS.
1) Существует ли четкое правило относительно того, когда оценивается постинкремент?
Лучший ответ, я думаю, "нет". Побочные эффекты из-за ++
и --
завершаются в какой-то момент до следующей точки последовательности, но дальше этого сказать нельзя. Для четко определенных выражений не имеет значения, когда завершатся побочные эффекты. Если выражение чувствительно к моменту завершения побочного эффекта, это обычно означает, что выражение не определено.
Из этого примера кажется, что он оценивается до &&, но после ==. Это потому, что логический оператор && делает выражение a-- == 10 полным, поэтому a обновляется после его выполнения?
В основном да.
2) Также для c/c++ некоторые операторы, такие как декремент префикса, выполняются справа налево.
Осторожный. Я не уверен, что вы имеете в виду, но что бы это ни было, я почти уверен, что это неправда.
поэтому a == --a сначала уменьшает a до 9, а затем сравнивает 9 == 9.
Нет, a == --a
не определено. Невозможно сказать, что он делает.
Есть ли причина, по которой c/С++ разработан таким образом?
Да.
Я знаю, что для Java все наоборот (оценивается слева направо).
Да, Java отличается.
Вот несколько рекомендаций, которые помогут вам понять вычисление выражений C:
Изучите правила приоритета операторов и ассоциативности. Для «простых» выражений эти правила сообщают вам практически все, что вам нужно знать об оценке выражения. Учитывая a + b * c
, b
умножается на c
, а затем произведение добавляется к a
из-за более высокого приоритета *
над +
. Учитывая a + b + c
, a
добавляется к b
, а затем сумма добавляется к c
, потому что +
ассоциируется слева направо.
За исключением ассоциативности (как указано в пункте 1), старайтесь не использовать слова "слева направо" или "справа налево" вообще. C не имеет ничего похожего на оценку слева направо или справа налево. (Очевидно, что Java отличается.)
Там, где это становится сложно, побочные эффекты. (Когда я сказал «простые» выражения в пункте 1, я в основном имел в виду «выражения без побочных эффектов».) Побочные эффекты включают (а) вызовы функций, (б) присваивания с =
, (в) присваивания с +=
, -=
, и т. д., и, конечно, (d) увеличение/уменьшение с помощью ++
и --
. (Если имеет значение, когда вы выбираете из переменной, что обычно имеет место только для переменных, обозначенных как volatile
, мы можем добавить (e) выборки из volatile
переменных в список.) В общем, вы не можете сказать, когда возникают побочные эффекты. Постарайтесь не заботиться. Пока вам все равно (пока ваша программа нечувствительна к порядку, в котором побочные эффекты имеют значение), это не имеет значения. Но если ваша программа является конфиденциальной, она, вероятно, не определена. (Подробнее см. в пунктах 4 и 5 ниже.)
У вас никогда не должно быть двух побочных эффектов в одном и том же выражении, которые пытаются изменить одну и ту же переменную. (Примеры: i = i++
, a++ + a++
.) В противном случае выражение не определено.
С одним классом исключений у вас никогда не должно быть побочного эффекта, который пытается изменить переменную, которая также используется в другом месте в том же выражении. (Пример: a == --a
.) В противном случае выражение не определено. Исключением является случай, когда полученное значение используется для вычисления сохраняемого значения, как в i = i + 1
.
person
Steve Summit
schedule
10.10.2018
&&
- person Tormund Giantsbane   schedule 10.10.2018(a-- == 10 & a-- == 9)
зачем вам писать такой код? - person Jean-François Fabre   schedule 10.10.2018&&
и||
предоставляют точки последовательности; операторы&
и|
этого не делают. - person Jonathan Leffler   schedule 10.10.2018&
), а не логический (&&
) - person Jonathan Wood   schedule 10.10.2018a-- ==10 & a-- == 9
? Как вы думаете, какой из них будет вычислен компилятором первым? - person Gaurav   schedule 10.10.2018if (a == --a)
— это неопределенное поведение — нет смысла строить догадки о том, что произойдет. Первое условие (теперь) определено; он должен напечатать1
. Вам лучше с новыми строками после печати. - person Jonathan Leffler   schedule 10.10.2018logical and
операторе"guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand."
. Таким образом, все побочные эффектыa-- == 10
завершаются до оценкиa-- == 9
. Это реактивный другой случай. - person ReAl   schedule 10.10.2018