Почему я вижу так много конструкций (;;)? [закрыто]


14

На мой взгляд, цикл for используется для итерации по известному или определяемому диапазону.

String[] names = //something;
for ( int i = 0; i < names.length; i++ ) { //do stuff }

что эквивалентно (определение i в стороне):

String[] names = //something;
int i = 0;
while (i < names.length )
{
   // do stuff
   i++;
}

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

Тем не менее, я вижу много for(;;)конструкций в сети, которые функционально эквивалентныwhile(true)

Какова причина этого? Почему бесконечный цикл for предпочтительнее бесконечного цикла while?

// Я даже видел учебник по Java, который вообще не использовал циклы while! Ведущие к таким чудовищным конструкциям как:

String input = getInput();
for( ; !inputIsValid(input) ; )
{
   //redo;
}

Основная причина - предпочтение. Читаемость должна войти в игру при выборе, однако YMMV.
Аарон Макивер

Почему кто-то предпочел бы неудобную конструкцию?
Крис Кадмор

10
Вы можете поменяться whileи forздесь, и вопрос не изменится. while(true)и for(;;)иметь в виду то же самое. У вас явно есть сильное предпочтение while, другие могут иметь такое же сильное предпочтение for. Нельзя сказать, что одно правильнее другого.
Калеб

3
@ Крис, я не нахожу ничего for(;;)запутанного. Это стандартная идиома C, которую вы документируете в разделе 3.5 K & R (2e). Я понимаю, что тебе это не нравится; Вы должны понимать, что другие, очевидно, предпочитают это (иначе вы бы никогда этого не увидели). Это может быть более или менее приемлемо на языках, отличных от C; Вы пометили этот язык-независимость, которая только снижает вероятность окончательного ответа. Опять же, я проголосовал за закрытие, потому что Q не конструктивен; если бы я обиделся, я бы пометил как оскорбительное вместо или в дополнение к закрытию. Это все.
Калеб

1
Лично я думаю, что здесь есть реальная возможность полностью использовать другой синтаксис для бесконечных циклов: что-то вродеwheeeeeeee { ... }
детально

Ответы:


33

Это пережиток старой практики программирования на PDP-11 (да, я сказал, старая ). Он использовался для сохранения одной инструкции, что было полезно для ускорения циклов.

Для получения дополнительной информации см. Следующее: http://www.flounder.com/exceptions.htm


3
Это именно то, что я искал. Существует реальная, законная причина, но она больше не действительна.
Крис Кадмор

1
@chris Nnnope, современные компиляторы иногда будут жаловаться на использование константы в условии цикла. Это не чисто пережиток.
Изката

Это больше, чем это. Я помню, как писал C в начале 1990-х годов на Unix-системах, и хотя (true) {} не было вариантом. Стандартного логического типа не было, но несколько систем Unix определили свои собственные в заголовочных файлах C. По памяти, по крайней мере, один поставщик Unix определил TRUE как ноль, чтобы помочь обработать возвраты функций, так как условием было возвращать ноль в случае успеха, а положительные числа были ошибками. Это означало, что while (TRUE) {} не было переносимым.
Майкл Шоу

1
Я не могу найти это прямо сейчас, но я могу поклясться, что несколько лет назад Деннис Ричи написал пост в Usenet, в котором говорилось, что это просто неправильно, и он / они используют for(;;)синтаксис как (по их мнению) более прямое утверждение Намерение, что не было никаких критериев для выхода из цикла.
Джерри Гроб

@Ptolemy: Ну, вы, конечно, могли бы написать while(1) { }.
Эд С.

10

некоторые компиляторы выдают предупреждение (что-то вроде условного выражения является константой ) при использовании, while( 1 )но с for( ; ; )этим нечего предупреждать. Программисты хотят код без предупреждений, поэтому они используют вариант for.


Некоторые вещи, о которых предупреждают компиляторы, вполне допустимы и даже (в некоторых особых случаях) неизбежны. Поэтому некоторые из нас рассматривают предупреждения как, ну, как предупреждения. Если вы игнорируете их, конечно, вы можете быть поглощены проклятыми вещами и не увидеть важные из них - но есть прагмы и опции для отключения предупреждений, локально или глобально. В принципе, да, лучше не иметь предупреждений, но мне обычно нужна более веская причина, чтобы принять худший стиль кода. Здесь все не хуже, просто по-другому, но «бесконечные» петли редки (или вообще очень плохи) в любом случае.
Steve314

5

Это привычка, приобретенная в C-программировании, где нет логического типа. Хотя (1) потенциально может быть эквивалентом, но For (;;) часто используется, как показано в K & R, если я правильно помню. Я подозреваю, что там тоже была какая-то аппаратная причина.


4
... подозреваю, что была аппаратная причина ...
Аарон Макивер

2
Как отметил Эдвард Робертсон, причина в том, что компилятор C на PDP-11 не осознавал, что значение true в «while (true)» было постоянной времени компиляции и добавило бы дополнительную инструкцию (сравнение) при генерации сборки. Из-за ограниченных ресурсов, доступных на PDP-11, программисты использовали цикл for, чтобы оптимизировать одну дополнительную инструкцию вне программы.
Джетти

3

for (;;) может читаться как «навсегда», что некоторые считают более естественным, чем «в то время как истина».


Хотя это не первоначальная причина, это вторичная причина, почему предпочтение застряло намного позже, чем первоначальная причина устарела. Однако очень трудно найти какие-либо доказательства, подтверждающие это, кроме как спросить у опытных программистов.
ДаренВ

-2

Все опытные программисты, которых я попросил, могут распознать for(;;)быстрее, чем while(true)или while(1).


2
Любой программист, который стоит проклятого, должен быть в состоянии распознать все три сразу. Все три достаточно распространены, и каждый, кто потратил больше 5 минут на чтение кода, видел каждый из них несколько раз.
Цао

1
Исследования показали, что опытные программисты могут понимать на for(;;)14 мс быстрее, чем while(1):-)
Кевин Клайн
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.