Следует использовать


если бы вам пришлось повторить цикл 7 раз, вы бы использовали:

for (int i = 0; i < 7; i++)

или:

for (int i = 0; i <= 6; i++)

есть два соображения:

  • производительность
  • читабельности

для производительности я предполагаю Java или C#. Имеет ли значение "меньше" или "меньше или равно" используется? Если у вас есть понимание для другого языка, пожалуйста, укажите, какой.

для удобства чтения я предполагаю, что 0-на основе матрицы.

UPD: мое упоминание о массивах на основе 0 может привести к путанице. Я не говорю о переборе элементов массива. Просто общий цикл.

ниже есть хороший момент об использовании константы, которая объяснила бы, что такое это магическое число. Так что если бы я...int NUMBER_OF_THINGS = 7" то "i <= NUMBER_OF_THINGS - 1" выглядело бы странно, не было.

30 124

30 ответов:

первый более идиоматическое. В частности, он указывает (в смысле 0) количество итераций. При использовании чего-то 1-based (например, JDBC, IIRC) у меня может возникнуть соблазн использовать

for (int i=0; i < count; i++) // For 0-based APIs

for (int i=1; i <= count; i++) // For 1-based APIs

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

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

Я помню из моих дней, когда мы делали 8086 Ассамблеи в колледже это было более эффективным, чтобы сделать:

for (int i = 6; i > -1; i--)

как было!--10-->JNS операция, которая означает прыжок, если нет знака. Использование этого означало, что после каждого цикла не было поиска памяти, чтобы получить значение сравнения и не сравнивать. В наши дни большинство компиляторов оптимизируют использование регистра, поэтому память больше не важна, но вы все равно получаете необязательное сравнение.

кстати ставлю 7 или 6 в вашем цикле вводится"магическое число". Для лучшей читаемости вы должны использовать константу с намерением раскрывая имя. Вот так:

const int NUMBER_OF_CARS = 7;
for (int i = 0; i < NUMBER_OF_CARS; i++)

EDIT: люди не получают сборку, поэтому, очевидно, требуется более полный пример:

если мы делаем для (i = 0; i

    mov esi, 0
loopStartLabel:
                ; Do some stuff
    inc esi
                ; Note cmp command on next line
    cmp esi, 10
    jle exitLoopLabel
    jmp loopStartLabel
exitLoopLabel:

если мы делаем для (int i = 10; i > -1; i--), то вы можете уйти с этим:

    mov esi, 10
loopStartLabel:
                ; Do some stuff
    dec esi
                ; Note no cmp command on next line
    jns exitLoopLabel
    jmp loopStartLabel
exitLoopLabel:

Я только что проверил и Компилятор Microsoft C++ не выполняет эту оптимизацию, но делает это, если вы делаете:

for (int i = 10; i >= 0; i--) 

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

for (int i = 10; i >= 0; i--)

а не любой из этих:

for (int i = 10; i > -1; i--)
for (int i = 0; i <= 10; i++)

но, честно говоря, получение читаемости "for (int i = 0; i

† другие компиляторы может делать разные вещи.

Я всегда использую

также имея

С точки зрения оптимизации это не имеет значения.

видно с точки зрения стиля кода я предпочитаю

for ( int i = 0; i < array.size(); i++ )

гораздо более читабельно, чем

for ( int i = 0; i <= array.size() -1; i++ )

также

еще один голос за

@Chris, ваше заявление О.Длина, являющаяся дорогостоящей в .NET, на самом деле не соответствует действительности, а в случае простых типов-наоборот.

int len = somearray.Length;
for(i = 0; i < len; i++)
{
  somearray[i].something();
}

на самом деле медленнее, чем

for(i = 0; i < somearray.Length; i++)
{
  somearray[i].something();
}

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

Я предпочитаю:

for (int i = 0; i < 7; i++)

Я думаю, что это более легко переводится на "повторение цикла 7 раз".

Я не уверен в последствиях для производительности - я подозреваю, что любые различия будут скомпилированы.

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

в Java 1.5, вы можете просто сделать

for (int i: myArray) {
    ...
}

Так что для массива случае вам не нужно беспокоиться.

Я не думаю, что есть разница в производительности. Вторая форма определенно более читабельна, хотя вам не нужно мысленно вычитать один, чтобы найти номер последней итерации.

EDIT: Я вижу, что другие не согласны. Лично мне нравится видеть фактические номера индексов в структуре цикла. Может быть, это потому, что он больше напоминает Perl 0..6 синтаксис, который я знаю, эквивалентен (0,1,2,3,4,5,6). Если я вижу 7, я должен проверить оператора рядом с ним, чтобы смотрите, что на самом деле индекс 7 никогда не достигается.

Я бы сказал, что использовать версию "

Я бы не беспокоился о том, что "

Если вы хотите пойти на увеличение скорости, рассмотрите следующее:

for (int i = 0; i < this->GetCount(); i++)
{
  // Do something
}

для повышения производительности вы можете немного изменить его:

const int count = this->GetCount();
for (int i = 0; i < count; ++i)
{
  // Do something
}

обратите внимание на удаление GetCount() из цикла (потому что это будет запрашиваться в каждом цикле) и изменение "i++" на "++i".

В C++, я предпочитаю использовать !=, который можно использовать со всеми контейнерами STL. Не все итераторы контейнеров STL менее сопоставимы.

Edsger Dijkstra написал статью об этом еще в 1982 году, где он утверждает, что Нижний

существует наименьшее натуральное число. Исключение нижней границы - как в b) и d) - силы для подпоследовательности, начинающейся с наименьшего натурального числа нижняя граница, как упоминалось в области неестественных чисел. Это уродливо, поэтому для нижней границы мы предпочитаем≤, как в a) и c). Рассмотрим теперь подпоследовательности, начинающиеся с наименьшего натурального число: включение верхней границы заставило бы последнюю быть неестественной к тому времени, когда последовательность сократилась до пустой. Это некрасиво, поэтому для верхней границы мы предпочитаем

во-первых, не используйте 6 или 7.

лучше использовать:

int numberOfDays = 7;
for (int day = 0; day < numberOfDays ; day++){

}

в этом случае это лучше, чем с помощью

for (int day = 0; day <= numberOfDays  - 1; day++){

}

еще лучше (Java / C#):

for(int day = 0; day < dayArray.Length; i++){

}

и даже лучше (C#)

foreach (int day in days){// day : days in Java

}

обратный цикл действительно быстрее, но поскольку его труднее читать (если не Вы другими программистами), лучше избегать. Особенно в разделе C#, Java...

Я согласен с толпой, говоря, что 7 имеет смысл в этом случае, но я бы добавил, что в случае, когда 6 важно, скажем, вы хотите, чтобы ясно, что вы действуете только на объекты до 6-го индекса, то

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

однако, если вы говорите на C# или Java, я действительно не думаю, что один из них будет ускорением скорости над другим, несколько наносекунд, которые вы получаете, скорее всего, не стоит путаницы, которую вы вводите.

лично я бы написал код, который имеет смысл с точки зрения реализации бизнеса, и убедитесь, что это легко читать.

Это относится непосредственно к категории "Делая Неправильный Код Выглядеть Неправильно".

в языках индексирования на основе нуля, таких как Java или C#, люди привыкли к вариациям на index < count состояние. Таким образом, использование этого соглашения defacto сделало бы ошибки off-by-one более очевидными.

что касается производительности: любой хороший компилятор стоит его объем памяти должен отображать такие как не проблема.

как небольшое отступление, при циклическом переборе массива или другой коллекции в .Net, я нахожу

foreach (string item in myarray)
{
    System.Console.WriteLine(item);
}

чтобы быть более читаемым, чем числовой цикл for. Это, конечно, предполагает, что фактический счетчик Int сам по себе не используется в коде цикла. Я не знаю, есть ли изменение производительности.

есть много веских причин для написания i

Я всегда предпочитал:

for ( int count = 7 ; count > 0 ; -- count )

привычка использовать

Это почти наверняка имеет большее значение, чем разница в производительности между

еще одно замечание, что было бы лучше быть в привычке делать ++i, а не I++, поскольку fetch и increment требуют временного и increment и fetch не делают. Для целых чисел ваш компилятор, вероятно, оптимизирует временное удаление, но если ваш итерационный тип более сложный, он может быть не в состоянии.

Не используйте магические числа.

почему 7? (или 6, если уж на то пошло).

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

в этом случае я думаю, что лучше использовать

for ( int i = 0; i < array.size(); i++ )

операторы '

оператор '

использование ++i вместо i++ повышает производительность в C++, но не в C# - я не знаю о Java.

как люди заметили, нет никакой разницы ни в одном из двух вариантов, которые вы упомянули. Просто чтобы подтвердить это, я сделал несколько простых бенчмаркингов в JavaScript.

вы можете увидеть результаты здесь. Что не ясно из этого, так это то, что если я поменяю позицию 1-го и 2-го тестов, результаты для этих двух тестов меняются местами, это явно проблема с памятью. Однако 3-й тест, в котором я меняю порядок итерации, явно быстрее.

как все говорят, принято использовать 0-индексированные итераторы даже для вещей вне массивов. Если все начинается с 0 и заканчивается на n-1, а нижние границы всегда <= и верхние границы всегда <, там гораздо меньше думать, что вы должны сделать при просмотре кода.

большой вопрос. Мой ответ: используйте тип A ('

  • вы ясно видите, сколько итераций у вас есть (7).
  • разница между двумя конечными точками-это ширина диапазона
  • меньше символов делает его более читаемым
  • у вас чаще всего есть общее количество элементов i < strlen(s), а не индекс последнего элемента так что единообразие важно.

другая проблема связана со всей этой конструкцией. i появляется 3 раза в нем, так что это может быть опечатка. Конструкция for-loop говорит как сделать вместо что делать. Я предлагаю принять это:

BOOST_FOREACH(i, IntegerInterval(0,7))

Это более ясно, компилирует в exaclty те же инструкции asm и т. д. Спросите у меня код IntegerInterval, если хотите.

так много ответов ... но я думаю, что мне есть что добавить.

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

for (int i = 0; i <= array.Length - 1; ++i)

и если вы просто зацикливаетесь, а не повторяете массив, подсчет от 1 до 7 довольно интуитивно понятен:

for (int i = 1; i <= 7; ++i)

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

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

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

Я предпочитаю

строго с логической точки зрения, вы должны думать, что < count было бы эффективнее, чем <= count по той же причине, что <= будет тестирование на равенство, а также.