Re[7]: Приходилось ли вам использовать goto?
От: vdimas Россия  
Дата: 02.04.06 00:48
Оценка:
Здравствуйте, Cider, Вы писали:

C>Тогда все операции изменения потока управления — это аналог goto


Не все, а только лишь безусловные.

Для С-подобных языков, это: goto, return, break, continue.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: Приходилось ли вам использовать goto?
От: Kemsky  
Дата: 03.04.06 06:48
Оценка: :)))
Здравствуйте, McSeem2, Вы писали:

MS>Я бы сказал, что использование goto в стиле Фортрана-4 — это маразм. Однако, полный запрет goto — это тоже маразм. Народу не нужен нездоровый фанатизм. Народу нужен здоровый фанатизм.


Вы подходите к вопросу слишком рационально. Между тем, если изучить постинги по этому вопросу, станет очевидным, что с этим оператором дело не чисто. Он скверен, как число 13, как представитель касты неприкасаемых. Его использование — это ересь, за которую следует отлучать от интернета.
Re[8]: Приходилось ли вам использовать goto?
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 03.04.06 07:45
Оценка:
Здравствуйте, kan_izh, Вы писали:

_>for(xmlNodePtr c = parent->children; c; c = c->nextSibling)

_>{
_> if(c->type == NODE_TEXT) continue;
_> if(c->namespace != myNamespace) continue;
_>...
_>}
_>[/ccode]
_>В таком коде такой неявный брэйк нельзя сделать. А замена несколько continue будет порождать глубокую вложенность if.

По моему, даже самая наиглубочайшая вложенность IF — и то лучше чем один единственный continue по той простой причине, что код содержащий в себе слова continue невозможно оформить в виде отдельной процедуры.

Кстати, зачастую, всё множество вложенных IF-ов можно заменить одним единственным:
for(xmlNodePtr c = parent->children; c; c = c->nextSibling)
{
  if ((c->type != NODE_TEXT) && (c->namespace == myNamespace) && (...) && (...) && (...) && (...) ...)
  {
    ...
  }
}

или ещё лучше так:
for(xmlNodePtr c = parent->children; c; c = c->nextSibling)
{
  if (IsThisGood(c))
  {
    ...
  }
}
Re[9]: Приходилось ли вам использовать goto?
От: kan_izh Великобритания  
Дата: 03.04.06 09:59
Оценка:
Сергей Губанов wrote:

> _>for(xmlNodePtr c = parent->children; c; c = c->nextSibling)

> _>{
> _> if(c->type == NODE_TEXT) continue;
> _> if(c->namespace != myNamespace) continue;
> _>...
> _>}
> _>[/ccode]
> _>В таком коде такой неявный брэйк нельзя сделать. А замена несколько
> continue будет порождать глубокую вложенность if.
>
> По моему, даже самая наиглубочайшая вложенность IF — и то лучше чем один
> единственный continue по той простой причине, что код содержащий в себе
> слова continue невозможно оформить в виде отдельной процедуры.
Вообще говоря, различие исключительно синтаксическое, continue — всего лишь sugar, насколько оправдано использование
сахара — не знаю, диабетикам, конечно, вредно, но это не означает, что его нужно запретить вообще.
Так что почему невозможно? Не сложнее, чем куча вложенных if-ов. И делается довольно просто — все continue заменяются на
"return false", в конце, где нет continue — return true, а вместо блока, содержащего continue-ы ставим
if(!checkContinues(i)) continue;
или
if(chechContinues(i))
{
...
}

по вкусу.

> Кстати, зачастую, всё множество вложенных IF-ов можно заменить одним

> единственным:
>
> for(xmlNodePtr c = parent->children; c; c = c->nextSibling)
> {
> if ((c->type != NODE_TEXT) && (c->namespace == myNamespace) && (...) && (...) && (...) && (...) ...)
> {
> ...
> }
> }
>
Насколько оправданно писать всё в одну строчку (точнее оператор)?..

> или ещё лучше так:

>
> for(xmlNodePtr c = parent->children; c; c = c->nextSibling)
> {
> if (IsThisGood(c))
> {
> ...
> }
> }
Чем это хуже?
for(...)
{
    if(!IsThisGood(c)) continue;
    ...
}

Мне, честно говоря, так больше нравится — меньше вложенность {}.

Ладно, в общем, continue — да, легко обходится (даже можно запретить требованиями corporation code style). А что делать
с break? Насколько это мне представляется, это можно обойти только введением специального флага, что засоряет синтаксис.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re: Приходилось ли вам использовать goto?
От: Pavel Dvorkin Россия  
Дата: 04.04.06 02:53
Оценка: :))) :)
Здравствуйте, zzzale, Вы писали:

Z>Я имею в виду случаи когда ДЕЙСТВИТЕЛЬНО была необходимость применять этот оператор (желательно с примером и описанием ПО).


Во времена Windows 3.x исходник DefWindowProc был опубликован. И там было такое

goto ICantBelieveThatIUserAGotoStatement;
With best regards
Pavel Dvorkin
Re[9]: Приходилось ли вам использовать goto?
От: zzzale  
Дата: 04.04.06 09:06
Оценка: +4
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>Ну, во-первых, я в таких местах всегда пишу комментарий типа "exit the loop", а во-вторых — как я писал это чисто иррациональное, а не мотивированное большей читабельностью кода. Ну вот заскок у меня такой. Просто иногда бывает "не в тему" заводить очередную булеву переменную, значение которой проверяется наряду с "основным" условием цикла.


SDB>P.S.

SDB>Посто мой был собственно в поддержку "некоторых", на которых ссылался Cyberax.

В Вашем примере:

for (int i = 0; i < 10; ++i)
{
...
    if (some_rare_contition)
    {
        i = 10;        // неявный break :)
    }
    else {
        ...
    }
}


в случае если потребуется изменить количество итераций цикла — надо будет менять две строчки кода. Есть некоторая вероятность, что вы забудете это сделать. А когда начнёте искать ошибку, то этот комментарий "exit the loop" будет сбивать с толку, т.к. сообщает, что здесь выход из цикла.
Re[10]: Приходилось ли вам использовать goto?
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 04.04.06 09:11
Оценка:
Здравствуйте, zzzale, Вы писали:

Z>в случае если потребуется изменить количество итераций цикла — надо будет менять две строчки кода. Есть некоторая вероятность, что вы забудете это сделать. А когда начнёте искать ошибку, то этот комментарий "exit the loop" будет сбивать с толку, т.к. сообщает, что здесь выход из цикла.


Еще раз подчеркну, что не считаю этот код "идеальным" и "образцовым".
[ posted via RSDN@Home 1.1.4 stable SR1 r568, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[2]: Приходилось ли вам использовать goto?
От: zzzale  
Дата: 04.04.06 09:14
Оценка:
Здравствуйте, yurafitt, Вы писали:

Y>Мне нет, а вот в примерах поставляемых с SDK DirectX 7.0 во многих местатх встречал использование goto


А были ли они там оправданы с Вашей точки зрения?
Или это были примеры неграмотного использования языка.
Re[2]: Приходилось ли вам использовать goto?
От: zzzale  
Дата: 04.04.06 09:16
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А болкк интеллектуальных вопросов не нашлось?


VD>Или новое поколени РСДН-еров не умеет пользоваться поиском?


Вопрос не интеллектуальный, а философский.
Однозначного ответа на него найти не получается.
Re[2]: Приходилось ли вам использовать goto?
От: zzzale  
Дата: 04.04.06 09:20
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Во времена Windows 3.x исходник DefWindowProc был опубликован. И там было такое


PD>goto ICantBelieveThatIUserAGotoStatement;


Мне когда-то преподаватель показывал примеры на WinAPI, когда следовало применять goto.
Что-то вроде:

void fun()
{
    //... действия
    if(ошибка)goto end_fun;


    //... снова действия
         //вложенный if
         if(что-то)goto end_fin;
   
    //и опять в том же духе.

 normal:
   //что-то сделать
 end_fun:
   //что-то сделать
}
Re[3]: Приходилось ли вам использовать goto?
От: Kluev  
Дата: 04.04.06 09:31
Оценка:
Здравствуйте, zzzale, Вы писали:

Z>Мне когда-то преподаватель показывал примеры на WinAPI, когда следовало применять goto.

Z>Что-то вроде:

Z>
Z>void fun()
Z>{
Z>    //... действия
Z>    if(ошибка)goto end_fun;


Z>    //... снова действия
Z>         //вложенный if
Z>         if(что-то)goto end_fin;
   
Z>    //и опять в том же духе.

Z> normal:
Z>   //что-то сделать
Z> end_fun:
Z>   //что-то сделать
Z>}
Z>


Не всегда стоит слушать преподавателей.

void
    func()
{
    do
    {
        if ( error1 )
            break;

        if ( error2 )
            break;

        // well, no errors, do other stuff and exit
        return;
    }
    while (0);
    // вышли брейком
    // обрабатываем ошибку здесь
}
Re[10]: Приходилось ли вам использовать goto?
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 04.04.06 10:57
Оценка:
Здравствуйте, kan_izh, Вы писали:

_>Ладно, в общем, continue — да, легко обходится (даже можно запретить требованиями corporation code style).

_>А что делать с break?

Ничего не делать, break ни в чём не виноват. Его только нельзя использовать внутри WHILE-DO-END и REPEAT-UNTIL циклов по определению этих циклов. Внутри безусловного цикла LOOP-END инструкция break (т.е. EXIT) — единственный способ завершения цикла.

P. S.
В Си-образных языках безусловный цикл LOOP-END синтаксически обычно записывается как: while (true) {...}.
Re[4]: Приходилось ли вам использовать goto?
От: zzzale  
Дата: 04.04.06 11:21
Оценка:
Здравствуйте, Kluev, Вы писали:

K>Не всегда стоит слушать преподавателей.


K>
K>void
K>    func()
K>{
K>    do
K>    {
K>        if ( error1 )
K>            break;

K>        if ( error2 )
K>            break;

K>        // well, no errors, do other stuff and exit
K>        return;
K>    }
K>    while (0);
K>    // вышли брейком
K>    // обрабатываем ошибку здесь
K>}
K>


Мне тоже пример показался не самым лучшим.
Более точнее:
Z>void fun()
Z>{
Z> //... действия
Z> if(ошибка)goto end_fun;


Z> //... снова действия

Z> //вложенный if
for(...)
Z> {
//...
if(что-то)goto end_fin;
//...
}

Z> //и опять в том же духе.


Z> normal:

Z> //что-то сделать
Z> end_fun:
Z> //что-то сделать
Z>}
Z>
Re[3]: Приходилось ли вам использовать goto?
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.04.06 16:44
Оценка:
Здравствуйте, zzzale, Вы писали:

Z>Вопрос не интеллектуальный, а философский.

Z>Однозначного ответа на него найти не получается.

Филосовский он примерно настолько насколько филосовским вопросом является чем закусывать тройной адеколон.

Применение goto можно оправдать только в генерируемом коде. И то толко упрощением генератора.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Приходилось ли вам использовать goto?
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.04.06 16:44
Оценка:
Здравствуйте, zzzale, Вы писали:

Z>Мне когда-то преподаватель показывал примеры на WinAPI, когда следовало применять goto.


Он о С говорил или о С++?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Приходилось ли вам использовать goto?
От: Кодёнок  
Дата: 11.04.06 08:24
Оценка:
Совсем забыл. Зацените else-clause у циклов в питоне. else у цикла не выполяется, если цикл был прерван по break. Сильно подозреваю, что в питоне это сделано специально для решения типичной проблемы временной переменной-флага. Вот пример: если данные уже есть в массиве, то добавлять не надо, в противном случае — их надо добавить:
// всем знакомый паттерн
bool f = false;
for (unsigned i = 0; i < array.size(); ++i)
{
  if (array[i] == data)
  {
    f = true;
    break;
  }
}
if (!f) array.push_back(data);

for (unsigned i = 0; i < array.size(); ++i)
{
  if (array[i] == data)
    break;
}
else array.push_back(data);
Re[9]: Приходилось ли вам использовать goto?
От: WolfHound  
Дата: 11.04.06 17:10
Оценка:
Здравствуйте, Кодёнок, Вы писали:

Кё>Совсем забыл. Зацените else-clause у циклов в питоне. else у цикла не выполяется, если цикл был прерван по break. Сильно подозреваю, что в питоне это сделано специально для решения типичной проблемы временной переменной-флага. Вот пример: если данные уже есть в массиве, то добавлять не надо, в противном случае — их надо добавить:

Плохое решение. В таких случаях нужна декомпозиция.
bool Contains(Array const& array, Data const& data)
{
    for (unsigned i = 0; i < array.size(); ++i)
        if (array[i] == data)
            return true;
    retrun false;
}

if (!Contains(array, data))
    array.push_back(data);
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[10]: Приходилось ли вам использовать goto?
От: Olivan Россия  
Дата: 11.04.06 19:00
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Плохое решение. В таких случаях нужна декомпозиция.


или использование готовых алгоритмов
if (std::find(array.begin(), array.end(), data) == array.end())
    array.push_back(data);



Кстати, пример для упражнения
Кё>        CString expr = m_settings.expr;
Кё>        while (1)
Кё>        {
Кё>            if (IDOK != DataEditorDialog(expr).DoModal()) return 0;
            
Кё>            for (size_t i = 0; i < m_settings.rules.size(); ++i)
Кё>            {
Кё>                if (m_settings.rules[i].active && !m_settings.rules[i].Check(expr))
Кё>                {
Кё>                    MessageBox("Syntax error", 0, 0);
Кё>                    goto the_goto;
Кё>                }
Кё>            }
Кё>            break;
Кё>the_goto:;
Кё>        }
Кё>        m_settings.expr = expr;
Кё>

я бы всё-таки переписал с использованием флага:
        CString expr = m_settings.expr;
        bool rules_correct = false;
        while (!rules_correct)
        {
            if (IDOK != DataEditorDialog(expr).DoModal()) return 0;
            
            for (size_t i = 0, rules_correct = true; i < m_settings.rules.size() && rules_correct; ++i)
            {
                if (m_settings.rules[i].active && !m_settings.rules[i].Check(expr))
                {
                    rules_correct = false;
                    MessageBox("Syntax error", 0, 0);
                }
            }
        }
        m_settings.expr = expr;

кода столько же, но имхо так читабельней.
Re[11]: Приходилось ли вам использовать goto?
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 12.04.06 09:21
Оценка:
Здравствуйте, Olivan, Вы писали:

O>Кстати, пример для упражнения

...
O>я бы всё-таки переписал с использованием флага:
...
O>кода столько же, но имхо так читабельней.

Пора бы и прекратить предлагать иные варианты решения. Ведь, вообще-то, это
Автор: Сергей Губанов
Дата: 31.03.06
классическая задача линейного поиска имеющая каноническое решение:

i := 0;
WHILE (i < N) & условие(i) DO INC(i) END;
IF i < N THEN условие под номером i не выполнено END
Re[12]: Приходилось ли вам использовать goto?
От: Кодёнок  
Дата: 12.04.06 10:31
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>Пора бы и прекратить предлагать иные варианты решения. Ведь, вообще-то, это
Автор: Сергей Губанов
Дата: 31.03.06
классическая задача линейного поиска имеющая каноническое решение:


СГ>i := 0;

СГ>WHILE (i < N) & условие(i) DO INC(i) END;
СГ>IF i < N THEN условие под номером i не выполнено END

А если проверка условия состоит из 10 инструкций и не может быть записана выражением? А зависимость этих 10 инструкций от локальных переменных затруднит выделение его в локальную функцию? Для Оберона это особенно актуально.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.