Programming
Comments 54
UFO landed and left these words here
+3
ИМХО, само условие как таковое, не должно зависеть от восприятия. Оно должно быть однозначным для любого читателя. Главное это разделение скобками условий на группы. Что-то на подобии как большая буква идет в начале предложения и точка в конце. Так и скобки должны отделять начало и конец некоторого условия. Тогда все неоднозначности уходят сами собой.
+3
Кем? Компилятором или теми, кто работает с вами в команде/потом будет поддерживать код?
UFO landed and left these words here
+47
Пишу всегда со скобками. На всякий случай. Как-то так спокойнее. :)
-2
Недавно на хабре была статья, в которой говорилось, что написание лишнего кода «на всякий случай» — признак плохого программиста. Я не говорю что вы плохой программист, статья такая.
+1
Скобки — не совсем код. Для однозначного разделения приоритетов операций всегда использую скобки. Так более нагляднее где и что, особенно в длинных условиях.
-1
ИМХО, лишние символы наглядности вовсе не способствуют.
0
если условие не длинное (как в приведённом примере) то скобки не имеют смысла
а если длинное и состоит из подусловий, то нагляднее будет каждое подусловие написать в отдельной строке
UFO landed and left these words here
0
Сперва проголосовал за первый вариант, потом понял, что напишу так:
if ((a != b || c != d) && !e) { }
+6
Верно, напутал. Ниже уже поправляют.

Потому скобки обязательно и ставлю, когда намешаны ИЛИ и И — чтобы смысл был однозначен.
0
Аналогично. Скобки расставляю так, чтобы был понятен смысл разделения условий на группы.
+5
Вот кстати наглядный пример к моему комментарию ниже, ваше выражение не эквивалентно описанным, потому что приоритет && больше чем || и без скобок оно выполнится не так.
-1
Тогда уж если сохранять приоритет операций, то
if ((a != b) || ((c != d) && !e) { }
0
Вы поставили четыре открывающие скобки, но только три закрывающие. Это вызовет сообщение об ошибке.
-1
Он показал саму суть: раз уж добавлять лишние скобки, то до конца — ведь в 1м примере голосовалки все равно может быть неоднозначное восприятие. Многим приходится программировать на разных языках и там приоритет операций может быть иным, так что перестраховщики будут ставить скобку после каждой операции
+13
Ваш первый вариант добавляет избыточности, но не делает условие понятным,
потому что с приоритетами по группам легко, все помнят, что приоритет
сравнений больше чем у логических операторов.

Я пишу так:
if (a != b || (c != d && !e)) { }

Несмотря на то, что порядок приоритета логических операторов мне хорошо известен, это делает код читабельнее. Особенно в таком случае, когда операция с более высоким приоритетом стоит правее.
+1
К сожалению помнят не все, но ваш пример делает код понятнее даже для этих людей.
+12
Всегда без скобок из-за того что затрудняют понимание. Если же условие обретает форму, когда больше чем 2 под-условия, то разбиваю условие на несколько bool-евых флагов, которые читать проще.

пример разбития на несколько под условий:
bool fileOpen = (bla-bla-bla);
bool rc4used = (bla-bla-bla);
if ( fileOpen && rc4used )
{
// code
}

0
Я пользуюсь еще интересным приемом (правда это немножко иной язык программирования: perl):
{
a == b or last;
d > x + 150 or last;
f < 16 or last;
# все условия выполнены, выполняем действие

}
0
Сильно смахивает на аналог конструкции:

{
  if (!...)
    goto end;
  if (!...)
    goto end;
  if (!...)
    goto end;

// code here

end:;
}


Поэтому у меня возникают сомнения касательно правильности такого подхода
+1
return тоже «смахивает» на goto, но его никто в этом не упрекает. Есть четкий блок, внутри него условия, несовпадение условий — выход из блока. Если внимательно присмотритесь, то выход из блока используется сплошь и рядом: досрочное завершение подпрограммы с return, досрочный выход из цикла, case, иксепшины и т.д. Это нормальный прием. Сейчас объясню почему. Обычно, логика выполнения идет по одному пути: проверка, не выполнилась — свалили, проверка, не выполнилась — свалили, и т.д. Так происходит очень часто.

Например, банальная ситуация: проверили существование отправителя, нет — ошибка и конец, проверили достаточность денег на счету, нет — ошибка и коней, с получаетелем тоже самое и в конце запись в таблицу логов, нет — ошибка и конец. Если вы будете делать это через if, то создадите многоэтажную конструкцию, на 4й ступеньке ваш код перейдет в стадию «отвратный». Я практически никогда не допускаю больше 3х вложенностей.

Если же представить выполнение задачи по моему методу, то будет примерно следующее:

ok = 0;
{
проверка1 or last;
вычисления;
проверка2 or last;
вычисления;
проверка3 or last;
вычисления;
проверка4 or last;
ok = 1;
}
ok or rollback;

В такой конструкции явно прослеживается корректная цепочка операций, а все что не удовлетворяет ей — отсекается. Попробуйте, так очень удобно и понятно
+1
Ну и в добавок хочу отметить, что также в коде использую еще одну практику:
Если текст условия больше чем 25 символов, то нужно либо посмотреть в название переменных, либо составить несколько bool переменных.

Ранее у программеров была эмпирическая оценка — не больше 86 символов на строку.

Пример:
if(boost::filesystem::file_size(fpath) < minPackedImageSize && dosHeader.e_lfanew<= boost::filesystem::file_size)
{
// code
}


1) sizeof(«boost::filesystem::file_size(fpath) < minPackedImageSize && dosHeader.e_lfanew<= boost::filesystem::file_size») больше 25 символов
2) sizeof(«boost::filesystem::file_size(fpath) < minPackedImageSize») больше чем 25!!!
3) sizeof(«dosHeader.e_lfanew <= boost::filesystem::file_size») больше чем 25

Этот доп. признак позволяет мне обратить внимание на плохо написанное условие с точки зрения эстетики, а следовательно и читабельности кода.

Разбиваю на:

int fileSize = (int)boost::filesystem::file_size(fpath);
bool isCorrectElfanew = dosHeader.e_lfanew <= fileSize;
bool isImageLarge = fileSize  > minPackedImageSize;

if( !isImageLarge  && isCorrectElfanew )
{
// code
}


т.е. благодаря этому признаку, я смог остановить на «паузу» свой мозг и посмотреть на этот «дурно пахнущий» кусок кода. В спешке я бы не заметил этого.
0
Всегда пишу со скобками. Что-бы потом не удивляться как копилятор или интерпретатор обрабатывает приоритеты операторов.
0
А я их знаю. Но я не уверен что их знает данный конкретный копилятор или интерпретатор. :)
0
для одного языка — это закон, но согласен — в разных языках есть свои нюансы
+1
Когда пишешь на нескольких языках, то проще скобки поставить, чем «контекст переключать».
-2
Лучше выделить в функцию, имя которой будет полностью оправдывать ее назначение.
+1
Для 2-3 переменных — это лишнее, а для 4+ потом можно запутаться в порядке параметров.

Я бы долго бил за такое:
if (checkSomething(a, b, c, d, e)) { doSomething(); }

Учитывая, что даже человеческие названия переменных одинакового типа будут читаться не лучше «a, b, c, d, e».
0
Согласен с автором, что сложное условие лучше выносить в функцию (функции). При этом одна функция не обязательно должна содержать одно условие. Например:

if (IsSmth1(a,b) || IsSmth2(c,d,e)) {}
...
bool IsSmth1(a, b) { return a != b; }
...
bool IsSmth2(c, b, e) { return c != d && !e; }


Возможно, для данного примера делать отдельные функции избыточно и скобок вполне хватит для улучшения восприятия кода.
0
все это можно инкапсулировать в объекте, тогда и не надо будет передавать столько параметров
-3
Код есть искусство. Он должен читаться легко и быстро. Логическое выражение с лишними скобками лишь вынесет мозг в попытке его прочитать, что замедлит работу. А без лишних скобок логика условия сразу будет понятной.
0
Обычно пишу со скобками, когда выражения визуально сложны для восприятия. Выражения со >> и << всегда заключаю в скобки, т.к. уже напарывался на неверную запись условия. На мой взгляд, в C и C++ перемудрили с приоритетами.
0
Приоритетам логических операций не очень доверяю, поэтому так:
if (a != b || (c != d && !e)) { }

Сравнения ставлю в скобки только в конструкциях вида

bool q=(a!=b);

или

bool x=(a<0? a<b: a>b);
+1
Предпочитаю ставить скобки в любых сложных условиях. Помнить приоритеты операций одно, а быстро прочитать код, понять логику и быть, к тому же, достаточно уверенным в отсутствии опечаток — совсем другое.
+2
может не очень в тему, но я обожаю писать конструкции типа a=(bla bla)?(bla bla):(bla bla bla);
так вот в таких случаях почти всегда очень помогают скобки

а в обычных случаях скобки редко использую, в основном только в сложных условиях
+1
Приведенный пример я бы написал так:

if (a != b || (c != d && !e)) { }


Т.е. скобкаи я всегда явно выделяю порядок проверки условия.
0
Если бы не было паскаля, то все бы гарантированно знали, что в выражении (a != b) || (c != d) скобки не нужны.
За одно то, что в паскале логические операторы имеют приоритет над сравнением, Вирт будет гореть в аду.
0
А за то, что в C операции << и & имеют приоритет ниже, чем сложение? Хотя << это умножение, а & — остаток от деления.
0
А если серьезно, то претензия не принимается, т.к. в конструкции a != b || c != d трактовка может быть только одна. Никому в голову не придет что имелось в виду a != (b || c) != d. Поэтому именно за то что в паскале автор языка заставляет ставить скобки в совершенно однозначной ситуации надо руки обрывать.
А с битовыми операциями другое.
Там a << b + c может по замыслу программиста быть и (a << b) + c и a << (b + c) поэтому с целью увеличения читаемости там скобки не помешают.
0
Всегда без лишних скобок. Они чаще только запутывают и ухудшают читаемость.
А если возникает необходимость в скобках для улучшения читаемости, то стоит рассмотреть вариант с изменением порядка условий (не нарушая, разумеется, логику) и разделением на несколько строк.
Only logged in users are able to leave comments. , please.