Какой цикл использовать для итерации, которая может быть прервана до конца? - PullRequest
0 голосов
/ 23 сентября 2010

У меня есть диапазон памяти для анализа. Если я нахожу определенную последовательность байтов до конца, я прерываю итерацию. Интересно, какой цикл я бы предпочел здесь:

while(i < end && !sequenceFound ) {
    // parse
    i++;
}

Или

for( i; i < end && !sequenceFound; i++ ) {
    // parse
}

Используется в методе класса, производного от класса, который реализует кольцевой буфер. Суперкласс обеспечивает i и end. Мой вопрос: какой из них, по вашему мнению, легче понять (лучше выражает намерение) для кого-то, кто не знаком с кодом?

Редактировать Тот факт, что я нашел последовательность, необходим для дальнейшего анализа потока. Я мог бы использовать break и установить sequenceFound = true, но это было бы излишним, или я был здесь строгим?

Ответы [ 9 ]

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

Почему бы просто не использовать break; в тот момент, когда возникает необходимость "прервать" цикл.Это похоже на языковую функцию, которая наиболее идиоматически выражает ваше намерение.Обычно это означает, что вы можете обойтись без дополнительной логической переменной отслеживания состояния.

Если вам нужно узнать, завершена ли итерация раньше, вы можете использовать условие i != end. В любом случае, использование наиболее понятного метода управления будеткажется лучшим и break; в точке, в которой вы хотите прерваться, мне кажется наиболее ясным, поддерживаете ли вы переменную «раннего выхода» или нет.Кажется излишним продолжать цикл и проверять условие, которое, как вы только что гарантировали, завершится неудачей.

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

Предпочитают алгоритмы рукописным циклам.

#include <algorithm>

auto it = std::find(begin, end, predicate);
if (it == end)
    :-(
else
    :-)
3 голосов
/ 23 сентября 2010

Для циклов с переменной цикла и концом (т. Е. Для всех циклов, которые работают в диапазоне путем проверки i != end или i < end), я предпочитаю подход for, поскольку это более или менее каноническое использование for.

Если вы можете выйти из цикла преждевременно, break:

for(; i != end; ++i) {
    // parse
    if (sequenceFound)
        break;
}
3 голосов
/ 23 сентября 2010

Для итерации с явным ограничением я бы обычно использовал цикл for. Циклы while следует использовать, когда итерация не имеет верхнего предела.

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

Я предпочитаю while здесь, поскольку это читается лучше. Возможно, это личное предпочтение. until, который доступен на некоторых языках, тоже подойдет.

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

Я предпочитаю for с break внутри.

Причина в том, что вы можете избежать уродливых конструкций, которые должны проверять ваше состояние 'break', например ::10000*

for(; i != end; ++i) {

    // do stuff

    if (sequenceFound) break;

    // you don't need an 'if(!sequenceFound)' around this block of code
    // do more stuff
}

Но с помощью версии while или for со встроенным условием, в зависимости, конечно, от того, что вы делаете, вы не сможете так легко избежать этого условия.

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

Согласитесь с Чарльзом Бэйли, поскольку, как только вы прервете итерацию, вы сразу выйдете из самой непосредственной зацикливающейся структуры, без необходимости переоценивать условную переменную. Кроме того, вам не нужна дополнительная условная переменная, что сокращает объем памяти, необходимый для работы блока кода.

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

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

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

Вторая версия лучше понятна и позволяет использовать оператор продолжения.

...