while(true)+break и альтернативы
Можно делать так:
{
// ...
if(condition_func()) break;
// ...
}
или так:
{
// ...
}
Можно использовать переменную вместо функции, но это менее изящно, хотя в конечном счёте всё сведётся именно к этой переменной.
Первый способ плох тем, что придётся искать условие выхода внутри тела цикла. И это может породить бесконечный цикл при внесении изменений в код цикла. Второй плох тем, что условие выхода привязано к определённой точке. То есть, он менее гибок.
Может есть ещё какие-то альтернативы? Или может есть какие-то соображения, чтобы не использовать один из подходов вообще?
Ну, у меня таких практически нет.
Тут дело не в оптимизации. дело в смысле. Хотя, если уж говорить о ней, то есть понятие "преждевременная оптимизация", но ещё есть и другое, о котором редко говорят: "преждевременная пессимизация". И вот тут и она есть, и ещё запутанность. Получается же так:
{
if (условие2) break;
if (условие3) break;
// ...
}
Но чем же условие1 лучше других условий? Почему его выделяем? Не ясно. Намного ровнее такая конструкция:
{
if (условие1) break;
if (условие2) break;
if (условие3) break;
// ...
}
Из такого цикла легко сделать цикл с предусловием, с постусловием, и даже с "посерединеусловием".
Слово forever не очень нравится. Всё-таки на самом деле тут может быть не бесконечный цикл.
Пятница, поздний вечер... Думаю лучше перенести дискуссию на завтрашний вечер, а то мой парсер утверждает, что в цитируемом сообщении говорится о ненужности while.
Возможно, такая ясность может пригодиться только для while. Про for - сильно не уверен. Например, для поиска элемента в списке может потребоваться дополнительный выход. Но тут лучше будет использовать return со значением индекса, а не пустой break.
В общем-то, я перечислил циклы, которые есть в современных языках программирования. Более того, некоторые из видов циклов, типа do-while я убрал. С другой стороны, while(true) (оно же for( ; ; )) - настолько привычная конструкция, что её можно выделить в отдельный вид циклов. Не обязательно придумывать специальное слово - главное помнить, что это уже не while и не for.
Знаешь, я не вижу здесь рационального зерна. Возможно мне не понятен ход твоих мыслей, потому как я лично не вижу проблем, которые бы это решило. Поэтому я и вспомнил о этой стране - уж больно похож шаблон поведения.
Поэтому возмож тебе имеет смысл озвучить собственно - что бы решило твое нововведение?
Улучшилась "читаемость" кода? Да вряд ли особо.
Расширит возможности для его автоматической генерации? Тоже особо нет - как раз возможно это ее усложнит.
Поэтому озвучь проблему для начала, которая может быть частично либо полностью решена благодаря твоей "рацухе".
Тут в основном абстрактные рассуждения. Но есть и конкретные практические идеи. Например, есть идея создать скрипт для управления разными технологическими процессами. Например, нагревание печи до определенной температуры, затем охлаждение и т.д.
Такой скрипт должны писать люди далёкие от программирования, но знакомые с определенной технологией. То есть скрипт должен быть простейшим - он должен содержать 5-10 ключевых слов, в нем должны отсутствовать пользовательские функции, переменные и т.п.
Так как эти процессы часто содержат циклы, то приветствуется простейший для понимания цикл. Так вот это не while, ибо он запутает новичка: работаем пока выполняется условие или пока не выполняется? loop намного проще - петля и есть петля. Кроме того, он не менее гибок.
...
Так как эти процессы часто содержат циклы, то приветствуется простейший для понимания цикл. Так вот это не while, ибо он запутает новичка: работаем пока выполняется условие или пока не выполняется? loop намного проще - петля и есть петля. Кроме того, он не менее гибок.
Если говорить о специальном операторе бесконечного цикла - да, возможно в этом есть смысл. Правда вряд ли это решит проблему выполняется/не выполняется (тем более что тут запутанного то) но создаст новую - например бесконечный цикл чтения из файла, если этот тупой удод забыл поставить проверку. И что тогда? Делать на уровне компилятора проверку и добавлять проверку чтения флагов состояния потока. Соответственно все объекты потоков обязаны реализовать единый механизм опросов флагов состояния.
А для них, особо важно чтобы в цыкле недайбох не было break or continue - ибо таких как он это ставит в тупик. Их в принципе многое ставит в тупик. Точнее они вообще редко от туда (из тупика) выходят (шутка)
Про запутанность: начинающие часто не могут сразу запомнить, что из двух циклов:
while(true){}
while(false){}
будет бесконечным циклом, а что будет циклом к нулем итераций. Это довольно утрированные примеры, путаница обычно случается с меняющимся флагом.
Если кто-то забыл поставить условие, то программа будет работать некорректно и ему придётся поправить. Обычная отладка.
Я вижу это задачу наоборот. Какой смысл в while и while-do, если с достаточной для практики надёжностью они делаются с помощью бесконечных циклов?
Кроме того, если в половине случаев while используется для создания бесконечного цикла, или, что ещё хуже, в while добавляется какое-то противоестественное условие просто для того, чтобы оно там было, то значит что-то не в порядке.
Пояснение: некоторых программистов почему-то раздражает while(true), вот они и ставят какой-нибудь флаг вместо true для порядка. И это во многих случаях - зло.
А для них, особо важно чтобы в цыкле недайбох не было break or continue - ибо таких как он это ставит в тупик. Их в принципе многое ставит в тупик. Точнее они вообще редко от туда (из тупика) выходят (шутка)
Просто хочется читать код как Ленин читал книжки — взглянул по диагонали и можно перелистывать (жать PGDN/PGUP). ^)
А если кто-то не может разобраться с while(true), while(false), break и continue, то, может, он и не нужен в племени программистском? ;) Кстати, эта гиперзабота о несмышленых новичках - это теория, или тебя реально окружает подавляющее количество подобных?
Сам я, кстати, постоянно использую break и continue и не вижу в этом ничего плохого.
Проблема в том, что этих чётких критериев нет. Но примеры приводились и в этой теме. Приведу ещё:
while (command != 'q')
{
command = get_command();
// обработка команды. Тут может быть даже
// ... if (command == 'q') break;
}
Меня не окружают начинающие программисты. Но у меня есть мнение, что простейшие скрипты могут пригодиться не только программистам. Например, технарями, которые не являются программистами, экономистам, аниматорам и т.д.
Вот такие люди меня окружают. Но чтобы они восприняли скрипты, в тех, по возможности, не должно быть путаницы.
Ну и я не вижу. Но просто хочу упорядочить их использование.
В теме проскакивали предложения:
- ввести forever()
- отменить while() и do{}while()
- отменить for( ; ; )
- отменить break, continue
- предложения по стилистике кода
аргументы почти везде - "новичкам (якобы) нипанятна" или "хочу код читать PageDown'ом и взглядом по диагонали" ;)
Нормально оформленный код (с комментами в неочевидных местах) и так неплохо читается. Так что большую часть проблемы (проблемы ли?) решит прививание культуры кодирования и комментирования.
[QUOTE=Kogrom]Но примеры приводились и в этой теме. Приведу ещё[/QUOTE]Ну так с почти любой конструкцией языка можно сотворить что-нибудь эдакое. Можно, например, switch написать без break'ов:
{
case 1: action1();
case 2: action2();
case 3: action3();
}
Если любую конструкцию языка можно будет использовать только одним строго определенным способом, язык неизбежно потеряет в гибкости
Меня не окружают начинающие программисты. Но у меня есть мнение, что простейшие скрипты могут пригодиться не только программистам. Например, технарями, которые не являются программистами, экономистам, аниматорам и т.д.
Вот такие люди меня окружают. Но чтобы они восприняли скрипты, в тех, по возможности, не должно быть путаницы.
слух а эхкономисты-аниматоры - они взамен обязуются не просить сделать кнопку "Хочу чтобы было песдато"? Или может лучше тогда с экономики начать - вот индекс джоу-джонса - вот многим моим друззям это вообще непонятная ебаная хуйня - давайте упрощать. Чего это так? Экономистам понятно а Ваське нет? Не, не порядок.
#define forever while(true)
может, стоит тогда определить какой-нибудь внутрикорпоративный стандарт оформления подобных циклов, если это для вас важно?
#define forever while(true)
Потому что оно уже evil. Evil x evil = evil to the power of 2.
может, стоит тогда определить какой-нибудь внутрикорпоративный стандарт оформления подобных циклов, если это для вас важно?
Вообще-то, о чем-то таком речь и идет. Мы же не поправку к стандарту какого-нибудь С++ обсуждаем. ^_^
Да и гибкость сомнительная. Вот в perl я хочу
а хочу
а хочу
Это гибкость — как приспичило, так и записал, а смысл не поменялся и читаемость и не пострадала. И информацию никакую дополнительную, вроде как, вложить сюда без лютого натуга нельзя было, да и не надо было. А заголовок цикла — штука посложнее и на нее можно еще семантики довесить.
В теме проскакивали предложения:
- ввести forever()
- отменить while() и do{}while()
- отменить for( ; ; )
- отменить break, continue
Ты немного горячишься. Поправлю.
- ввести loop() или (circle или ещё что-то, но не forever), но только в скриптах, новых языках. В старых помнить что замена этому - while(true);
- не отменять while() и do{}while(), но использовать там, где одно условие выхода. В крайнем случае допустимо использование return.
- отменить for( ; ; ). Это правильно. Зачем такая извращенная конструкция для бесконечного цикла?
- break использовать только в бесконечных циклах. На счет continue - была поправка :)
Аргумент простой - избавление от путаницы.
switch не нужен же. Но это отдельная тема :)
Это зависит от него. Не знаю, что такое мотолок, но если он сделан так, чтобы ударять по пальцам, то он не нужен.
Ну я же показывал, что гибкость не теряется. Бесконечный цикл не менее гибок, чем обычный while.
Сдается мне, скоро от языка останется только озвученная kot_'ом одна-единственная инструкция "хочу, чтоб было пе...то" ;)
2 Kogrom
Ааа, так ты собрался новый язык разработать! :)
[QUOTE=Kogrom]while() и do{}while(), но использовать там, где одно условие выхода[/QUOTE]А мне кажется, что это вполне "естественно" использовать в основном условии while, например, что-нибудь вроде "читать, пока файл не кончится" или "принимать сообщение, пока не кончится", а в самом цикле устроить несколько break'ов при обработке ошибочных ситуаций (но вообще это зависит от синтаксиса конкретных функций чтения)
Тут другая торговля, другой обмен. Если продукт будет обладать дополнительной гибкостью, которой сможет воспользоваться дилетант в программировании, то продукт будет более востребован. Элементарно же.
Конечно, есть другой подход - встроить какую-нибудь Lua. Это даст ещё больше гибкости. Но всё зависит от конкретного потребителя.
Подтверждаю.
while(true){}
while(false){}
будет бесконечным циклом, а что будет циклом к нулем итераций.
ты понимаешь что тот кто это написал, у него явно проблемы с развитием еще с детского сада? И после этого ты уверяешь, что ЭТОТ ЖЕ человек решит проблемы с флагами потоков простой отладкой?
Ты серьёзно спрашиваешь, чем плохи макросы в C++ ?
Ааа, так ты собрался новый язык разработать! :)
Более практично изобретать скрипты для конкретной задачи. Интерпретатор такого скрипта может сделать любой.
Но и язык нужно будет сделать как-нибудь, ибо что за программист такой, что не пытался изобрести свой язык программирования? :)
Может быть. Но не в ближайшем будущем.
Это не естественно, это - привычно. Собаке тоже естественно чесать ухо задней лапой. В этом она профессионал. Шучу.
отнюдь. Упрощение != популярность, упрощение != удобство пользования.
тем более такого рода. Тут как раз проблема не в однозначности использования. ИМХО в цикле не должно быть свойства - "+- бесконечность" - цикл должен крутится до тех пор пока выполняется условие. Все остальное - куйня, не мало-мало облегчающая жизнь. потому что ты тогда должен объяснить анаиматорам - вот фор - но только используйте его так, как вам сказано, а вот луп - он для бесконечностей. а если аниматоры его для конечностей заюзают?
То есть любой русский человек с детского сада знает чем отличается while от until?
Про потоки - это ты наплел где-то, или от Romik-а пошло. Потоки - это, в общем-то, не то, чем должен заниматься дилетант и в простых скриптах такого понятия быть не должно. Но да, отладкой всё решится.
Ок. Вечер, поздно. Хватит с меня пока :)
оф-топ: Щас погуглил, нуби-паскальщики (ну, видимо, общающиеся со старым паскалем) не могут из цикла выйти по требованию (goto же не велено ^_^). =) Обратная проблема!
[QUOTE=Kogrom]Не знаю, что такое мотолок, но если он сделан так, чтобы ударять по пальцам, то он не нужен...
Собаке тоже естественно чесать ухо задней лапой. В этом она профессионал. Шучу.[/QUOTE]Не знаю, что такое собака, но если она сделана так, чтобы чесать ухо не задней лапой, то она не нужна ;)
Ты определись - мы все же про С++ или о гипотетическом языке говорим.
Это не естественно, это - привычно. Собаке тоже естественно чесать ухо задней лапой. В этом она профессионал. Шучу.
смысл шутки потерян. Потому как именно задней ногой собаке максимально удобно чесать ухо. Ты видимо мало наблюдателен.
нет. любой нормальный человек различает где правда а где ложь. Потому проблем тут нет. Даже в детском саду. А вот у русских - с этим проблемы.
Про потоки - это ты наплел где-то, или от Romik-а пошло. Потоки - это, в общем-то, не то, чем должен заниматься дилетант и в простых скриптах такого понятия быть не должно. Но да, отладкой всё решится.
Ок. Вечер, поздно. Хватит с меня пока :)
хм. любопытно. про потоки - это не от Romik. Это мой вопрос. Как в твоем случае будет обрабатываться работа с конечными объектами (файл, БД, память) в бесконечном цикле.
Если почитать Страуструпа, Александреску, Саттера, то они утверждают, что макросы в C++ - это зло. Есть конечно и исключения, типа стражей включения, но и о них Страуструп говорит с некоторой неприязнью
Нездешний говорил о макросах в C++, я ему ответил. Основная тема - о циклах.
Что тут непонятного? Собаке то может и удобно, но бездумно брать пример с собаки не имеет смысла.
Ок. В Си есть цикл while-do, а в Паскале repeat-until. В чём разница? И зачем это помнить?
Всё очень просто. while отличается от бесконечного цикла только более экономной записью в некоторых случаях. Всё. Другой разницы нет. Об этом в данной теме я уже 2 раза сказал. Далее зацикливаться нет смысла.
kot_, ты уже давно говоришь не по теме, а просто толсто и неуклюже троллишь. Ну что это за провокации про русских, например? Что за разговоры про детский сад, про недоразвитых? Постыдился бы.
Чем плохо, например, такое использование define:
#define LogFileName "c:\\program files\\my program\\report.log"
#define MagicValue 347
#define LogFileName "c:\\program files\\my program\\report.log"
#define MagicValue 347
В первом случае удобнее typedef, так как он учитывает области видимости и тип будет определён там где надо. С #define придётся хитрить с помощью #undef. Это лишнее действие, о котором легко забыть.
Остальные 2 случая - глобальные константы, не уважающие пространств имён. Глобальные константы, как и переменные лучше не использовать в больших программах, так как они превращают код в монолит.
Есть другие случаи, когда приходится использовать встроенные макросы, типа __FUNCTION__. Этот __FUNCTION__ не имеет смысла обёртывать функцией по понятным причинам. И тут, люди идут на использование макросов, чтобы не дублировать код.
Щас Kogrom причешет. =)
--
о чем и речь.:)
--
тема плавно переходит в этот самый монолитный оффтоп. Kogrom, толкай тележку. =)
Ну, по циклам я вроде бы для себя определился. А по макросам... Я над этим примером задумался:
Тут получится, что каждый объектный файл для себя создаст такую константную строку. То есть может несколько раз продублироваться в программе. В случае с нормально упакованной константой - она создастся один раз.
Хм... что-то и адрес какой-то слишком конкретный. Но это мелочи, конечно. Тут не в макросе дело.
MESSAGE_HANDLER(WM_SOME_MESSAGE, TMessage, OnSomeMessage);
END_MESSAGE_MAP(TForm)