Зачем использовать цикл for вместо цикла while?

Возможные дубликаты:
Итерации с циклом for или while?
Циклы в C - for() или while() - что BEST?

Когда следует использовать цикл for вместо цикла while?

Я думаю, что следующие циклы идентичны, за исключением их синтаксиса. Если да, то зачем выбирать один за другим?

int i;
for (i = 0; i < arr.length; i++) {
  // do work
}

int i = 0;
while (i < arr.length) {
  // do work
  i++;
}

Ответ 1

В вашем случае вы не получаете больше, кроме одной меньшей строки кода в цикле for.

Однако, если вы объявите такой цикл:

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

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

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

Последняя мысль:
Еще одно важное замечание. Между ними существует семантическая разница. Хотя циклы, как правило, предназначены для неограниченного количества итераций. (т.е. пока файл не будет прочитан. Неважно, сколько строк в нем), а для циклов должно быть более определенное количество итераций. (цикл через все элементы в коллекции, которые мы можем рассчитывать на основе размера коллекции.)

Ответ 2

Есть одна причина выбрать for над while: читаемость.

Используя цикл for, вы прямо заявляете, что намерены выполнить какой-то тип работы, требующий инициализации, операции "шаг" и условия завершения.

С while, с другой стороны, вы только говорите, что вам нужно условие завершения.

Ответ 3

Я использую "while", когда мне не обязательно нужен счетчик, например, когда вы читаете файл, и вы ожидаете достижения EOF. В этом случае "для" не может быть лучшей альтернативой. Когда вы просматриваете элементы массива, я предпочитаю использовать "для", потому что он лучше передает намерения.

Ответ 4

Единственная заметная разница между циклами for() и while() заключается в том, что оператор "continue" в цикле while() будет входить в начало цикла, а один в цикле for() будет входить в третья часть предложения for() [после условия, обычно используемого для перестановки переменных].

Ответ 5

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

  • for -loops для подсчета. подсчет, подсчет. Конструкции
  • while/do-while предназначены для всех других условий. c!=EOF, diff<0.02 и т.д. Итераторы/Перечислители являются счетчиками, очень подходящими для циклов for-loops.

то есть. ваш int=0; while( ... ) отвратителен для моих глаз.

Ответ 6

Зачем выбирать Coke over Pepsi?

Между циклами WHILE и FOR вы можете использовать их взаимозаменяемо. Чтобы быть пуристом, вы могли бы принять решение о характере условий. Если вы выполняете цикл, основанный на счете, то цикл FOR будет иметь наибольший смысл.

for( cur = 0; cur < myList.Length; cur++ ){
    doSomething( myList[cur] );
}

Если вы выполняете логический цикл, тогда WHILE сделает для самой чистой реализации

Iterator i = myObject.getIterator();
while( i.hasNext() ){
    doSomething( i.next() );
}

Ответ 7

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

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

Ответ 8

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

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

Поэтому я использую только WHILE в тех случаях, когда мне действительно нужна только средняя часть FOR.

Ответ 9

Они функционально идентичны, однако можно утверждать, что цикл for меньше подвержен ошибкам, поскольку все функции цикла находятся там же. если у вас есть несколько строк, разделяющих объявление i, декларацию while и итератор индекса, вы можете забыть или смутить, как он используется. Конечно, это субъективно.

Ответ 10

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

for (;x<5;x++){ 
    //do work 
} 

не настолько зловещий, но пишущий

while(x<5){
    x++
    //do work
}

вместо

while(x<5){
    //do work
    x++
}

может запутать некоторых людей и вызвать ошибки "один за другим".

Ответ 11

В ранние времена программирования преобладающей структурой данных была линейная матрица (aka vector), а повторяющийся шаблон должен был перемещаться и использовать каждый элемент массива. Настолько обычным был этот сценарий, что языки включали специфический синтаксис для этого шаблона: цикл for. Помимо этого исторического наследия вы можете использовать цикл while в порядке (хорошо в наши дни с функциональными языками, такими как F #, вы предпочитаете использовать List.map или List.fold; -)

Ответ 12

В основном это проблема читаемости. Как правило, используйте для циклов, когда у вас есть определенный диапазон значений для перебора. Используйте while while, если вы не выполняете итерации, или не знаете, когда ваше условие выхода будет истинным.

С точки зрения java, я нахожу для циклов очень удобными для коллекций:

for (Object o : objects){
    o.process();
}

намного легче читать, чем:

int i=0;
while(i < objects.size()){
    objects.get(i).process();
    i++;
}

Ответ 13

На языке, таком как Pascal, для и в то время как конструкции имели разные приложения. Вы должны написать цикл for в Pascal следующим образом:

for i := 1 to 5 do
begin
{ some code here }
end

Итак, вы явно указываете, что я увеличивается на 1. Здесь не указано явно условие завершения. Таким образом, вы можете использовать цикл for только в тех местах, где вы знаете, что цикл будет выполняться для определенного заранее определенного количества раз до начала фактического цикла. С другой стороны, вы можете указать явное условие завершения в случае цикла while.

i:=0;
while (i<>5) do
begin
{ some code here }
i:=i+1;
end

Таким образом, цикл while намного более гибкий. Позже, когда C был разработан, хотя для поддержки и в то время были поддержаны, значение конструкции for было изменено, и вы могли добавить в явные условия завершения, используя логические операторы. Таким образом, мощность while и для C и C-подобных языков одинакова и, следовательно, она становится большей проблемой читаемости, чем проблема удобства использования.

Ответ 14

Оглядываясь на другие (очень хорошие) ответы, я не вижу, как получается. (Если это произошло, я пропустил это и извинился.)

Я дам вам два фрагмента, казалось бы, семантически идентичного кода.

Фрагмент # 1:

for (int a = 0; a < arr.length; a++) {
  /* do some work here */
}

Фрагмент # 2:

int b = 0;
while (b < arr.length) {
  // do work
  b++;
}

Они выглядят так, как будто они делают то же самое, не так ли? Теперь позвольте мне добавить одну строчку к каждому фрагменту и посмотреть, что произойдет:

Фрагмент № 3:

for (int c = 0; c < arr.length; c++) {
  /* do some work here */
}
printf("%d\n", c);

Фрагмент № 4:

int d = 0;
while (d < arr.length) {
  // do work
  d++;
}
printf("%d\n", d);

Итак, когда я компилирую мусорный файл с этими четырьмя встроенными фрагментами (плюс некоторый клей, чтобы иметь значение arr.length что-то), я получаю следующую ошибку:

$ clang junk.c
junk.c:20:17: error: use of undeclared identifier 'c'
        printf("%d\n", c);
                       ^
1 diagnostic generated.

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

Ответ 16

читаемость. И из старого VB 6 дней wend, когда я вижу какое-то время, я хочу плакать.

Есть некоторые случаи, когда циклы хороши в использовании. Вызов функции для объекта, который возвращает true/false, но выполняет итерацию значения внутри этого объекта.

Пример: DataReader в С#:

List<string> strings = new List<string>();
while(DataReader.Read())
{
  strings.Add(DataReader["foo"].ToString());
}

Цикл for позволяет вам инкапсулировать вашу работу внутри функции, что обеспечивает лучшее управление памятью. Кроме того, если в вашем цикле while есть ошибка, он может закрутиться в замкнутый контур, который угрожает всей жизни:

bool keepGoing = true;
while(keepgoing)
{
   try
   {
     //something here that causes exception, fails to set keepGoing = false;
     keepGoing = false;
   }
   catch(Exception)
   {
    //Do something, but forget to set keepGoing.
    //maybe there is always an exception...
   }

}

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

Никто не говорит, что это неправильно, мы просто говорим: "Пожалуйста, сложите под давлением своих сверстников, чтобы поддерживать мир кодирования".

Ответ 17

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

Также я не с Джастином, сохраняющим i в области цикла, и я использую var aL = array.length вне цикла. Затем используйте i и aL в конструкторе цикла for, чтобы вы не пересчитывали длину массива при каждом ударе (вместе с созданием var снова и снова;)). Опять отрицательно. (см. первый бит моего ответа), если у вас нет очень больших массивов. Если вам известно, что длина массива upfront инициирует его с фиксированной длиной вначале (небольшая помощь с распределением памяти на crappy browsers;), если это клиентская сторона, и у вас много данных).

Пример js

<script>
var i=0;
var myArray = ["D","R","Y"];//literal style will do for now;)
var aL=myArray.length; //or use 3 if known upfront
for(i;i<aL;i++){/*always do DRY things here*/}
</script>

также обеспечить, когда условие выполнено, спросите себя: "Мне все еще нужно заполнить весь цикл?" Если вы не забудете выйти из цикла, как только сможете.

Ответ 18

Существует семантическая разница между циклами for и while. При циклах for число итераций предварительно определено, тогда как с циклами while это необязательно.

Некоторые языки (такие как Ada) применяют это, делая счетчик циклов for константой в теле цикла. Следовательно, было бы незаконно говорить, например:

for i in values'range loop
   ...
   i := i + 1;   -- this is illegal, as i is a constant within the loop body
end if;

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

Ответ 19

Связанные мелочи:

В Google new Перейти на язык, они решили не включать оператор while. Вместо этого они позволяют вам написать для оператора, в котором есть только условие. Таким образом, эквивалент

while (a < b) { ... }

просто

for a < b { ... }

Ответ 20

Проще говоря:

A 'для' цикла, как правило, используется для итерационного использования. Вам нужно итерации через массив, вам нужны номера от 1 до 100 (или других диапазонов) по разным причинам.

A 'while' цикл имеет тенденцию быть условным циклом. Вы хотите продолжать делать что-то, пока не будет ложным. Предполагая, что у вас есть класс под названием "Toast", и вы хотели приготовить тост до его поджаривания, у вас будет что-то вроде следующего:

while (!toast.isToasted) cook(toast);

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

Ответ 21

Чтение - очень важный момент, но он работает в обоих направлениях. Я преобразую цикл for в цикл while, даже когда я использую переменную счетчика, иначе в противном случае она была бы "естественной" для использования, когда она более читабельная. Это обычное явление, когда у вас есть длинное или сложное выражение в любой из трех частей или нескольких счетчиков (что связано с сложностью).

Knuth loop-and-half также лучше работает на нескольких языках как бесконечный цикл с перерывом, а не for -loop.

Однако существует очень важная семантическая разница:

for (int i = 0; i < arr.length; i++) {
  if (filter(arr[i])) continue;
  use(arr[i]);
}

int i = 0;
while (i < arr.length) {
  if (filter(arr[i])) continue;
  use(arr[i]);
  i++;
}

Ответ 22

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

Ответ 23

Предпочтение. Для меня вся логика циклов встроена в оператор for, поэтому вам не нужно объявлять переменную счетчика или делать элементы increment/decment в фактическом цикле. Кроме того, вы можете объявить счетчик/индекс локальным для оператора for.

Ответ 24

Для циклов часто проще распараллеливать. Поскольку программа может заранее указать количество итераций, которые будут выполняться, и значение итератора в любой точке, распараллеливание с использованием API, такого как OpenMP, тривиально. Конечно, если вы попадаете в перерывы, продолжаете и вручную меняете итератор, это преимущество исчезает.

Ответ 25

потому что последним может быть один лайнер: while (++ я &lt.l arr.length) {//do work}

Ответ 26

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

Кроме того, если мы добавим 'Do' в микс, мы можем использовать цикл do while, когда мы хотим, чтобы операция выполнялась хотя бы один раз, независимо от текущего состояния.

Ответ 27

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

Ответ 28

Цикл while, определенный как

while(condition)

представляет этот шаблон программирования:

1:
if(!condition) goto 2;
...
goto 1;
2:

В то время как цикл for, определенный как

for(var i = seed; condition; operation)

представляет этот шаблон:

var i = seed
1:
if(!condition) goto 2;
...
operation;
goto 1;
2:

Оба шаблона так часто используются, что они были названы и встроены в языки.

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