Другой способ использовать ключевое слово continue в C ++ - PullRequest
13 голосов
/ 29 сентября 2010

Недавно мы нашли «хороший способ» закомментировать строки кода, используя continue:

for(int i=0; i<MAX_NUM; i++){
  ....
  .... //--> about 30 lines of code
  continue;
  ....//--> there is about 30 lines of code after continue
  ....
}

Я ломаю голову, спрашивая, почему предыдущий разработчик поместил ключевое слово continue в интенсивном цикле. Скорее всего, он / она чувствует, что проще поставить ключевое слово «continue» вместо удаления всего нежелательного кода ...

Это вызывает у меня другой вопрос, глядя на сценарий ниже:

Сценарий A:

for(int i=0; i<MAX_NUM; i++){
  ....
  if(bFlag)
    continue;
  ....//--> there is about 100 lines of code after continue
  ....
}

Сценарий B:

for(int i=0; i<MAX_NUM; i++){
  ....
  if(!bFlag){
  ....//--> there is about 100 lines of code after continue
  ....
  }
}

Как вы думаете, что лучше? Зачем? Как насчет ключевого слова break?

Ответы [ 7 ]

23 голосов
/ 29 сентября 2010

Использование continue в этом случае значительно уменьшает вложенность и часто делает код более читабельным.

Например:

for(...) {
    if( condition1 ) {
        Object* pointer = getObject();
        if( pointer != 0 ) {
            ObjectProperty* property = pointer->GetProperty();
            if( property != 0 ) {
        ///blahblahblah...
        }
     }
}

становится просто

for(...) {
    if( !condition1 ) {
        continue;
    }
    Object* pointer = getObject();
    if( pointer == 0 ) {
        continue;
    }
    ObjectProperty* property = pointer->GetProperty();
    if( property == 0 ) {
       continue;
    }

    ///blahblahblah...
}

Видите ли, код становится линейным, а не вложенным.

Вы также можете найти ответы на этот тесно связанный вопрос полезный.

6 голосов
/ 29 сентября 2010

По первому вопросу это может быть способ пропустить код, не комментируя и не удаляя его.Я бы не рекомендовал делать это.Если вы не хотите, чтобы ваш код выполнялся, не ставьте перед ним продолжение / останов / возврат, так как это вызовет путаницу, когда вы / другие просматриваете код, и может рассматриваться как ошибка.

Что касается вашего второго вопроса, они в основном идентичны (зависит от выходных данных сборки) по производительности и сильно зависят от дизайна.Это зависит от того, как вы хотите, чтобы читатели кода «перевели» его на английский, как это делают большинство при чтении кода назад.

Итак, первый пример может гласить: «Делай, бла, бла, бла. Если(выражение), переходите к следующей итерации. "В то время как второй может читать «Do бла, бла, бла. If (выражение), do бла, бла, бла»

Таким образом, использование оператора continue может привести к подрыву важности кода, следующего за ним.

По моему мнению, я бы предпочел продолжить, если бы мог, потому что это уменьшило бы вложенность.

4 голосов
/ 06 октября 2010

continue полезно в высокой сложности для цикла. Это плохая практика использовать его для комментирования оставшегося кода цикла даже для временной отладки, так как люди склонны забывать ...

4 голосов
/ 29 сентября 2010

Я ненавижу комментировать неиспользованный код.Что я сделал, так это:

Я полностью удаляю их и затем возвращаюсь в систему контроля версий.

Кому еще нужно закомментировать неиспользованный код после изобретения исходного кодаконтроль кода?

4 голосов
/ 29 сентября 2010

Я согласен с другими ответчиками, что первое использование continue - ПЛОХО . Неиспользуемый код должен быть удален (если он вам понадобится позже, вы всегда можете найти его в SCM - вы действительно используете SCM, верно?: -)

Во-вторых, в некоторых ответах подчеркивалась удобочитаемость, но я упускаю одну важную вещь: IMO первым шагом должно быть извлечение этих 100 строк кода в один или несколько отдельных методов . После этого цикл становится намного короче и проще, и поток выполнения становится очевидным . Если я могу извлечь код в один метод, я лично предпочитаю if:

for(int i=0; i<MAX_NUM; i++){
  ....
  if(!bFlag){
    doIntricateCalculation(...);
  }
}

Но continue было бы для меня почти одинаково хорошо. Фактически, если в этих 100 строках кода есть несколько continue s / return s / break s, его невозможно извлечь в один метод, поэтому рефакторинг может закончиться серией continue с и вызовы методов:

for(int i=0; i<MAX_NUM; i++){
  ....
  if(bFlag){
    continue;
  }
  SomeClass* someObject = doIntricateCalculation(...);
  if(!someObject){
    continue;
  }
  SomeOtherClass* otherObject = doAnotherIntricateCalculation(someObject);
  if(!otherObject){
    continue;
  }
  // blah blah
}
4 голосов
/ 29 сентября 2010

Использование "1001" в качестве "комментария" примерно так же оскорбительно, как и переход :-).Очень просто ввести #if 0/#endif или /*...*/, и многие редакторы затем раскрасят закомментированный код, так что сразу станет ясно, что он не используется.(Мне иногда нравится, например, #ifdef USE_OLD_VERSION_WITH_LINEAR_SEARCH, поэтому я знаю, что там осталось, учитывая, что для меня сразу очевидно, что у меня никогда не было бы такого глупого имени макроса, если бы я действительно ожидал, что кто-то определит его во время компиляции ... думаю, я быЯ должен объяснить это команде, если я поделился кодом в этом состоянии.) Другие ответы указывают на то, что системы контроля версий позволяют вам просто удалить закомментированный код, и, хотя это моя практика перед коммитом, часто есть этап «работы», когдавы хотите, чтобы это было максимально удобно для перекрестных ссылок, копирования и вставки и т. д.

Для сценариев: практически не имеет значения, какой вы используете, если ваш проект не имеет последовательного подхода, который вам нужно вписатьс, поэтому я предлагаю использовать то, что кажется более читабельным / выразительным в данных обстоятельствах.В более длинных кодовых блоках одно продолжение может быть менее заметным и, следовательно, менее интуитивно понятным, в то время как группу из них - или много разбросанных по всему циклу - сложнее пропустить.Чрезмерно вложенный код тоже может стать уродливым. Так что выберите любой, если вы не уверены, затем измените его, если альтернатива начинает выглядеть привлекательной.

Они также передают читателю немного различную информацию: continue означает "эй, исключите все эти обстоятельстваа затем посмотрите на приведенный ниже код ", тогда как блок if означает, что вы должны" протолкнуть "контекст, но при этом помнить о них все, как пытаетесь понять остальную часть внутренних элементов цикла (здесь, только чтобы найти if сразус последующим завершением цикла, так что все эти умственные усилия были потрачены впустую. В противовес этому операторы continue имеют тенденцию вызывать мысленную проверку, чтобы убедиться, что все необходимые шаги были выполнены до следующей итерации цикла - что все это так же верно, как и все последующие действия.и если кто-то скажет, что добавляет дополнительный оператор приращения или отладки внизу цикла, он должен знать, что есть операторы continue, которые он также может захотеть обработать.

Вы можете даже решить, какой из них использовать, основываясь на том, кактривиальный тест, так же, как некоторые программыmmers будет использовать операторы раннего возврата для исключительных условий ошибки, но будет использовать переменную «result» и структурированное программирование для ожидаемых потоков.Все это может запутаться - программирование должно быть по меньшей мере таким же сложным, как и проблемы - ваша задача - сделать его минимально сложным / более сложным.

Чтобы быть продуктивным, важно помнить «Дон»мелочь ", но в ИТ это может быть правильным испытанием, изучая то, что мало: -).

В стороне: вам может быть полезно почитать плюсы и минусы структурированного программирования,который включает в себя отдельные точки входа / выхода, gotos и т. д.

2 голосов
/ 29 сентября 2010

Сначала подумайте о читабельности, что сделает ваш код более понятным.Использование оператора continue ясно для пользователя: при этом условии я больше ничего не могу / не хочу делать с этим элементом, забудьте об этом и попробуйте следующий.С другой стороны, if только говорит о том, что следующий блок кода не применяется к тем, для которых условие не выполняется, но если блок достаточно большой, вы можете не знать, есть ли на самом деле какой-либо дополнительный кодэто будет применяться к этому конкретному элементу.

Я предпочитаю continue вместо if по этой конкретной причине.Это более явно заявляет намерение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...