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

Ваш аккаунт

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

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

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

while(true)+break и альтернативы

87
21 июля 2010 года
Kogrom
2.7K / / 02.02.2008
Небольшой, но чисто программистский холливар. Например, есть цикл с заранее неизвестным количеством итераций, выход из которого должен быть по условию.

Можно делать так:

 
Код:
while(true)
{
    // ...
    if(condition_func()) break;
    // ...
}

или так:
 
Код:
while(!condition_func())
{
    // ...
}

Можно использовать переменную вместо функции, но это менее изящно, хотя в конечном счёте всё сведётся именно к этой переменной.

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

Может есть ещё какие-то альтернативы? Или может есть какие-то соображения, чтобы не использовать один из подходов вообще?
Страницы:
87
21 июля 2010 года
Kogrom
2.7K / / 02.02.2008
Добавлю ещё две альтернативы:

 
Код:
while(true)
{
    // ...
    if(condition_func()) return;
    // ...
}


 
Код:
for( ; ; )
{
    // ...
    if(condition_func()) break;
    // ...
}

Эти тоже имеют свои плюсы и минусы.
11
21 июля 2010 года
oxotnik333
2.9K / / 03.08.2007
бесят пустые for-ы, когда смотришь чужие исходники, а так же дикая инициализация переменных в них.
а по теме - все зависит от ситуации, например чтение из сокета 1-й вариант 1-го поста. И сдается что все эти выкрутасы компилятор преобразует к единому коду на низком уровне.
253
21 июля 2010 года
Proger_XP
1.5K / / 07.08.2004
Лично моё мнение - если процедуры держать в рамках 15-20 строк кода, то можно использовать любой подход (в разумных пределах, конечно) - ибо сразу будет видно, что к чему. Циклы и блоки if/try..catch тоже по возможности стремлюсь выносить в отдельные функции.

По сабжу - последняя форма с for(;; ) по-моему очевидно проигрывает while (true) в наглядности, таких использовать не стоит.
По поводу while/do..while - по возможности я стараюсь не использовать break, поэтому пытаюсь использовать условия циклов, но когда приходится писать что-то вроде такого:
 
Код:
do {
  cond = getCond();
  if (cond) {
    ...
  }
while (!cond);

...то я вместо повторов условий ставлю просто break/return, как в первом/третьем примерах.

Благодаря тому, что функции мелкие, идея видна сразу и сложнее что-то напутать с условиями выхода.
87
21 июля 2010 года
Kogrom
2.7K / / 02.02.2008
Цитата: oxotnik333
бесят пустые for-ы, когда смотришь чужие исходники, а так же дикая инициализация переменных в них.



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

Цитата: Proger_XP

По поводу while/do..while - по возможности я стараюсь не использовать break, поэтому пытаюсь использовать условия циклов, но когда приходится писать что-то вроде такого:
 
Код:
do {
  cond = getCond();
  if (cond) {
    ...
  }
while (!cond);

...то я вместо повторов условий ставлю просто break/return, как в первом/третьем примерах.



Тут ещё переменная cond мешается. Её придётся создавать и инициализировать где-то за пределами цикла. Не ФП-шно :)

Как компилятор переварит выкрутасы - не очень важно. Более важна читаемость, лаконичность, свобода от "мин замедленного действия".

287
21 июля 2010 года
Shiizoo
958 / / 14.03.2004
Ну, while (true) где-нибудь на 1e-99999999999999999999999999999 с быстрее скомпилится, чем пустой for, так что для лютого перфекциониста выбор очевиден.
Блок-схему проще нарисовать с меньшим числом выходов из цикла, но, в конечном итоге, смотреть и работать придется с кодом, а в нем удобнее кучей break'ов оперировать, imvho.

--
Про теоретическую оптимальность для старых/мкшных компилеров не очень понял. =)
87
21 июля 2010 года
Kogrom
2.7K / / 02.02.2008
Цитата: Shiizoo
Про теоретическую оптимальность для старых/мкшных компилеров не очень понял. =)



Да, это я наверное попутал. Теоретически небесконечный while будет не медленнее, чем for, а do-while даже быстрее, так как ему нужен только один "джамп". Это если без оптимизации. Но теоретически компилятору легче оптимизировать код цикла, в котором число итераций заранее известно. Вот только к бесконечным циклам это не относится...

87
21 июля 2010 года
Kogrom
2.7K / / 02.02.2008
Ок. Добавлю ещё один случай - комбинированный из первых двух:

 
Код:
while(!condition_func())
{
    // ...
    if(condition_func()) break;
    // ...
}


Это выглядит как уродство, или вполне допустимо?
287
21 июля 2010 года
Shiizoo
958 / / 14.03.2004
Я думаю, вполне. =)
253
21 июля 2010 года
Proger_XP
1.5K / / 07.08.2004
Цитата: Kogrom
while(1)


Кстати, если уж говорим о чистом коде - то в while(1) vs. while(true) к первому я отношусь хуже, чем к for(;; ) - что обозначает цифра 1 на первый взгляд (/на нетрезвую голову :D)? Одну итерацию? А после (bool)1 получается, что совсем наоборот.

Так что этой конструкции тоже стоит избегать, ИМХО.

Цитата: Kogrom

Тут ещё переменная cond мешается. Её придётся создавать и инициализировать где-то за пределами цикла. Не ФП-шно :)


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

В длинном цикле, однако, я использую именно if'ы, так как где-то в середине цикла break можно не заметить (особенно если их несколько и в разных местах), а вот indentation - намного нагляднее.

Цитата: Kogrom
Ок. Добавлю ещё один случай - комбинированный из первых двух:
while(!condition_func()) { ... if(condition_func()) break; ... }


А нафиг такая форма может быть нужна? :eek:
По-моему изврат, лучше уж do..while из моего примера, там по крайней мере условие инициализируется внутри цикла.

87
21 июля 2010 года
Kogrom
2.7K / / 02.02.2008
Цитата: Proger_XP
Кстати, если уж говорим о чистом коде - то в while(1) vs. while(true) к первому я отношусь хуже, чем к for(;; ) - что обозначает цифра 1 на первый взгляд (/на нетрезвую голову :D)? Одну итерацию? А после (bool)1 получается, что совсем наоборот.


Но в си до недавнего времени не было булевского типа. Да и сейчас не всё просто. Потому и 1. Для C++ - конечно же true.

Цитата: Proger_XP
Так нет, в том-то и смысл, что она инициализируется внутри цикла. Просто она проверяется в двух местах + появляется лишний if, что вообще говоря перебор, ибо можно поставить один break и убрать несколько инструкций и переменную..



Как это она инициализируется внутри цикла? Так что-ли:

 
Код:
do {
  bool cond = getCond();
  if (cond) {
    ...
  }
while (!cond);

Такое работать не должно, ибо переменная исчезнет раньше while. Значит объявляется и инициализируется (явно или неявно) снаружи цикла.
Цитата: Proger_XP
А нафиг такая форма может быть нужна? :eek:
По-моему изврат, лучше уж do..while из моего примера, там по крайней мере условие инициализируется внутри цикла.



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

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

253
21 июля 2010 года
Proger_XP
1.5K / / 07.08.2004
Цитата: Kogrom
Но в си до недавнего времени не было булевского типа. Да и сейчас не всё просто. Потому и 1. Для C++ - конечно же true.


А, да, про bool в С я не раз слышал. Но и сейчас часто встречаю использование while(1) в самых разных языках, в том же PHP, к примеру - видимо народ ведётся на то, что оно короче пишется.

Цитата: Kogrom
Как это она инициализируется внутри цикла?
Такое работать не должно, ибо переменная исчезнет раньше while. Значит объявляется и инициализируется (явно или неявно) снаружи цикла.


Ну, объявить переменную вне цикла по-моему не проблема, я имел в виду именно место, где ей присваивается значение - это происходит в одной точке внутри цикла, а не один раз до и ещё раз внутри.

Да и потом далеко же не все языки дают циклам свою зону видимости, так что для них даже объявления снаружи ни к чему.

Цитата: Kogrom
Например, если условие проверяется вначале или в конце тела цикла. Тут экономим строчку или две. Но пурист скажет, что такой код запутает читающего, так как тот может решить, что выход из цикла идёт в одном месте.


Я не пурист, но я тоже так скажу :)

Плюс, там происходит два вызова функции проверки условия на одну итерацию - становится не понятно, от чего это условие зависит. Например, когда каждый её вызов сдвигает какой-то внутренний указатель, то почему она вызывается два раза - фактически две итерации в одной? Ещё и разбитых пополам break'ом.
В таком случае нужно использовать переменную, а её нужно будет где-то устанавливать - если не хотим делать этого два раза, нужно юзать do..while + if'ы, получается ещё больше кода.
И так далее.

Цитата: Kogrom
Кроме того, это может быть перестраховкой. Но перестраховки вредны тем, что могут скрыть дефект ПО, и это сокрытие в лучшем случае может внести ненужные задержки.


+1

1
22 июля 2010 года
kot_
7.3K / / 20.01.2000
Цитата: Proger_XP
А, да, про bool в С я не раз слышал. Но и сейчас часто встречаю использование while(1) в самых разных языках, в том же PHP, к примеру - видимо народ ведётся на то, что оно короче пишется.


народ исходит из того, все что не ноль - то true иначе false. Это общее правило для приведения типов к булевскому. Потому пожалуй у крайне ограниченного круга людей тут могут возникнуть проблемы с чтением. И нормальных среди них ... мало. :)
А что типа уважаемым участникам дискуссии слабо взять и скомпилировать и посмотреть, что собственно генерирует компилятор? Или просто хочется почесать языками? Или может просто не знают о такой возможности? Так она есть.

285
22 июля 2010 года
Romik
479 / / 24.11.2002
Я предпочитаю использовать флаги для выхода из циклов, это упрощает работу при наличии нескольких потоков. Мне все же ближе javascript, но, думаю, это в равной степени относится и к c/cpp.
[highlight=javascript]
var f=true;
while(f) {
// do something
// turn off 'f' if you need it
}

window.onclick=function(){
/* using closure */
f=false; // stop iterations
}
[/highlight]
56K
22 июля 2010 года
pika.chu
13 / / 19.07.2010
мне кажется, это не тема для хуливара. единственное отличие всех приведенных конструкций в удобочитаемости, и то, каждый сочтет свою конструкцию удобней. На производительность выбор конкретной конструкции сильно не повлияет.
а можно вообще организовать цикл при помощи ассемблерных вставок, как то так

Цитата:
mylabel:

//cycle body

__asm {
call getCondition
test eax,eax
jz mylabel
}

253
22 июля 2010 года
Proger_XP
1.5K / / 07.08.2004
Цитата: kot_
народ исходит из того, все что не ноль - то true иначе false. Это общее правило для приведения типов к булевскому. Потому пожалуй у крайне ограниченного круга людей тут могут возникнуть проблемы с чтением. И нормальных среди них ... мало. :)


Ну, если исходить из того, что и глобальные переменные существуют и работают на ура, то почему бы не использовать только их, ведь меньше кода и удобно?

Цитата: kot_
А что типа уважаемым участникам дискуссии слабо взять и скомпилировать и посмотреть, что собственно генерирует компилятор? Или просто хочется почесать языками? Или может просто не знают о такой возможности? Так она есть.


Так мы не бестродействие обсуждаем, что генерит компилер он знает лучше. Интересны сами конструкции.

И языками почесать тоже - это же холивар :)

1
22 июля 2010 года
kot_
7.3K / / 20.01.2000
Цитата: Proger_XP
Ну, если исходить из того, что и глобальные переменные существуют и работают на ура, то почему бы не использовать только их, ведь меньше кода и удобно?


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

Цитата: Proger_XP

Так мы не бестродействие обсуждаем, что генерит компилер он знает лучше. Интересны сами конструкции.

И языками почесать тоже - это же холивар :)



чесание языками без причины - признак отнюдь не холивара :)

399
22 июля 2010 года
KIV
432 / / 20.01.2009
Цитата:
а можно вообще организовать цикл при помощи ассемблерных вставок, как то так


Ну а вообще всё надо писать на ассемблере :-)

Два раза вызов одной и той же функции для проверки условия выхода в одной итерации - зло, потому что:
1. Потери скорости. Особенно если функция проверки не состоит из одной проверки условия и возвращения результата.
2. Функция может что-то изменять при проверке, как уже сказали ранее, и поэтому могут возникнуть проблемы
3. Код понимается хуже

87
22 июля 2010 года
Kogrom
2.7K / / 02.02.2008
Цитата: kot_
А что типа уважаемым участникам дискуссии слабо взять и скомпилировать и посмотреть, что собственно генерирует компилятор?


Да не слабо, просто не вижу смысла. Например, возьмём первые два примера и имеющийся под рукой компилятор:

Код:
import dis

def func1():
    while True:
        if condition_func(): break

dis.dis(func1)

print '-' * 20

def func2():
    while condition_func(): pass

dis.dis(func2)

Ну и вывод:
Код:
6           0 SETUP_LOOP              27 (to 30)
        >>    3 LOAD_GLOBAL              0 (True)
              6 JUMP_IF_FALSE           19 (to 28)
              9 POP_TOP            

  7          10 LOAD_GLOBAL              1 (condition_func)
             13 CALL_FUNCTION            0
             16 JUMP_IF_FALSE            5 (to 24)
             19 POP_TOP            
             20 BREAK_LOOP          
             21 JUMP_ABSOLUTE            3  
--------------------
 14           0 SETUP_LOOP              15 (to 18)
        >>    3 LOAD_GLOBAL              0 (condition_func)
              6 CALL_FUNCTION            0
              9 JUMP_IF_FALSE            4 (to 16)
             12 POP_TOP            
             13 JUMP_ABSOLUTE            3

Лишнее (возврат пустоты) убрал. Во втором случае короче для данного конкретного примера, но это мало о чём говорит, ибо случай простейший.

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

"Требования к оформлению бесконечного цикла абсолютно произвольно" только со стороны стандартов языка, компиляторов. Но со стороны программиста и читающего - это не так.
87
22 июля 2010 года
Kogrom
2.7K / / 02.02.2008
Цитата: Romik
Я предпочитаю использовать флаги для выхода из циклов, это упрощает работу при наличии нескольких потоков.



Флаг - это переменная, в данном случае, даже глобальная (для показанной области видимости). Для маленького кода - оно самое то. Но функция гибче тем, что, например, не нужно знать, сколько флагов применяются для формирования условия выхода, с помощью каких логических операций получается результирующий флаг.

Короче, тут всё зависит от конкретного кода.

285
22 июля 2010 года
Romik
479 / / 24.11.2002
Korgrom, всё верно и именно потому [у меня] в javascript все замыкания ограничены областью видимости конкретной функции. Однако флаг отражает результат решения, а обрабатывающая функция может быть асинхронной, находится в отдельном потоке и никак не влиять на производительность. Вызовы функции внутри цикла мне меньше импонируют, так как куда удобнее пользоваться механизмом событий для отработки своего кода.
Мне представляется крайне узким список задач, где было бы полезно в каждой итерации вызывать свою функцию проверки, в ущерб безболезненной проверке флага.

Проблема доступа к флагу может решаться посредством сокрытия его в объекте, но мне этот способ не нравится из-за сложности применения на практике и очевидной бесполезности. Количество флагов влияющих на работу цикла в идеале должно стремится к единице. Все остальные флаги могут быть скрыты в конкретных функциях обработчиках.
1
22 июля 2010 года
kot_
7.3K / / 20.01.2000
Цитата: Kogrom
Но со стороны программиста и читающего - это не так.


т.е. видимо есть некий абсолют гарантирующий успешность одного варианта кода перед другим? Или что?
Утверждая - "Требования к оформлению бесконечного цикла абсолютно произвольно" - я вполне обосновано говорю, если во всех случаях бесконечного цикла вы используете единый подход - то абсолютно пох, что вы конкретно используете.
Те кто утверждают что в стопятсоттысячный раз им трудно понять что while(1){... //тут условие выхода } - всего навсего бесконечный цикл - вероятно имеют проблемы с задержкой развития - ввиду того, что конструкция вполне стандартная для языка С/С++. Конкретная же конструкция не имеет никаких особых преимуществ перед любыми остальными.

87
22 июля 2010 года
Kogrom
2.7K / / 02.02.2008
Romik, в общем, я согласен, что в большинстве случаев флаг удобнее. То есть все мои примеры (из первых двух сообщений) для соответствия принципу KISS можно было бы переписать с флагом.

Цитата: kot_
если во всех случаях бесконечного цикла вы используете единый подход - то абсолютно пох, что вы конкретно используете.


Вот я и хотел выявить для себя такой подход. Пока вижу только одну нечёткую рекомендацию: если внутри тела цикла есть из него выход через break/return, то лучше сделать цикл бесконечным. Это намекнёт читающему поискать выход из цикла внутри.

Цитата: kot_
Те кто утверждают что в стопятсоттысячный раз им трудно понять что while(1){... //тут условие выхода } - всего навсего бесконечный цикл - вероятно имеют проблемы с задержкой развития - ввиду того, что конструкция вполне стандартная для языка С/С++.


Я и сам не совсем понял чего тут непонятного. Разве что while(true) больше на человеческий язык похоже.

1
22 июля 2010 года
kot_
7.3K / / 20.01.2000
Цитата: Kogrom

Вот я и хотел выявить для себя такой подход. Пока вижу только одну нечёткую рекомендацию: если внутри тела цикла есть из него выход через break/return, то лучше сделать цикл бесконечным. Это намекнёт читающему поискать выход из цикла внутри.


Хм. Если внутри цикла есть выход через break/return - то далеко не факт, что его всегда надо делать бесконечным. Если из цикла выход возможен только через break/return - это одно. но например в чтении некоторых данных по определенному условию из источника - то вариант завершения самый очевидный - либо выполнение условия, либо окончание чтения данных. Зачем же его делать бесконечным? читаем до конца данных - условие выполнилось - то break/return. Я чего то не понял?

14
22 июля 2010 года
Phodopus
3.3K / / 19.06.2008
Залезу собссно сюда чтобы просто сказать что тоже предпочитаю не пользоваться break/return. Из-за этого для страшной дельфины даже написано семейство Assign*-функций которые эмулируют сишное while [COLOR="Blue"](res = getRes())[/COLOR] {}
287
22 июля 2010 года
Shiizoo
958 / / 14.03.2004
Цитата: Phodopus
Залезу собссно сюда чтобы просто сказать что тоже предпочитаю не пользоваться break/return. Из-за этого для страшной дельфины даже написано семейство Assign*-функций которые эмулируют сишное while [COLOR="Blue"](res = getRes())[/COLOR] {}



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

87
22 июля 2010 года
Kogrom
2.7K / / 02.02.2008
Цитата: kot_
например в чтении некоторых данных по определенному условию из источника - то вариант завершения самый очевидный - либо выполнение условия, либо окончание чтения данных. Зачем же его делать бесконечным? читаем до конца данных - условие выполнилось - то break/return. Я чего то не понял?



Если тело цикла маленькое (не более 3 строчек), то, вероятно, так. Иначе человек, сопровождающий код, может долго ломать голову, почему файл иногда читается не полностью. Конечно, можно поставить предупреждающий комментарий, но это похоже на костыль.

Можно сделать так:

 
Код:
while(true)
{
    // ...
    if (EofFlag || myFlag) break;
    // ...
}

и выход будет в одной точке. Можно это внести в само условие цикла, но тогда флаг придётся выносить за цикл.
287
22 июля 2010 года
Shiizoo
958 / / 14.03.2004
С таких позиций for-loop вообще можно объявить вне закона и перевести все на while с флагами. =) И придется тогда все время перед циклами с пред-условием лепить инициализацию флагов, которая будет дублироваться в теле самого цикла. Либо, что по-моему, совсем ужасно, делать на основе while-do цикл с пред-условием, но с выносом проверки условия из того места, где ему положено быть, в тело цикла. Франкенштейн, потому что это уже while-loopah-goto. А for тем и импонирует, что форма у него очень удобная для восприятия. Ну, это мне так кажется. =)
1
22 июля 2010 года
kot_
7.3K / / 20.01.2000
Цитата: Kogrom
Если тело цикла маленькое (не более 3 строчек), то, вероятно, так. Иначе человек, сопровождающий код, может долго ломать голову, почему файл иногда читается не полностью.


Знаешь, я тоже иногда считаю окружающих дебилами - но в целом это не так :)
Если ты твердо уверен что человек, читающий твой код не способен удержать в памяти три строчки - я уж и не уверен что это забота о читаемости кода - это какое то завуалированное презрение к людям. Уж не знаю. Ты вообще к виду Homo Sapiens относишься? ))
На самом деле ты не прав - если отбросить абсолютно дебильную идею, что изучающий код способен помнить только то, что видит на экране - твоя идея сама по себе ошибка.
Почему? Потому что - если поток данных завершен - прочитан файл, вычитан рекордсет и т.п. - это одно состояние программы. Если же выполнено сравнение успешно - это вероятно совсем другое состояние. Конечно здесь надо опираться на конкретную ситуацию - но имхо не правомерно - если я ищу совпадение (например) - то как раз неожиданной будет единая точка выхода - очень приятно, нашел я что либо - или нет - но выйти будьте добры в одном месте. Зачем? Это кардинально разные события - то ли я вышел с искомым, то ли потому что кончилось где искать? Твой подход может быть вполне назван клоачным :) по большому и малому все в одно :) Но как бы там ни было, что одно решение, что второе - абсолютно произвольно. ВОЗМОЖНО твое код может усложнить - но это опять же от конкретной задачи. И по сути ни на качество ни на читаемость как правило влияния не оказывает.

87
22 июля 2010 года
Kogrom
2.7K / / 02.02.2008
Отвечу сразу на 2 цитаты.
Цитата: Shiizoo
С таких позиций for-loop вообще можно объявить вне закона и перевести все на while с флагами. =) И придется тогда все время перед циклами с пред-условием лепить инициализацию флагов...


Цитата: kot_
Знаешь, я тоже иногда считаю окружающих дебилами - но в целом это не так :)
Если ты твердо уверен что человек, читающий твой код не способен удержать в памяти три строчки - я уж и не уверен что это забота о читаемости кода - это какое то завуалированное презрение к людям. Уж не знаю. Ты вообще к виду Homo Sapiens относишься? ))



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

То есть тут нужно определить, где будут "спагетти", а где - нет. В идеале должен быть какой-то такой список циклов:

1. for (iter in iters) - то есть обход итераторами. Тут не должно быть ни break, ни continue.
2. Вариант первого for (i in n..m), например, for (i in 0..10). Тоже без неожиданных выходов.
3. while(flag), где флаг не может быть константой. Тоже выход один.
4. loop - бесконечный цикл. Вот тут уж допустимо всё: и break, и continue и ещё какая-нибудь "лапша".

Запрещать return в первых трёх видах циклов наверное не имеет смысла. Но увлекаться им тоже не следует.

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

287
22 июля 2010 года
Shiizoo
958 / / 14.03.2004
В принципе, идея хорошая как рекомендация по оформлению кода. Но без (значительного) опыта применения как-то не очень понятно, насколько теоретическая полезность реальна. Ясно, что точно не видел, чтобы кто-то такого подхода придерживался. Ну да у меня опыта с гулькин нос. =) В любом случае попробую подружиться с этой идеей на практике, ибо в данном виде она уже достойна внимания.

Мысль только еще такая, что зная задачу, решаемую алгоритмом, должно быть, по-моему, ясно, какие могут быть исключительные ситуации (т. е. breakes). Мне без примера, а его у меня нет, не очень верится, что можно забыть break'и.
87
22 июля 2010 года
Kogrom
2.7K / / 02.02.2008
Цитата: Shiizoo
В принципе, идея хорошая как рекомендация по оформлению кода.


Всё-таки там предположение. И на счет continue я наверное погорячился. Давно не использовал - вот и решил, что он не нужен.

Цитата: Shiizoo
Мысль только еще такая, что зная задачу, решаемую алгоритмом, должно быть, по-моему, ясно, какие могут быть исключительные ситуации (т. е. breakes). Мне без примера, а его у меня нет, не очень верится, что можно забыть break'и.



Вот это я не совсем распарсил, потому ответ может быть неточным:

 
Код:
if (...) ...
else if (...) ...
else if (...) ...
else if (...) ...
else if (...) ...
else if (...) ...
else ...

и ни одного break. То есть, это ещё может навести на мысль, что и switch-case не нужен. Но это уже отдельная тема.

Кроме того, я не говорил, что про break-и надо забыть. Но вроде бы надо предупредить читателя, что они будут в конкретном цикле.
287
22 июля 2010 года
Shiizoo
958 / / 14.03.2004
Ну, я так и понял, что предлагается определенное оформление цикла использовать как способ декларирования того, что flow-control полностью определяется заголовком цикла (варианты 1-3), либо же используются соответствующие операторы (вариант 4). Т. е. дополнительный прием самодокументирования.

Конечно, отшлифовать надо идею, вот continue я тоже забыл, и не очевидно, в каких из 4 вариантов следует его допускать. А свитч, по-моему, можно поковырять разве что чтобы новое что-то узнать, т. к. он точно эффективнее if'а, проще (если я не ошибаюсь) в оптимизации, и вокруг него как антогониста if'а ведутся особые свистопляски в языках описания аппаратуры (VHDL, Verilog и т. п.).
1
23 июля 2010 года
kot_
7.3K / / 20.01.2000
Цитата: Kogrom
В идеале должен быть какой-то такой список циклов:


странное у тебя понятие идеала. Ну хотя если учесть место твоего проживания - то не удивительно. Мне казалось что возможность выйти условно из цикла - это как бы естественно. Это выбор пользователя - а не свойство цикла. Ты же предлагаешь этим процессом управлять - тогда надо дополнительную спецификацию ввести - оставь надежду, всяк сюда входящий.... И возможность выйти из цикла становится свойством цикла. Не ну я понимаю - у вас счас эпоха супердзюдоистов - противовес силиконовой долине - сколково, противовес нормальному циклу - список циклов. Нормально вьюноша. Я думаю твои идеи будут подхвачены.

87
23 июля 2010 года
Kogrom
2.7K / / 02.02.2008
Цитата: kot_
Мне казалось что возможность выйти условно из цикла - это как бы естественно. Это выбор пользователя - а не свойство цикла. Ты же предлагаешь этим процессом управлять - тогда надо дополнительную спецификацию ввести - оставь надежду, всяк сюда входящий.... И возможность выйти из цикла становится свойством цикла.


Зато видно: вот этот цикл - гибкий, а вот этот - предсказуемый.

Возможно, такая ясность может пригодиться только для while. Про for - сильно не уверен. Например, для поиска элемента в списке может потребоваться дополнительный выход. Но тут лучше будет использовать return со значением индекса, а не пустой break.

Цитата: kot_
противовес нормальному циклу - список циклов.


В общем-то, я перечислил циклы, которые есть в современных языках программирования. Более того, некоторые из видов циклов, типа do-while я убрал. С другой стороны, while(true) (оно же for( ; ; )) - настолько привычная конструкция, что её можно выделить в отдельный вид циклов. Не обязательно придумывать специальное слово - главное помнить, что это уже не while и не for.

287
23 июля 2010 года
Shiizoo
958 / / 14.03.2004
Цитата: Kogrom
Не обязательно придумывать специальное слово - главное помнить, что это уже не while и не for.



 
Код:
franken-loopah-goto {
  statement;
  ...
}


В любом случае, fail или нет — покажет время. Если, конечно, не забыть это дело сразу как топик отвалится. А do-while надо вернуть. Чем он хуже-то? И мне интересно, а как часто встречаются циклы, которые без прокрутки не охватишь? На вскидку так.
87
23 июля 2010 года
Kogrom
2.7K / / 02.02.2008
Цитата: Shiizoo
А do-while надо вернуть. Чем он хуже-то?


Чем хуже цикл с постусловием? Это субъективное. Конечно, он может сэкономить строчку или несколько, но зато первая итерация проходит без условия, то есть отличается от других. Да и не так часто используются такие циклы.

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

Цитата: Shiizoo
И мне интересно, а как часто встречаются циклы, которые без прокрутки не охватишь? На вскидку так.



Не понял вопроса.

285
23 июля 2010 года
Romik
479 / / 24.11.2002
Обсуждение методик является полезным и интересным занятием, но выделение одной методики в отдельную конструкцию языка мне представляется подобным приданию личностных качеств частям тела.
87
23 июля 2010 года
Kogrom
2.7K / / 02.02.2008
Цитата: Romik
Обсуждение методик является полезным и интересным занятием, но выделение одной методики в отдельную конструкцию языка мне представляется подобным приданию личностных качеств частям тела.



Ещё один заговорил загадками...

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

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

Другое дело, что может и while тогда будет не нужен... шучу.

287
23 июля 2010 года
Shiizoo
958 / / 14.03.2004
Я спрашивал про то, как часто на деле встречаются такие большие циклы, что взглядом никак не охватить. Ну, из опыта. =)

А про нет гарантии, гарантий вообще нет, что компилятор оптимизировать умеет. =) И я вообще ни йоты не знаю про мультипоточное программирование, векторизацию и т. п., но, может, там есть реальные рекомендации, которые созвучны с темой обсуждения.
285
23 июля 2010 года
Romik
479 / / 24.11.2002
Kogrom, вопрос оптимизации компилятора следует обсуждать разработчикам компилятора. Тут, как мне показалось, собрались пользователи компилятора. Зачем задачи оптимизации компилятора проецировать на образ мышления программиста? Был while(1){}, он им и останется. Не вижу какой-либо надобности (потребности) в отдельном forever() {}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог