Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

while(1)

3.3K
18 сентября 2006 года
ShadyMan
191 / / 15.07.2006
Хотелось бы услышать, что думает прогрессивная программистская общественность о такой конструкции - while(1). Коряво это или нет? Согласитесь, что иногда для выхода из цикла может быть не одно, а несколько самых разнообразных условий, причём в зависимости от конкретного повода для выхода должны выполняться разные действия, так что просто записать их за пределами цикла нельзя.
Страницы:
2
18 сентября 2006 года
squirL
5.6K / / 13.08.2003
а что тут корявого? я всегда такую применяю при написании демонов. на С и на Perl. что вызвало вопрос?
547
19 сентября 2006 года
Hydra
488 / / 20.06.2006
Солидарен со squirL
break никто еще не отменял.
713
19 сентября 2006 года
Ap0k
360 / / 13.03.2006
Точно так же отношусь как и к конструкции for(;;), т.е. ничего против не имею и сам использую, только не while(1), а while(true) , т.к. компилятор C# первую конструкцию не проглотит :)
240
19 сентября 2006 года
aks
2.5K / / 14.07.2006
[QUOTE=Ap0k]только не while(1), а while(true) , т.к. компилятор C# первую конструкцию не проглотит :)[/QUOTE]
Ну так понятно все зависит от языка. Где нету true исспользуется 1.
Где есть, даже если true равен 1 как в C++, понятно его надо исспользовать для наглядности.
3.3K
19 сентября 2006 года
ShadyMan
191 / / 15.07.2006
Интересно, а главный блюститель чистоты языка выскажется?
240
19 сентября 2006 года
aks
2.5K / / 14.07.2006
Причем тут блюститель чистоты. У тебя помоему предвзятое отношение. Суть в том что надо выбирать то, что соответствует задачи и дает грамотный код при том.
В данном случае как вариант при задачи какого либо сервера или сервиса не предусматривающего завершения например.
10
19 сентября 2006 года
Freeman
3.2K / / 06.03.2004
[QUOTE=ShadyMan]Интересно, а главный блюститель чистоты языка выскажется?[/QUOTE]
Я хоть и не главный блюститель, но мне это почему-то напоминает анекдот про программиста и шампунь или примеры из учебников по Бейсику 80-х годов.

Хотя, в C#(?) есть ведь цикл do-loop без условия. Мне приходилось использовать repeat until False в Паскале совместно с Break. Но в подобных задачах, как правило, требовалось выполнить тело цикла минимум один раз. Поэтому использование конструкции с предварительным условием для бесконечного цикла наводит на сомнения в правильности ее использования.
2
19 сентября 2006 года
squirL
5.6K / / 13.08.2003
[quote=ShadyMan]Интересно, а главный блюститель чистоты языка выскажется?[/quote]
я так и знал, что пост - дешевая провокация... :(
3.3K
19 сентября 2006 года
ShadyMan
191 / / 15.07.2006
[QUOTE=Freeman]Поэтому использование конструкции с предварительным условием для бесконечного цикла наводит на сомнения в правильности ее использования.[/QUOTE]
Да нет, я же объяснил о чём идёт речь. Конкретизирую.
Код:
while(1)
{
 if (...)
 {
    some task;
    break;
  }
  if (...)
  {
    other task;
    break;
  }
  if (...)
  {
    third task;
    break;
  }
  some else;
}

Как бы Вы, Уважаемый Freeman, решили бы эту задачу?
3
19 сентября 2006 года
Green
4.8K / / 20.01.2000
IMHO все зависит от конкретной задачи и общей концепции.
В некоторых случаях удобнее и красивее писать while(true).
Есть ещё одна похожая конструкция do {....} while(false), которая заменяет конструкцию try/final.

Иногда и та и другая конструкция превращается в реализацию конечного автомата через switch.
Для прмера приведенного выше, это выглядело бы примерно так:
Код:
while( (state != end) || (state != error) )
{
    switch(state)
    {
    case some:
        some task;
        state = end;
        break;

    case other:
        other task;
        state = end;
        break;

    case third:
        third task;
        state = end;
        break;

    default:
        some else;
    }
}

Это превращение обусловлено обычно необходимостью "знать" по какому все же условию мы вышли из цикла.
Очень часто такое бывает при инициализации/деинициализации ряда подсистем в составе одной сложной системы. Например, в играх происходит инициализация менеджера памяти, подсистемы ввода/вывода, графической подсистемы, подсистемы звука и т.п. При этом деинициализация по ошибке или по завершению игры должна проходить в обратном порядке, причем при ошибке деинициализация проходит с последней удачно инициализированной системы.
5.4K
19 сентября 2006 года
Svyatozar
221 / / 11.09.2006
Попробовал в gcc for(;;) и while(1) - ассемблерный код на 100% одинаковый.
2
19 сентября 2006 года
squirL
5.6K / / 13.08.2003
ну естественно. gcc оптимизирует код, как и полагается порядочному компилятору из хорошей семьи :)
3.3K
20 сентября 2006 года
ShadyMan
191 / / 15.07.2006
Ну спасибо. В этот раз вы порадовали меня широтой взглядов.
309
21 сентября 2006 года
el scorpio
1.1K / / 19.09.2006
А я while совсем не использую - за ненадобностью :D.
 
Код:
for (bool Working = true; Working; )
{
// .................
}
3
21 сентября 2006 года
Green
4.8K / / 20.01.2000
IMHO дело вкуса... но это те же штаны только в профиль.
А почему не
 
Код:
for (;true;) {}
16K
22 сентября 2006 года
aragaer
25 / / 28.07.2006
Потому что в первом случае можно в теле цикла сказать
Working = false;
и покинуть цикл на следующей итерации.

while(1) вообще нужен тогда, когда выход из цикла является совсем уж исключительным типа "пора бы и компьютер выключить" и все выходы из цикла должны происходить сразу, как только какое-то событие наступило, не дожидаясь завершения итерации. Тогда break выглядит самым правильным решением, ну а если все выходы делаются break'ом, то зачем вводить еще какое-то условие?
241
22 сентября 2006 года
Sanila_san
1.6K / / 07.06.2005
Я не Freeman, поэтому лишь предположу, что это решается так:
Код:
repeat
  if <condition_1> then
  begin
  .
  .
  end;
  if <condition_2> then
  begin
  .
  .
  end;
  .
  .
  if <condition_n> then
  begin
  .
  .
  end;
until true;


Примерно так.
309
22 сентября 2006 года
el scorpio
1.1K / / 19.09.2006
Циклы с постусловием не самый удачный стиль программирования. Ладно, если эти операторы перепутать с чем либо ещё сложно, а вот следующий пример может ввести в заблуждение
 
Код:
do
{
// Много команд
}
while (Условие)
Команда2

Если цикл слишком большой, то его будет трудно читать. И оператор while может восприниматься программистом как условие цикла для Команда2. Просто потому, что программист достал исходники из архива полугодовой давности :(
3
22 сентября 2006 года
Green
4.8K / / 20.01.2000
[QUOTE=el scorpio]Циклы с постусловием не самый удачный стиль программирования.[/QUOTE]
Я бы не был так категоричен.
Достаточно не писать циклов на несколько экранов (что уже само по себе плохой стиль) и сделать пустую строку после while, и все становиться весьма читабельным.
350
22 сентября 2006 года
cheburator
589 / / 01.06.2006
[QUOTE=Green]
 
Код:
while( (state != end) || (state != error) )
{
...
}

[/QUOTE]
Оч интересный цикл. Выход из него происходит тогда, когда state равен одновременно end и error :)
3
22 сентября 2006 года
Green
4.8K / / 20.01.2000
Давайте, не будем придераться к мелочам. На каждого можно накопать целый гербарий таких опечаток и пр. нелепостей. :)
309
23 сентября 2006 года
el scorpio
1.1K / / 19.09.2006
Цитата:
Достаточно не писать циклов на несколько экранов (что уже само по себе плохой стиль)


Ох, мне как-то пришлось доделывать мегапроект :confused: после одного начинающего программиста :eek: ... Хорошо, что он не знал о постусловиях, а то б я вообще опух :D
[QUOTE=Green]сделать пустую строку после while, и все становиться весьма читабельным.[/QUOTE]
В этом согласен- наглядно. Если же продолжать код сразу за постусловием, его сложнее воспринимать даже при коротких циклах.

3.3K
28 сентября 2006 года
ShadyMan
191 / / 15.07.2006
[QUOTE=Sanila_san]Я не Freeman, поэтому лишь предположу, что это решается так:
Код:
repeat
  if <condition_1> then
  begin
  .
  .
  end;
  if <condition_2> then
  begin
  .
  .
  end;
  .
  .
  if <condition_n> then
  begin
  .
  .
  end;
until true;


Примерно так.[/QUOTE]
Ну вы и даёте, Sanila_san! Это же то же самое, что я и написал: формально бесконечный цикл ("until true"), а выходы, очевидно, делаются между begin и end.
1.9K
02 октября 2006 года
[*]Frosty
278 / / 17.06.2006
[QUOTE=ShadyMan]Да нет, я же объяснил о чём идёт речь. Конкретизирую.
Код:
while(1)
{
 if (...)
 {
    some task;
    break;
  }
  if (...)
  {
    other task;
    break;
  }
  if (...)
  {
    third task;
    break;
  }
  some else;
}

Как бы Вы, Уважаемый Freeman, решили бы эту задачу?[/QUOTE]
В структурном программировании у кождого блока должен быть один вход и один выход(так легче производить разбор кода, код становиться более последовательным), по-этому один из возможных выходов - можно организовать флаг:
Код:
fExit = false;
while(fExit == false)
{
 if (...)
 {
    some task;
    fExit = true;
  }
  if (...)
  {
    other task;
    fExit = true;
  }
  if(...)
  {
    third task;
    fExit = true;
  }
  some else;
}
3.3K
02 октября 2006 года
ShadyMan
191 / / 15.07.2006
Спасибо вам, Фрости, конечно, но то, что вы написали, уже было предложено Грином.
1.9K
02 октября 2006 года
[*]Frosty
278 / / 17.06.2006
Вы правы неугледел)))))))))))))))))))))
17K
10 октября 2006 года
_mrhx_
27 / / 09.10.2006
Циклы с условием в конце выполняются несколько быстрее, чем с условиям в начале. (если только компилятор не оптимизирует while(1)), так что лучше наверное do .. while(1); либо по-простому goto :)
3.3K
10 октября 2006 года
ShadyMan
191 / / 15.07.2006
Разумеется компилятор (я даже думаю, любой компилятор) оптимизирует while(1). Неужели вы, товарищ с непроизносимым ником, думали, что на уровне машинных инструкций в этом случае будет происходить сравнение единицы с нулём в каждой итерации? Реально сравнение и условный переход будут происходить только при употреблении оператора if. В конце же цикла имеет место безусловный переход.
309
11 октября 2006 года
el scorpio
1.1K / / 19.09.2006
Цитата:

что на уровне машинных инструкций в этом случае будет происходить сравнение единицы с нулём в каждой итерации? Реально сравнение и условный переход будут происходить только при употреблении оператора if.


Кстати, заметили ли вы, что компилятор (Borland C++ Builder), при компиляции может выводить warning ("условие всегда истина") - возможно, это означает, что код проверки формироваться не будет вообще.

3
11 октября 2006 года
Green
4.8K / / 20.01.2000
Кончно же не будет.
17K
11 октября 2006 года
_mrhx_
27 / / 09.10.2006
[QUOTE=ShadyMan]Разумеется компилятор (я даже думаю, любой компилятор) оптимизирует while(1). Неужели вы, товарищ с непроизносимым ником, думали, что на уровне машинных инструкций в этом случае будет происходить сравнение единицы с нулём в каждой итерации? Реально сравнение и условный переход будут происходить только при употреблении оператора if. В конце же цикла имеет место безусловный переход.[/QUOTE]
Надо просто знать как произносить ;))
А потом хз будет или нет оптимизировать - это от компилятора зависит
и, вероятно, настроек сборки. Потенциально, вдруг нам НУЖНО чтобы там была единица, чтобы потом, путем runtime-изменения кода испольняемого, преобразовать ее во чтото еще? )))) (врят ли конечно это нужно, но вдруг)
3
11 октября 2006 года
Green
4.8K / / 20.01.2000
Да, от настроек зависит.
10
11 октября 2006 года
Freeman
3.2K / / 06.03.2004
[QUOTE=_mrhx_]вдруг нам НУЖНО чтобы там была единица, чтобы потом, путем runtime-изменения кода испольняемого, преобразовать ее во чтото еще?[/QUOTE]
Это уже другим словом называется.
3.3K
11 октября 2006 года
ShadyMan
191 / / 15.07.2006
[QUOTE=Green]Да, от настроек зависит.[/QUOTE]
Ну, не знаю. У меня Builder отбрасывал это сравнение и при выключенной оптимизации. Если какой-то компилятор даст код сравнения на месте while(1), то, по-моему, это какой-то недоделанный компилятор.
309
11 октября 2006 года
el scorpio
1.1K / / 19.09.2006
[QUOTE=ShadyMan]Ну, не знаю. У меня Builder отбрасывал это сравнение и при выключенной оптимизации. Если какой-то компилятор даст код сравнения на месте while(1), то, по-моему, это какой-то недоделанный компилятор.[/QUOTE]
Builder 6. Компиляция с отладкой для строки while (true) выдаёт ассемблерный код jmp -0x49 - безусловный переход на верх.
Несмотря на то, что while находится перед циклом, компилятор размещает эту команду после.
Посему рассуждения о преимуществе "постусловия" в исходном тескте можно считать пустым флудом. Ибо, как я уже сказал, while в конце цикла затрудняет чтение и понимание исходника.
3
11 октября 2006 года
Green
4.8K / / 20.01.2000
jmp наверх всегда будет внизу... :)

ну и так просто эксперименты:
 
Код:
while(1)
00401004 B8 01 00 00 00   mov         eax,1
00401009 85 C0            test        eax,eax
0040100B 74 02            je          0040100F
    {
    }
0040100D EB F5            jmp         00401004

 
Код:
do
    {
    }
    while(1);
00401004 B8 01 00 00 00   mov         eax,1
00401009 85 C0            test        eax,eax
0040100B 75 F7            jne         00401004

Это по поводу того, какой код формируется при отсутствии оптимизации.
Но в глобальном плане это ничего не значит, т.к. подобное нельзя назвать оптимизацией, а тем более, что после оптимизатора код будет одинаковым:
 
Код:
00401000 EB FE            jmp         00401000
309
11 октября 2006 года
el scorpio
1.1K / / 19.09.2006
Green, почему компилятор занимается проверкой истинности единицы :eek:? Мой Builder ничего подобного не даже в "отладочном" режиме не выдаёт.
Из-за этого первый вариант длиннее на одну команду :D.
1.9K
11 октября 2006 года
[*]Frosty
278 / / 17.06.2006
[QUOTE=el scorpio]Кстати, заметили ли вы, что компилятор (Borland C++ Builder), при компиляции может выводить warning ("условие всегда истина") - возможно, это означает, что код проверки формироваться не будет вообще.[/QUOTE]
Просто - это признак потенциальной ошибки. Лучше использовать состояния.

З.Ы.
Цитата:
почему компилятор занимается проверкой истинности единицы ?


А может ты так задумал))))))

3.3K
11 октября 2006 года
ShadyMan
191 / / 15.07.2006
[QUOTE=Green]ну и так просто эксперименты...[/QUOTE]
Это что же, MVC такое выдаёт?!!!!
7.6K
21 октября 2006 года
Darien
125 / / 15.01.2006
Ничего плохого в псевдо-бесконечных циклах не вижу. Предпочитаю юзать for(;;) . Что касается проверки на еденицу, то в Microsoft C++ 7.1 и 8.0 в Debug режиме это действительно имеет место быть, сделано это вот для чего : как известно студия как 2003 так и 2005 позволяет править код прямо во время выполнения программы, вот это и позволяет вместо единицы туда что-нить другое написать на следующей итерации, например.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог