Оправдано ли использование GOTO в струтурированных программах?31.07.07 11:49 [Den] Автор: Vedrus <Serokhvostov Anton> Статус: Member Отредактировано 04.08.07 04:52 Количество правок: 2
..А предложение/требование не использовать GOTO пришло, мне кажется, с ассемблерных времён, где код читать было весьма сложно из-за изобилия переходов, в результате чего в языках более высокого уровня большинство случаев применения goto были заменены синтаксическими конструкциями вроде for и while.
А вот могут ли существовать задачи, не реализуемые этими конструкциями.... Мне кажется, могут найтись.
местами21.08.07 16:59 Автор: zelych Статус: Member
Никогда не использую и даже когда нужно досрочно выйти из глубоких циклов завожу флаг и пишу
repeat
repeat
.....
until условие1 OR флаг
until условие2 OR флаг.
Т.О. абсолютно любой код можно написать используя только if then else и while/repeat.
НО!!!
Использую иногда для улучшения читабельности, т.к. goto и ехit позволяют сразу отваливаться из ситуаций, который в стуктурном программировании привели бы к очень глубокому уровню вложенности.
вместо
if условие1 then begin
.......
if условие2 then begin
........
if условие3 then begin
........
пишу:
if not условие1 then goto отвалить
и т.д.
Есть еще одно требование в добавок к вышесказанному - Нужна...28.08.07 10:36 Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
> Т.О. абсолютно любой код можно написать используя только if > then else и while/repeat.
Есть еще одно требование в добавок к вышесказанному - Нужна поддержка объединения операторов в блоки {} или begin/end.
Возьмем батник например. Иногда нужно выполнить кучу команд при условии. Поэтому и пишется первой строкой IF [условие не выполняется] то переход на метку в конце батника. Если же размножить IF перед каждой командой, то может выполнится только часть команд, если в процессе их выполнение результат проверки условия изменится.
bat-ники поддерживают блоки29.08.07 11:14 Автор: amirul <Serge> Статус: The Elderman
> > Т.О. абсолютно любой код можно написать используя > только if > > then else и while/repeat.
> > Есть еще одно требование в добавок к вышесказанному - Нужна > поддержка объединения операторов в блоки {} или begin/end. > Возьмем батник например. Иногда нужно выполнить кучу команд > при условии. Поэтому и пишется первой строкой IF [условие > не выполняется] то переход на метку в конце батника. Если > же размножить IF перед каждой командой, то может выполнится
if exist filename (
whatever
you
want
) else (
some
more
commands
)
---
> только часть команд, если в процессе их выполнение > результат проверки условия изменится.
Ну да, уже поддерживают в последних версиях виндов. Можно GOTO убирать :-).29.08.07 11:43 Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
+1, тоже давно хотел сказать, что поддержка блоков и функций в функциях в Паскале практически на 100% убирает нужность GoTo в этом языке.28.08.07 11:26 Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 28.08.07 12:07 Количество правок: 1
Без goto этот алгоритм реализовать невозможно. Это легко доказать.
Будем считать, что нам доступны только операторы if, while и do{}while; можно использовать break. Это стандартный набор - как правило любые другие операторы реализуются через них.
Далее надо заметить, что с помощью if{} переход в обратном направлении кода невозможен, то есть для этого можно использовать только while и do{}while. Для однократного перехода вперед нет принципиальной разницы между while и if (только while потребует дополнительной временной переменной; так что использовать будем if). Тогда приведенный код выше обязан иметь цикл while, содержащий фрагменты somecode2 и somecode3:
expr1 goto label2:
somecode1;
do {
somecode2;
label2:
somecode3;
} while expr2;
Для реализации goto под expr1 необходим блок if, который бы "пронзал" собой блок while, а сделать это невозможно синтаксически. Если мы разорвем цикл while, то у нас без goto опять же никаким образом не получится возврат к коду somecode2.
Конечно, можно много чего придумать. Например, каждый блок снабдить меткой и указывать ее с оператором continue. Извратиться с try b catch. Это решит проблему, но ИМХО читаемости коду не прибавит - уж лучше goto. Если приведенный мной выше пример сделать помасштабнее, добавив большее количество условных переходов и меток, то какой бы структурированный синтаксис мы не придумали, получится очень большой уровень вложенности, что не хорошо.
Есть ли полезные алгоритмы, где такие перекрестные goto используются? Не знаю. Но думаю, что даже если сегодня их нет, то они могут появиться в любой день в будущем. Главное наличие принципиальной возможности создания кода, реализуемого только на goto.
К тому же с точки зрения математического исследования алгоритмов goto - единственно возможный вариант для представления кода в виде графа. Если рассмотреть гипотетическую возможность автоматического создания алгоритмов с помощью ИИ (читайте про автоматическое доказательство теорем), то мы можем получать серьезные полезные алгоритмы, изначально использующие goto и не всегда понятно каким образом и почему работающие. Специально приводить их к синтаксису if/while не будет никакого смысла.
-------------------
[UPD]: В общем, я сглупил, ламо. Все что написано выше не считается =)
Пример кода выше можно реализовать на простых if/while так:
if (expr1) {
somecode1;
somecode2;
}
somecode3;
while (expr2) {
somecode2;
comecode3;
}
Я как-то изначально о таком ходе не подумал, хотя самому достаточно регулярно приходится писать такой код. Однако это никак не оправдывает общественную неприязнь к goto. Я настаиваю на том, что код на goto в самом начале поста куда более легко читаем и при этом более компактен. Более того, в ряде случаев интуитивные рассуждения приводят именно к коду с goto, а не к структурированному коду. Думаю, такие задачи каждому здесь попадались.
В общем из примера выше понятно, что без goto все же можно обойтись в любом случае, и алгоритма, не реализуемого без него не существует. Однако в случае таких перекрестных переходов может потребоваться либо слишком заумный синтаксис, либо слишком много кода потребуется дублировать (в простейшем случае выше объем кода увеличился в два раза, если пример будет несколько более сложным, потери могут быть еще больше).
По поводу общественной неприязни.13.08.07 17:49 Автор: Fighter <Vladimir> Статус: Elderman
Все, что было после слова "общественная" мне очень сильно напомнила один спор на 1-м курсе. Одна девушка, с пеной у рта, доказывала что в районе 15-17 вв. жизнь была просто восхитительна. Аргументы типа "канализациии не было, все воняли, стоматологов,терапевтов и кардиологов не было и т.д." на нее не действовали. У нее были несколько "весомых" контраргументов: "Зато были лошади, красивые одежды и не было нитратов". Так и здесь: достаточно посмотреть на (хотя бы) 5-и метрвый листинг на басике или асме испещеренный переходами (особенно безусловными), после этого вимательно почитать основные принципы структурного программирования и все желание вести религиозные войны пропадет.
Дейкстра и иже с ним придумали все не от лоховства, а просто от тоски и безысходности :)
Так я ж не говорю, что структурное программирование плохо13.08.07 18:14 Автор: Heller <Heller> Статус: Elderman Отредактировано 13.08.07 18:16 Количество правок: 1
Я ведь не только структурное, я еще даже и ООП люблю. Совсем другое дело, когда в учебниках предлагается не использовать goto ВООБЩЕ. Вот этого я не понимаю. По-моему вполне достаточно выдать основные рекомендации вроде того чтобы люди не скакали внутрь внешних циклов и по сторонним функциям. Ну и рекомендации вроде тех, что риводил ниже amirul. А отказываться от goto смысла не вижу.
Здесь опять же как в твоем споре с той одногруппницей. Конечно же правда на твоей стороне. Но никто не мешает носить красивые платья и ездить на лошадях и в современном мире. Это не значит, что надо отказываться от достижений науки. В случае же с goto картина противоположная - достижения науки есть, и они замечательны, но зачем отказываться от простого goto? Объективных причин я на то не вижу.
+1. Я просто попытался про неприязнь объяснить.13.08.07 18:20 Автор: Fighter <Vladimir> Статус: Elderman
> Я ведь не только структурное, я еще даже и ООП люблю. > Совсем другое дело, когда в учебниках предлагается не > использовать goto ВООБЩЕ. Вот этого я не понимаю. По-моему Когда "ВООБЩЕ" - это уже фанатизьм :) См. ниже высказывания HandleX'а - наш человек.
> вполне достаточно выдать основные рекомендации вроде того > чтобы люди не скакали внутрь внешних циклов и по сторонним > функциям. Ну и рекомендации вроде тех, что риводил ниже > amirul. А отказываться от goto смысла не вижу. > > Здесь опять же как в твоем споре с той одногруппницей. > Конечно же правда на твоей стороне. Но никто не мешает > носить красивые платья и ездить на лошадях и в современном > мире. Это не значит, что надо отказываться от достижений > науки. В случае же с goto картина противоположная - > достижения науки есть, и они замечательны, но зачем > отказываться от простого goto? Объективных причин я на то > не вижу.
ну флажком-то это лечится на раз13.08.07 17:02 Автор: dl <Dmitry Leonov>
> или уносом somecode2 в отдельную функцию (вроде должно > хватить) Вчера, говорят, были метеоритные дожди - видимо, на мне сказывается :)
Насчет выноса в отдельную функцию как-то пока не сообразил. С флажком вариант, как я понимаю, имеется ввиду такой:
flag=0;
if (expr1) {
flag = 1;
somecode1;
}
do {
if (flag == 1) flag = 0;
else somecode2;
somecode3;
} while (expr2)
---
Тоже, конечно, вариант. Но читаемости как по мне не добавляет. К тому же схема, которую я привел, относительно распространена, но решение достаточно легко находится только когда мы мыслим абстрактными somecode. На практике же мы в мозгах будем держать конкретный физический смысл этих goto и додуматься до такого изврата будет уже сложнее. Ну а скажем большинству вупускников тех. ВУЗов так и вообще не по силам. В данном случае goto видится мне вполне оправданным.
я имел в виду примерно то же, что в исправленном примере13.08.07 18:45 Автор: dl <Dmitry Leonov>
Просто с оформлением повторного кода в отдельной функции или макросе - в последнем случае на выходе оптимизирующего компилятора есть шанс получить код, аналогичный gotoшному.
Оффтоп. Дождь был метеорный :)13.08.07 17:56 Автор: Fighter <Vladimir> Статус: Elderman Отредактировано 13.08.07 18:16 Количество правок: 1