Перейти к содержанию

IF со множественными AND & OR


Antonshka

Рекомендуемые сообщения

Привет всем, недавно видел на форуме пост @imaginary

[bad_alloc] переполнение памяти C++

В 27.07.2022 в 20:53, imaginary сказал:

Ты знаешь что некоторые думают что если проверять всё в одном месте то будет тратить много ресурсов, потому что если вложенно, то там первое не выполнится - другие не будут тратить время. Я тоже так думала когда не разбиралась как всё работает раньше. Так что не удивительно что многие делают много условий

, и думал про себя, а я разбираюсь? Оказалось что нет.

Короткие выражения я понимаю/ Как например

if (a == 1 || a == 2)

a == 2 проверяется только если a == 1 false.

if (a == 1 && a == 2)

a == 2 проверяется только если a == 1 true.

 

Но как быть когда операторов много? Например

if (isAnchorEnabled && !isInLayout || isAnchorEnabled && layoutOwner && !layoutOwner->layout.enabled)
  calculate();

Нужно чтобы calculate() вызывался только если у контрола якорь активен и контрол НЕ в системе Layout.

Либо если у контрола якорь активен и контрол В системе Layout, но система Layout не активна.

&& layoutOwner - эта проверка указателя на null перед тем как к нему обратиться.

 

Не могу найти в интернете решение для такого выражения.

Оператор || в данном примере оперирует только !isInLayout и isAnchorEnabled? Или он оперирует вообще всем что слева от него и всем что справа, и рссматривает все что слева как одну единицу и все что справа как одну единицу.

Ссылка на комментарий
Поделиться на другие сайты

Все логические операторы обладают одинаковым приоритетом и выполняются слева направо. Если тебе нужно сложное условие, ты можешь более простые условия объединять в круглые скобки, тогда приоритетно будут вычисляться выражения внутри них.

В приведенном тобой примере получится 

if ((isAnchorEnabled && !isInLayout) || (isAnchorEnabled && layoutOwner && !layoutOwner->layout.enabled))
  calculate();
Ссылка на комментарий
Поделиться на другие сайты

2 часа назад, Xipho сказал:

Все логические операторы обладают одинаковым приоритетом и выполняются слева направо. Если тебе нужно сложное условие, ты можешь более простые условия объединять в круглые скобки, тогда приоритетно будут вычисляться выражения внутри них.

В приведенном тобой примере получится 

if ((isAnchorEnabled && !isInLayout) || (isAnchorEnabled && layoutOwner && !layoutOwner->layout.enabled))
  calculate();

 

isAnchorEnabled повторяется два раза. Я поэтому и начал задумываться над тем как все это работает.

Скобки в интернете советовали тоже, но что если без них? Как тогда поведет себя выражение. Хочу просто понять, а использовать можно и скобки.

 

Можно ли так упростить

if (isAnchorEnabled && !isInLayout || layoutOwner && !layoutOwner->layout.enabled)
  calculate();

isAnchorEnabled если будет true, тогда по идее далее его нет смысла проверять.

Если && и || работают только с тем что конкретно слева и справа от них (а не вообще все, до конца), тогда по идее такой вариант сработает.

У меня еще была мысль посмотреть в Disassembler, посмотреть как там на самом деле работает && и || в таких длинных выражениях.

Ссылка на комментарий
Поделиться на другие сайты

1 час назад, Antonshka сказал:

isAnchorEnabled если будет true, тогда по идее далее его нет смысла проверять.

это не так. У тебя ведь условие || есть. Для второй части выражения isAnchorEnabled теперь не существует.

1 час назад, Antonshka сказал:

У меня еще была мысль посмотреть в Disassembler, посмотреть как там на самом деле работает && и || в таких длинных выражениях.

ты игры не реверсил никогда? Просто серия проверок с джампами.

 

1 час назад, Antonshka сказал:

Если && и || работают только с тем что конкретно слева и справа от них (а не вообще все, до конца), тогда по идее такой вариант сработает.

хипхо написал как они работают и скобки расставил даже. Хотя я бы напихал скобочек даже к операторам отрицания и по возможности разбил бы условие на несколько простых подряд идущих, например.

Ссылка на комментарий
Поделиться на другие сайты

59 минут назад, youneuoy сказал:

это не так. У тебя ведь условие || есть. Для второй части выражения isAnchorEnabled теперь не существует.

 

Теперь кажется понятно. Значить действие || распространяется на все вообще части, слева от него и справа.

Спойлер
#include <windows.h>
#include <iostream>


VOID  calculate() {
    std::wcout << L"calculated!";
}

int main() {
    INT isAnchorEnabled = 0;
    INT isInLayout = 1;
    INT layoutOwner = 1;
    INT layoutOwnerLayoutEnabled = 0;

    if (isAnchorEnabled && TRUE && !isInLayout || layoutOwner && !layoutOwnerLayoutEnabled) {
       calculate();
    }

	//Действие || распространяется на всю левую часть - isAnchorEnabled && TRUE && !isInLayout
  	//и на всю правую часть - layoutOwner && !layoutOwnerLayoutEnabled
  
  	//Я же думал что только на - !isInLayout || layoutOwner
    return 0;
}

 

 

Со скобками получается можно избавиться от повторного сравнения isAnchorEnabled

if ( isAnchorEnabled && (!isInLayout || layoutOwner && !layoutOwner->layout.enabled) ) {
   calculate();
}

 

Изменено пользователем Antonshka
Ссылка на комментарий
Поделиться на другие сайты

39 минут назад, Antonshka сказал:

Теперь кажется понятно. Значить действие || распространяется на все вообще части, слева от него и справа.

ага, так как скобки хипхо расставил

40 минут назад, Antonshka сказал:

Со скобками получается можно избавиться от повторного сравнения isAnchorEnabled

если только условие теперь определяет именно то, что ты изначально задумал. Оно сложное.

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.