порядок приоритетов операторов и путаница при оценке

В книгах и Вот это учитывая, что приоритет приращения & оператор декремента больше, чем троичный оператор, но почему в приведенном ниже коде значения b и c не увеличиваются, а только увеличивается на b (или c нарастает, если условие ложно)

int a=1,h;
h = (a==1)?++b:++c;
printf("%d%d",b,c);

или даже для таких заявлений, как

++i&&++j||++k;   // why not all the increment and decrement operator executes first

пожалуйста, объясните, если я делаю какую-то концептуальную ошибку
(если это дубликат, пожалуйста, перенаправьте меня на оригинальный вопрос, я не нашел его)

-3

Решение

Условный (?:), логическое соединение (&&) и логическая дизъюнкция (||) операторы ленивы. Они только оценивают операнды, необходимые для получения результата.

В случае условного оператора он оценивает только одну из двух ветвей; первый, если условие оценивается как истинное, или второй, если условие оценивается как ложное.

Оператор логического соединения не будет оценивать выражение правой части, если выражение левой части оценивается как ложное, потому что результат будет ложным, несмотря ни на что. Оператор логического дизъюнкции работает аналогичным образом, с той разницей, что он не будет оценивать правую часть, если левая часть будет иметь значение true: true || x всегда верно, независимо от x,


Если вы не имеете дело с перегруженным && или же ||, Перегруженные операторы не могут выполнять ленивую оценку операндов.

4

Другие решения

За h = (a==1)?++b:++c; увидеть C11 6.5.15 Условный оператор p4 (мой акцент

Первый операнд оценивается; есть точка последовательности между его
оценка и оценка второго или третьего операнда
(что бы ни оценивалось). Второй операнд вычисляется только если
сначала сравнивается с неравным 0; третий операнд вычисляется только если
первое сравнение равно 0
;

Это подтверждает, что ваше наблюдение, что только один из ++b а также ++c выполнены правильно.

За ++i&&++j||++k; см. разделы C11 6.5.13, 6.5.14. И логические операторы OR, и AND оценивают слева направо, пропуская оценку дальнейших выражений, когда результат известен (то есть, когда выражение оценивается как ненулевое для ||; как только выражение оценивается в ноль для &&).

2

Тернарный оператор оценивает только условный операнд и операнд, который оказывается истинным. ++c часть в вашем случае не оценивается вообще.

Во втором случае не все операнды оцениваются, потому что || а также && операторы делают то, что называется «коротким замыканием», то есть, если у целого выражения больше нет шансов изменить свой результат, остальные операнды не оцениваются.

1

Приоритет не контролирует порядок оценки.. Он только контролирует, как операторы и операнды группируются вместе.

Оба || а также && операторы выполняют оценку слева направо, и оба являются операторами «короткого замыкания»; если значение выражения можно определить из левого выражения, то правое выражение вообще не будет оцениваться.

Так, учитывая выражение как

a++ || b++ && c++

если результат a++ не равен нулю, то результат будет истинным независимо от результата b++ && c++, поэтому правая часть вообще не оценивается.

0
По вопросам рекламы [email protected]