(true && true || false && false) оценивается как && с более высоким приоритетом.
TRUE && TRUE = True
FALSE && FALSE = False
True || False = True
Обновление:
1&&1||infiniteLoop()&&infiniteLoop()
Почему это дает истину в C ++?
Как и прежде, давайте разберем его на части. && имеет более высокий приоритет, чем || и логические операторы короткого замыкания в C ++.
1 && 1 = True.
Когда значение bool конвертируется в целочисленное значение, тогда
false -> 0
true -> 1
Выражение оценивает этот (true) && (true) оператор, который замыкает ||, что препятствует выполнению бесконечных циклов. Компилятор Juju работает намного больше, так что это упрощенное представление о ситуации, подходящее для этого примера.
В среде без короткого замыкания это выражение будет зависать вечно, потому что обе стороны ИЛИ будут "оценены", а правая сторона зависнет.
Если вы не уверены в приоритете, вот как все будет оцениваться в вашем исходном сообщении, если || имеет более высокий приоритет, чем &&:
1st.) True || False = True
2nd.) True && 1st = True
3rd.) 2nd && false = false
Expression = False;
Я не могу вспомнить, идет ли он справа налево или слева направо, но в любом случае результат будет одинаковым. В вашем втором посте, если || имел более высокий приоритет:
1st.) 1||InfLoop(); Hang forever, but assuming it didn't
2nd.) 1 && 1st;
3rd.) 2nd && InfLoop(); Hang Forever
tl; dr: Первоочередной задачей является оценка && в первую очередь, но компилятор также замыкает ИЛИ. По сути, компилятор группирует порядок операций, подобных этому (SIMPLISTIC VIEW, положите вниз вилы :-P)
1st.) Is 1&&1 True?
2nd.) Evaluate if the Left side of the operation is true,
if so, skip the second test and return True,
Otherwise return the value of the second test(this is the OR)
3rd.) Is Inf() && Inf() True? (this would hang forever since
you have an infinite loop)
Обновление № 2:
«Однако этот пример доказывает, что && НЕ имеет приоритета, так как || оценивается перед вторым &&. Это показывает, что && и || имеют одинаковый приоритет и оцениваются в порядке слева направо."
"Если бы && имел приоритет, он вычислил бы первый && (1), затем второй && (бесконечные циклы) и повесил программу. Поскольку этого не происходит, && не оценивается до ||."
Давайте рассмотрим это подробно.
Мы говорим здесь о двух разных вещах. Приоритет, который определяет порядок операций, и короткое замыкание, которое является трюком компилятора / языка для сохранения циклов процессора.
Давайте сначала рассмотрим приоритет. Приоритет - это сокращение от «Порядок операций». По сути, это утверждение:
1 + 2 * 3
в каком порядке должны быть сгруппированы операции для оценки?
Математика четко определяет порядок операций, давая умножение более высокий приоритет, чем сложение.
1 + (2 * 3) = 1 + 2 * 3
2 * 3 is evaluated first, and then 1 is added to the result.
* has higher precedence than +, thus that operation is evaluated first.
Теперь давайте перейдем к логическим выражениям: (&& = AND, || = OR)
true AND false OR true
C ++ дает AND более высокий приоритет, чем OR, таким образом
(true AND false) OR true
true AND false is evaluated first, and then
used as the left hand for the OR statement
Таким образом, только по приоритету (true && true || false && false) будет работать в следующем порядке:
((true && true) || (false && false)) = (true && true || false && false)
1st Comparison.) true && true
2nd Comparison.) false && false
3rd Comparison.) Result of 1st comparison || Result of Second
Со мной до сих пор? Теперь перейдем к короткому замыканию:
В C ++ логические операторы называются «короткозамкнутыми». Это означает, что компилятор будет смотреть на данный оператор и выбирать «лучший путь» для оценки. Возьмите этот пример:
(true && true) || (false && false)
There is no need to evaluate the (false && false) if (true && true)
equals true, since only one side of the OR statement needs to be true.
Thus, the compiler will Short Circuit the expression. Here's the compiler's
Simplified logic:
1st.) Is (true && true) True?
2nd.) Evaluate if the Left side of the operation is true,
if so, skip the second test and return True,
Otherwise return the value of the second test(this is the OR)
3rd.) Is (false && false) True? Return this value
Как вы можете видеть, если (true && true) оценивается как TRUE, то нет необходимости тратить такты на оценку, если (false && false) имеет значение true.
C ++ Всегда короткие замыкания, но другие языки предоставляют механизмы для так называемых «нетерпеливых» операторов.
Возьмем, к примеру, язык программирования Ada. В Аде «И» и «ИЛИ» являются «нетерпеливыми» операторами… они заставляют все оценивать.
В Ada (истина и истина) ИЛИ (ложь И ложь) будет оценивать как (истина И истина), так и (ложь И ложь) перед оценкой ИЛИ. Ада также дает вам возможность короткого замыкания с И, ТО, ИЛИ ИЛИ, что даст вам то же поведение, что и С ++.
Надеюсь, это полностью ответит на ваш вопрос. Если нет, дайте мне знать: -)
Обновление 3: Последнее обновление, а затем я продолжу по электронной почте, если у вас все еще есть проблемы.
"Если происходит короткое замыкание оператора || и короткое замыкание при выполнении второго выражения &&, это означает, что оператор || был выполнен ДО второго оператора &&. Это подразумевает выполнение слева направо для && и|| (не && приоритет). "
Давайте посмотрим на этот пример:
(false && infLoop()) || (true && true) = true (Put a breakpoint in InfLoop and it won't get hit)
false && infLoop() || true && true = true (Put a breakpoint in InfLoop and it won't get hit)
false || (false && true && infLoop()) || true = false (infLoop doesn't get hit)
Если то, что вы говорите, было правдой, InfLoop получит удар в первых двух.Вы также заметите, что InfLoop () также не вызывается в третьем примере.
Теперь давайте посмотрим на это:
(false || true && infLoop() || true);
Infloop вызывается!Если OR имеет более высокий приоритет, чем &&, тогда компилятор оценит:
(false || true) && (infLoop() || true) = true;
(false || true) =true
(infLoop() || true = true (infLoop isn't called)
Но вызывается InfLoop!Вот почему:
(false || true && infLoop() || true);
1st Comparison.) true && InfLoop() (InfLoop gets called)
2nd Comparison.) False || 1st Comp (will never get here)
3rd Comparison.) 2nd Comp || true; (will never get here)
Precendece ONLY устанавливает группировку операций.При этом && больше, чем ||.
true && false || true && true gets grouped as
(true && false) || (true && true);
Компилятор Затем появляется и определяет, в каком порядке он должен выполнить оценку, чтобы дать ему наилучшую возможность для сохранения циклов.
Consider: false && infLoop() || true && true
Precedence Grouping goes like this:
(false && infLoop()) || (true && true)
The compiler then looks at it, and decides it will order the execution in this order:
(true && true) THEN || THEN (false && InfLoop())
Это своего рода факт ... и я не знаю, как еще это продемонстрировать.Приоритет определяется правилами грамматики языка.Оптимизация компилятора определяется каждым компилятором. Некоторые лучше, чем другие, но Все могут свободно переупорядочивать сгруппированные сравнения по своему усмотрению, чтобы дать ему «лучший» шанс для быстрого выполнения снаименьшее количество сравнений.