(true && true || false && false) оценивается с &&, имеющим более высокий приоритет.
TRUE && TRUE = True
FALSE && FALSE = False
True || False = True
Обновление:
1&&1||infiniteLoop()&&infiniteLoop()
Почему это дает true в C++?
Как и прежде, давайте разобьем его на части. && имеет более высокий приоритет, чем || и короткое замыкание логических операторов в C++.
1 && 1 = True.
Когда логическое значение преобразуется в целочисленное значение, тогда
false -> 0
true -> 1
Выражение оценивает этот (истинный) оператор && (истинный), который закорачивает ||, что предотвращает запуск бесконечных циклов. Там происходит гораздо больше компилятора 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: Это по-прежнему приоритет, который заставляет && оцениваться первым, но компилятор также замыкает ИЛИ. По сути, компилятор группирует порядок операций следующим образом (УПРОЩЕННОЕ ПРЕДСТАВЛЕНИЕ, опустите вниз вилы :-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.
Теперь давайте перейдем к логическим выражениям: (&& = И, || = ИЛИ)
true AND false OR true
C++ дает И более высокий приоритет, чем ИЛИ, таким образом
(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).
C++ Всегда короткие циклы, но другие языки предоставляют механизмы для так называемых "нетерпеливых" операторов.
Возьмем, к примеру, язык программирования Ада. В Аде «И» и «ИЛИ» являются «нетерпеливыми» операторами.. они заставляют все оцениваться.
В языке Ада (истина И истина) ИЛИ (ложь И ложь) будет оценивать как (истина И истина), так и (ложь И ложь) перед оценкой ИЛИ. Ada также дает вам возможность замыкания с помощью AND THEN и OR ELSE, что даст вам то же поведение, что и C++.
Я надеюсь, что это полностью отвечает на ваш вопрос. Если нет, дайте знать :-)
Обновление 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)
Precence ТОЛЬКО устанавливает группировку операций. В этом && больше, чем ||.
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())
Это своего рода факт.. и я не знаю, как еще это продемонстрировать. Приоритет определяется правилами грамматики языка. Оптимизация компилятора определяется каждым компилятором. Некоторые лучше, чем другие, но Все могут изменить порядок сгруппированных сравнений по своему усмотрению, чтобы дать ему «лучший» шанс для самого быстрого выполнения. с наименьшим количеством сравнений.
person
Caladain
schedule
31.10.2010