Как вы пишете условия в СИ-подобных языках? Со скобками в условиях или без?

     

    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

    Как вы пишете условия в СИ-подобных языках? Со скобками в условиях или без?

    • 62.1%if ((a != b) || (c != d) && !e) { }1654
    • 34.8%if (a != b || c != d && !e) { }928
    • 2.9%Свой вариант, напишу в комментариях79
    Поделиться публикацией

    Комментарии 54

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

                        Потому скобки обязательно и ставлю, когда намешаны ИЛИ и И — чтобы смысл был однозначен.
                        0
                        Аналогично. Скобки расставляю так, чтобы был понятен смысл разделения условий на группы.
                          +5
                          Вот кстати наглядный пример к моему комментарию ниже, ваше выражение не эквивалентно описанным, потому что приоритет && больше чем || и без скобок оно выполнится не так.
                            –1
                            Тогда уж если сохранять приоритет операций, то
                            if ((a != b) || ((c != d) && !e) { }
                              0
                              У вас перед блоком 1 скобки не хватает закрывающей.
                                0
                                Я думаю идея ясна, а скобки переживут.
                                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
                                }
                                
                                
                                  +1
                                  Я в таких случаях ещё добавляю const к объявлению.
                                    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;

                                        В такой конструкции явно прослеживается корректная цепочка операций, а все что не удовлетворяет ей — отсекается. Попробуйте, так очень удобно и понятно
                                          0
                                          Понял, осознал.
                                      +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
                                          А я их знаю. Но я не уверен что их знает данный конкретный копилятор или интерпретатор. :)
                                            0
                                            для одного языка — это закон, но согласен — в разных языках есть свои нюансы
                                              +1
                                              Когда пишешь на нескольких языках, то проще скобки поставить, чем «контекст переключать».
                                        0
                                        Вот так: if(a && (b || (c && d)))
                                          –2
                                          Лучше выделить в функцию, имя которой будет полностью оправдывать ее назначение.
                                            +1
                                            Для 2-3 переменных — это лишнее, а для 4+ потом можно запутаться в порядке параметров.

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

                                            Учитывая, что даже человеческие названия переменных одинакового типа будут читаться не лучше «a, b, c, d, e».
                                              +1
                                              if (checkSmth1(a,b) || (checkSmth2(c,d) && checkSmth3(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);
                                                    +3
                                                    if(  (a != b || c != d) && 
                                                        !(x != y || z != w) &&
                                                         (g != f || r != w) ) 
                                                    { 
                                                    }
                                                    
                                                      +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
                                                                Не знаю, стоит ли Вирту отвечать за это.
                                                                  0
                                                                  А если серьезно, то претензия не принимается, т.к. в конструкции a != b || c != d трактовка может быть только одна. Никому в голову не придет что имелось в виду a != (b || c) != d. Поэтому именно за то что в паскале автор языка заставляет ставить скобки в совершенно однозначной ситуации надо руки обрывать.
                                                                  А с битовыми операциями другое.
                                                                  Там a << b + c может по замыслу программиста быть и (a << b) + c и a << (b + c) поэтому с целью увеличения читаемости там скобки не помешают.
                                                                0
                                                                Всегда без лишних скобок. Они чаще только запутывают и ухудшают читаемость.
                                                                А если возникает необходимость в скобках для улучшения читаемости, то стоит рассмотреть вариант с изменением порядка условий (не нарушая, разумеется, логику) и разделением на несколько строк.

                                                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                Самое читаемое