Antonshka Опубликовано 1 августа, 2022 Поделиться Опубликовано 1 августа, 2022 Привет всем, недавно видел на форуме пост @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? Или он оперирует вообще всем что слева от него и всем что справа, и рссматривает все что слева как одну единицу и все что справа как одну единицу. Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 2 августа, 2022 Поделиться Опубликовано 2 августа, 2022 Все логические операторы обладают одинаковым приоритетом и выполняются слева направо. Если тебе нужно сложное условие, ты можешь более простые условия объединять в круглые скобки, тогда приоритетно будут вычисляться выражения внутри них. В приведенном тобой примере получится if ((isAnchorEnabled && !isInLayout) || (isAnchorEnabled && layoutOwner && !layoutOwner->layout.enabled)) calculate(); Ссылка на комментарий Поделиться на другие сайты Поделиться
Antonshka Опубликовано 2 августа, 2022 Автор Поделиться Опубликовано 2 августа, 2022 2 часа назад, Xipho сказал: Все логические операторы обладают одинаковым приоритетом и выполняются слева направо. Если тебе нужно сложное условие, ты можешь более простые условия объединять в круглые скобки, тогда приоритетно будут вычисляться выражения внутри них. В приведенном тобой примере получится if ((isAnchorEnabled && !isInLayout) || (isAnchorEnabled && layoutOwner && !layoutOwner->layout.enabled)) calculate(); isAnchorEnabled повторяется два раза. Я поэтому и начал задумываться над тем как все это работает. Скобки в интернете советовали тоже, но что если без них? Как тогда поведет себя выражение. Хочу просто понять, а использовать можно и скобки. Можно ли так упростить if (isAnchorEnabled && !isInLayout || layoutOwner && !layoutOwner->layout.enabled) calculate(); isAnchorEnabled если будет true, тогда по идее далее его нет смысла проверять. Если && и || работают только с тем что конкретно слева и справа от них (а не вообще все, до конца), тогда по идее такой вариант сработает. У меня еще была мысль посмотреть в Disassembler, посмотреть как там на самом деле работает && и || в таких длинных выражениях. Ссылка на комментарий Поделиться на другие сайты Поделиться
youneuoy Опубликовано 2 августа, 2022 Поделиться Опубликовано 2 августа, 2022 1 час назад, Antonshka сказал: isAnchorEnabled если будет true, тогда по идее далее его нет смысла проверять. это не так. У тебя ведь условие || есть. Для второй части выражения isAnchorEnabled теперь не существует. 1 час назад, Antonshka сказал: У меня еще была мысль посмотреть в Disassembler, посмотреть как там на самом деле работает && и || в таких длинных выражениях. ты игры не реверсил никогда? Просто серия проверок с джампами. 1 час назад, Antonshka сказал: Если && и || работают только с тем что конкретно слева и справа от них (а не вообще все, до конца), тогда по идее такой вариант сработает. хипхо написал как они работают и скобки расставил даже. Хотя я бы напихал скобочек даже к операторам отрицания и по возможности разбил бы условие на несколько простых подряд идущих, например. Ссылка на комментарий Поделиться на другие сайты Поделиться
Antonshka Опубликовано 2 августа, 2022 Автор Поделиться Опубликовано 2 августа, 2022 (изменено) 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(); } Изменено 2 августа, 2022 пользователем Antonshka Ссылка на комментарий Поделиться на другие сайты Поделиться
youneuoy Опубликовано 2 августа, 2022 Поделиться Опубликовано 2 августа, 2022 39 минут назад, Antonshka сказал: Теперь кажется понятно. Значить действие || распространяется на все вообще части, слева от него и справа. ага, так как скобки хипхо расставил 40 минут назад, Antonshka сказал: Со скобками получается можно избавиться от повторного сравнения isAnchorEnabled если только условие теперь определяет именно то, что ты изначально задумал. Оно сложное. Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения