Полная версия этой страницы:
Оператор GoTo
Почему считается, что "нехорошо" использовать данного оператора?
Yura_K
Sep 29 2006, 16:02
Как я понимаю, этот оператор неявно присутствует в основных конструкциях структурированных языков. Цикл то не организовать без goto

. Хотя, например, в C оператор goto присутствует, просто им не рекомендуют пользоваться. Вообщем, все вопросы приходят к разговору о стиле, используемом при разработке ПО (структурированное, объектно-ориентированное программирование и т.д.).
Полностью согласен, взять ассемблер - циклов без меток и переходов не бывает. А ПОЧЕМУ в С не рекомендуют, или так сложилось, как байте восемь бит?
Это филосовский вопрос. И ответ на него будет: "В силу некоторых особенностей человеческого разума/мышления".
Пока сами не почувствуете, объяснить более подробно будет сложно.
rezident
Sep 29 2006, 16:47
Гм. Когда-то давно (больше 15 лет назад) у нас в универе был курс информатики, который включал в себя изучение языков BASIC и FORTRAN. Там без GOTO у меня как-то не получалось. Как-то совершенно естественно GOTO в структуру языка BASIC ложился. Я в общем и сейчас не профессионал в программировании. Уровень у меня скорее любительский. С языком СИ познакомился лет пять назад. Но ни разу за это время GOTO применять не приходилось и даже не возникало такой нужды. Видимо таковы особенности структуры именно этого языка программирования. ИМХО.
jorikdima
Sep 29 2006, 16:47
Я слышал, что причина в том, что не известно будет "откуда" ты пришел в эту часть программы. Ну то есть если есть метка и где то в другом коде 2 ГоТу, то если программа перепрыгнула на метку, нельзя будет сказать откуда именно
bodja74
Sep 29 2006, 16:56
Потому что оператор безусловного перехода не сохраняет адресс возврата в стеке,и если допустим
функция в Си физически выступает как подпрограмма ,переходить к ней по безусловному переходу
даже на асме крайне рискованое занятие ,так как в конце есть все шансы встретится с коммандой ret,
которая загрузит из стека адресс возврата неизвестно какого значения и прога уйдет в ступор.
ЗЫ Правила хорошего тона - это набитые шишки на ошибках,собственных или чужих.
CD_Eater
Sep 29 2006, 17:27
Программу проще понять, если она состоит из стандартных функциональных блоков: циклов While с пред или пост-условием, циклов с фиксированным числом повтора, вызовов подпрограмм с единственной точкой выхода (а не как в Си), и т.д.
Соблюдение правил хорошего тона облегчает другим людям (да и вам самому по истечении длительного интервала времени) понять вашу программу. Других причин вроде нет.
Соответственно, разные языки с разной степенью удобства позволяют эти правила хорошего тона использовать. В некоторых (напр., BASIC), использовать эти правила очень затруднительно, равно как затруднительно понимать программу на таком языке.
muravei
Sep 29 2006, 17:31
Цитата(CD_Eater @ Sep 29 2006, 21:27)

В некоторых (напр., BASIC), использовать эти правила очень затруднительно, равно как затруднительно понимать программу на таком языке.
Время от времени пописываю на Визуал Бэйсике, но ГОУ ТО ни разу не использовал.
artem100
Sep 29 2006, 17:51
go to
не явно присутствует во всех языках всегда
а идет это от гулявших ошибок перекрестных при применении нескольких go to на странице текста более чем 25 строк
конструкция
команда (условие){
что-то делать
}
логически читалась легче
в 1980-ых написаны книги по стилю написания и оформления кода
в 1988-мом Borland рекомендавал в TurboC2.0 постепенно переходить с goto на конструкции for, if и do ,а while еще не был придуман, try еще даже в мечтах не было
Borland извинялся за неоптимальность компилируемого двоичного кода с конструкцией goto
Вот с тех пор рекомендация на подсознательном уровне отложилась как правило для языков высокого уровня.
Жестко вроде нигде не запрещенно
Только рекомендации и извинения за возможные глюки
а кому глюки нужны
Тут бы быстрей как-то что-то
Так что пиши как хочешь и где хочешь, а возможные глюки в самых древних из самых древних библиотек на твоей совести будут

пожелтевшие бумажные 700 листов Borland-овского Help-а еще где-то лежат
но копаться и и цитировать лень
могу только полку показать Im sorry
singlskv
Sep 29 2006, 18:05
Цитата
Почему считается, что "нехорошо" использовать данного оператора?
Цитата из Бьерн Страуструп "Язык программирования С++" (типа один из разработчиков С++):
3.3.2 Оператор goto
Презираемый оператор goto все-таки есть в С++:
goto идентификатор;
идентификатор: оператор
Вообще говоря, он мало используется в языках высокого уровня, но
может быть очень полезен, если текст на С++ создается не человеком,
а автоматически, т.е. с помощью программы. Например,
операторы goto используются при создании анализатора по заданной
грамматике языка с помощью программных средств.
Кроме того, операторы goto могут пригодиться в тех случаях,
когда на первый план выходит скорость работы программы. Один из
них - когда в реальном времени происходят какие-то вычисления во
внутреннем цикле программы.
Есть немногие ситуации и в обычных программах, когда применение
goto оправдано. Одна из них - выход из вложенного цикла или
переключателя. Дело в том, что оператор break во вложенных циклах
или переключателях позволяет перейти только на один уровень выше.Цитата(bodja74 @ Sep 29 2006, 20:56)

Потому что оператор безусловного перехода не сохраняет адресс возврата в стеке,и если допустим
функция в Си физически выступает как подпрограмма ,переходить к ней по безусловному переходу
даже на асме крайне рискованое занятие ,так как в конце есть все шансы встретится с коммандой ret,
которая загрузит из стека адресс возврата неизвестно какого значения и прога уйдет в ступор.
Исчо критика

простите, если сможете
В С/С++ goto не работает за пределами функции, так что проблем со стеком и с возвратом
по ret никогда не может возникнуть, единственная проблемма возникающия со стеком при
использовании goto заключается в следующем:
Код
for (i=0;i<10;i++)
{
char ar[1000];
if (i==5) goto label1;
}
label1:
память занимаемая массивом ar[1000] будет возвращена системе только после выхода за
следующий блок { ... }
У Microsoft специально для этих целей вместо goto используется структурная
обработка ошибок (не только для этих целей):
__try {
......
if(...) __leave;
......
}
__finally {
......
}
которая корректно умеет обрабатывать стек.
НО, если Вы поизучаете код который пишет Microsoft, то например
в MFC Вы обнаружите более 70 файлов в которых используется оператор goto
singlskv
Sep 29 2006, 18:39
Цитата(J_B @ Sep 29 2006, 19:13)

Почему считается, что "нехорошо" использовать данного оператора?
Да, забыл добавить:
Лично я считаю применение goto крайним случаем.
Иногда для скорости, а иногда чтобы не писать странные конструкции
которые позволят избежать использования goto.
Леонид Иванович
Sep 29 2006, 19:09
Единственная ситуация, когда нужен goto, это обработка ошибок. Но в C++ для этого придуманы исключения, которые позволяют обработать ошибки более изящно.
bodja74
Sep 29 2006, 20:32
Цитата(singlskv @ Sep 29 2006, 21:05)

[Исчо критика

простите, если сможете

Без проблем,у меня корона из головы не упадет.

Соглашусь со всем так как в Си не силен.
Но позвольте высказать свое ИМХО.

Какие операторы не писали и какие бы скобки не ставили,в конечном итоге все сводится к трем елементарным инструкциям переходов - условный,безусловный и переход на подпрограмму
(то есть опять же асм ,так как МК физически еще не научился понимать Си).
Тоесть как будут откомпелированы команды на Си в элементарные команды и будут ли они допущены вообще - это зависит
от интелекта компиллера Си ,а не от самого языка.
Для ПК я пишу на VB6 ,там также с помощью GOTO из функции или подпрограммы не выпрыгнеш и не запрыгнеш ,так как метки для них локальны,но это не значит что на старом и добром TB под ДОС
этого нельзя было делать.
ЗЫ Если кому хочется побольше увидеть команд Jmp под Win (тот же GOTO) - дизасемблируйте прогу,
их количество вас приятно удивит.

ЗЫЫ Раскажите чайнику для чего нужен MFC?
Как то был интерес поизучать,зашел в книжный,как увидел габариты этого толмута,так сразу перехотелось,я на полном серьезе - этой книжицей с одного удара по голове можно убить человека.
И перехотелось не потому ,что представил ,как буду долго и нудно ее изучать,а потому что представил,если разгорится спор,как моя жонка будет гонятся с этим толмутом за мной по квартире.
Сергей Борщ
Sep 29 2006, 21:57
Цитата(bodja74 @ Sep 29 2006, 23:32)

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

Фигня. Задача решаема. На вопрос "что бы подарить мне на день Варенья" жена получила ответ "Трехтомник Кнута". Ничего, сижу, читаю. Жив :-) В смысле - это жена у меня спрашивала насчет подарка.
_artem_
Sep 29 2006, 22:40
Сколько людей столько и мнений. Если не злоупотреблять, то goto иногда более удобный вариант чем циклы и свитчи с continue и break'ами (imho).
Есть еще другая истина в последней инстанции - файл должен помешаться на одну страницу текста - то есть полностью отображаться на экране дисплея . Так нет у некоторых на файл приходится по сотне килобайтов. Kрайности.
Конечно же никто не заставляет писать спагетти код и так же никто не может утверждать что тот кто использует goto пишет макаронные сурцы.
По моему, это больше напоминает реакцию некоих фундаментально настроенных обьектнооргазируемых эстетов на творения безразборчивых в средствах начинающих.
Была какая то статья, с которой весь этот садомазоэстетический спор в мире програмистов начался, не помню только ее название.
Скажу так - каждый прав по своему)
Спасибо высказавшимся, просто написал переход от двоичной в двоично-десятичную (для семисегментников), и вспомнил про гоуту...
zltigo
Sep 30 2006, 06:10
Цитата(_artem_ @ Sep 30 2006, 01:40)

Была какая то статья, с которой весь этот садомазоэстетический спор в мире програмистов начался, не помню только ее название.
Началась это на моей памяти Виртом с обоснования теоретической базы "Паскаля" как попытки создать язык идеальный для толкования компилятором ну априори предполагаемый "удобным" для пользователя ввиду его однозначности. Для компилятора, спору нет, goto в большинстве случаев - проблема, ибо начисто ломает его все стандартные "домашние заготовки". Соответственно простые компиляторы давних времен генерили весьма поганый код. Компиляторы поумнели и стали нормально понимать удобные человеку конструкции, идеалисты от компиляции продолжают движение и дошли до "Оберона".
На сегодняшний день причин не использовать в "C" goto в удобном месте нет.
Цитата(zltigo @ Sep 30 2006, 10:10)

На сегодняшний день причин не использовать в "C" goto в удобном месте нет.
Хм.... Причина есть! И на сегодняшний день она ещё более актуальна! Дело в том, что сейчас серьёзный проект можно написать только работая в команде разработчиков. И для того, что бы в твоём коде можно было разобраться другому человеку, надо писать по общепринятым "правилам хорошего тона". Одним из правил является форматирование отступами вложенного кода (например тело цикла, условия - так проще найти глазами конец цикла и условия и т.д.). С использованием Goto такое форматирование осуществить в общем случае невозможно, что приводит полному мясу кода, который спустя некоторое время не только сторонний человек понять не сможет, но и даже сам разработчик. А компиляторы тут ни при чём, сейчас они умные. ИМХО любой логичный алгоритм можно изящно записать без Goto. Это как "любую мысль можно передать без мата".
zltigo
Sep 30 2006, 10:04
Цитата(Petka @ Sep 30 2006, 12:43)

С использованием Goto такое форматирование осуществить в общем случае невозможно, что приводит полному мясу кода, который спустя некоторое время не только сторонний человек понять не сможет, но и даже сам разработчик.
Если выражаться коротко, то это бред.
Цитата
ИМХО любой логичный алгоритм можно изящно записать без Goto.
Это как "любую мысль можно передать без мата".
Можно все, но не изящно. Ибо понятие изящно применимо к более-менее искуственно замкнутым системам. Там где на систему плотно влияют внешние непреодолимые обстоятельства там и требуются якобы "неизящные" выходы и не самые исключения, которые подтверждают правила. Причем попав в такую ситуацию я предпочитаю четко и ясно выразить свлю мысль, например словом "пи....ц", поятным каждому нормальному человеку а не "изящно" и муторно с жевать сопли для "литературной" передачи
мысли.
CD_Eater
Sep 30 2006, 12:20
Цитата(zltigo @ Sep 30 2006, 14:04)

Цитата(Petka @ Sep 30 2006, 12:43)

С использованием Goto такое форматирование осуществить в общем случае невозможно, что приводит полному мясу кода, который спустя некоторое время не только сторонний человек понять не сможет, но и даже сам разработчик.
Если выражаться коротко, то это бред.
А если не коротко ? Пока не видно Ваших аргументов. Ждём примера кода, который без GOTO хуже, нежели с GOTO.
imho, максимум, что может дать GOTO - это сократить код на 2-3 строки в ущерб читабельности программы.
Цитата(zltigo @ Sep 30 2006, 14:04)

Цитата
Это как "любую мысль можно передать без мата".
Причем попав в такую ситуацию я предпочитаю четко и ясно выразить свлю мысль, например словом "пи....ц"
Не уподобляйтесь тем, у кого "косноязычие компенсируется скудоумием". Поверьте - русский язык велик и могуч. Хотя в Ваших краях, наверное, с его изучением туговато.
goodwin
Sep 30 2006, 12:41
Совсем недавно была дискуссия на телесистемах по поводу возвращения к началу обработки из нескольких вложенных циклов в подпрограмме. Всякие флаги, исключения - вот где настоящий изврат, по сравнеию с goto...
zltigo
Sep 30 2006, 12:52
Цитата(CD_Eater @ Sep 30 2006, 15:20)

А если не коротко ?
А не коротко, по поводу отцитированного ничего и не скажешь :-(.
Цитата
Хотя в Ваших краях, наверное, с его изучением туговато.
Тем не менее, я полагаю, что достаточно хорошо им (как в прочем и "C" ) владею и вполне внятно выразил причины использования и присутствия goto во всех реальных языках программирования не смотря на многодесятилетние теоретические размышления о "вреде", "возможности обойтись" и мифической "читабельности".
Цитата
Поверьте - русский язык велик и могуч.
И делает его
могучим именно присутствие элементов
живого языка, таких как обсуждаемый здесь goto, и выгодно отличает его от "легко читаемых" с выброшенными "ненужностями" искусственных языков, типа Эсперанто.
Особо переделкой без goto не занимался, но кто что скажет:
VAL=0;
X=100;
foR(I=0;I<=2;I++)
{
LABEL:
TMP_P=TMP;
TMP=TMP-X;
if(TMP<0)
{
SEG[i]=VAL;
VAL=0;
TMP=TMP_P;
X=X/10;
}
else
{
VAL=VAL++;
goto LABEL;
}
}
Смысл таков:
есть заранее неизвестное значение (16р) в диапазоне 0-999 - TMP.
Вывод на тройной индикатор SEG0-2. Идея:" Способ преобразования заключается в том, чтобы, вычитая из исходного числа число 100, сначала определить десятичную цифру десятков сотен. Затем находится цифра десятков последовательным вычитанием числа 10 и т. д. Вычитание каждый раз производится до получения отрицательной разности с подсчетом числа вычитаний. При переходе к определению каждого следующего десятичного разряда в регистрах исходного числа восстанавливается последняя положительная разность"
Цитата(zltigo @ Sep 30 2006, 14:04)

Цитата(Petka @ Sep 30 2006, 12:43)

С использованием Goto такое форматирование осуществить в общем случае невозможно, что приводит полному мясу кода, который спустя некоторое время не только сторонний человек понять не сможет, но и даже сам разработчик.
Если выражаться коротко, то это бред.
Аргументы?
В электронику я перешёл из "программистов". Могу позволить себе утверждать, что Вы не до конца освоили работу в команде, как и отличие языков высокого уровня от низкого. Недавно в форуме пробегала ссылка на "косметику для программистов". Советую ознакомится.
zltigo
Sep 30 2006, 14:56
Цитата(J_B @ Sep 30 2006, 17:27)

Смысл таков:
Если не касаться прочих многочисленных, назовем - странностей, то
просто вообще уберите две строки
label:
и
goto label;
и добавьте цикл с break;
Если зачем-то кто-то пишет такое, то я начинаю понимать
Petka :-)
zltigo
Sep 30 2006, 15:07
Цитата(Petka @ Sep 30 2006, 17:40)

Аргументы?
Попробуйте преречитать написанное Вами:
Цитата
Одним из правил является форматирование отступами вложенного кода (например тело цикла, условия - так проще найти глазами конец цикла и условия и т.д.). С использованием Goto такое форматирование осуществить в общем случае невозможно....
Я искренне не понимаю какие аргументы от меня требуются :-((((
Цитата(J_B @ Sep 30 2006, 18:27)

Особо переделкой без goto не занимался, но кто что скажет:
Код
VAL=0;
X=100;
for(I=0;I<=2;I++)
{
LABEL:
TMP_P=TMP;
TMP=TMP-X;
if(TMP<0)
{
SEG[i]=VAL;
VAL=0;
TMP=TMP_P;
X=X/10;
}
else
{
VAL=VAL++;
goto LABEL;
}
}
Смысл таков:
есть заранее неизвестное значение (16р) в диапазоне 0-999 - TMP.
Вывод на тройной индикатор SEG0-2. Идея:" Способ преобразования заключается в том, чтобы, вычитая из исходного числа число 100, сначала определить десятичную цифру десятков сотен. Затем находится цифра десятков последовательным вычитанием числа 10 и т. д. Вычитание каждый раз производится до получения отрицательной разности с подсчетом числа вычитаний. При переходе к определению каждого следующего десятичного разряда в регистрах исходного числа восстанавливается последняя положительная разность"
Скажу только, что
Код
goto LABEL;
здесь абсолютно бессмысленен, т.к. точно такой же по смыслу переход уже присутствует в силу организации цикла.
По сути программы: если Вы хотели уйти от деления, Вам это таки не удалось.
Сделайте хотя бы так:
Код
if(TMP<0)
{
SEG[i]=VAL;
VAL=0;
TMP=TMP_P;
if(X==100) X=10;
else if(X==10) X=1;
else break;
}
А еще проще посмотреть сорцы для BCD преобразования.
Бр-р-р. Не посмотрел на уловия цикла. Здесь и goto не поможет

.
zltigo
Sep 30 2006, 15:55
Код
seg[0] = tmp/100;
seg[2] = tmp%10; tmp /= 10;
seg[1] = tmp%10;
Цитата(zltigo @ Sep 30 2006, 19:55)

Код
seg[0] = tmp/100;
seg[2] = tmp%10; tmp /= 10;
seg[1] = tmp%10;
Ну так не интересно

. Без выподвывертов-то

.
prottoss
Sep 30 2006, 16:08
Выскажусь тоже про goto... так как несколько раз приходилось применять его в проектах на Си под х86 и AVR. Использовал его в вот в таком частном случае:
Код
// Глобальная переменная, изменяемая сторонним потоком
g_Value;
// Главный цикл
for(char x = 0; x < 100; x++)
{
выполняем полезную работу
......................
еще один цикл
for(char y = 0; y < 200; y++)
{
выполняем еще одну полезную работу
.....................
и еще один цикл
for(char i = 0; i < 300; i++)
{
// проверяем глобальную переменную
if(KILL_ALL_CYCLES == g_Value)
{
goto down;
}
else
{
выполняем еще одну полезную работу
}
}
}
}
down:
// едем дальше
_artem_
Sep 30 2006, 17:08
Я использую goto, но это не тот случай. Не проверял на ошибки - проверьте все ли там холосо):
Код
for(I=0;I<=2;I++)
{
LABEL:
TMP_P=TMP;
TMP=TMP-X;
if(TMP<0)
{
SEG[i]=VAL;
VAL=0;
TMP=TMP_P;
X=X/10;
}
else
{
VAL=VAL++;
goto LABEL;
}
}
for(I=0;;)
{
TMP_P=TMP;
TMP=TMP-X;
if(TMP<0)
{
SEG[i]=VAL;
VAL=0;
TMP=TMP_P;
X=X/10;
if(++I > 2)
break;
}
else
VAL=VAL++;
}
2 artem_ Вы про цикл с постусловием do while слышали?В вашем случае goto абсолютно ни к селу
ни к городу.
_artem_
Sep 30 2006, 19:55
WHALE, во первых я не из пешеры), во вторых это не мой случай а xemul'a,) в третьих я против использования
goto в этом примере) в четвертых был бы рад если Вы показали Ваш собственный вариант этой функции с использованием конструкции do/while.
for(I=0;I<=2;I++)
{
do{
TMP_P=TMP;
TMP=TMP-X;
if(TMP>=0) ++VAL;
}
while(TMP>=0)
SEG[i]=VAL;
VAL=0;
TMP=TMP_P;
X=X/10;
}
_artem_Извиняюсь,погорячился,тоже кривовато получается,но все-таки можно и без GOTO

Еще раз извиняюсь,прочел предыдущую страницу,это все вообще не из той оперы.
_artem_
Sep 30 2006, 22:17
Да никаких извинений не нужно, не обиделся.) Я сам грешу этим довольно таки часто.
Удачи.
Господа, о чем речь? Посмотрите в исходники библиотеки - функция printf, а точнее _formatted_write - там с goto все в порядке - в смысле - дофига
Мне кажется, что "ноги растут" от старинного труда Дейкстры"Структурное программирование".
В нем как раз обосновывались принципы написания кода, которые, в теории, должны были
уменьшить количество ошибок и облегчить жизнь программистам.
В том числе там рекомендовались и разбиение на куски ( процедуры ) размером не более экрана-двух,
стиль "программирование сверху-вниз" и "снизу-вверх", и т.д.
Оператор GOTO и попал там в опалу, поскольку нарушал стройность и красивость....
А по делу - пишите - как удобнее, только комментариев побольше.....
_artem_
Oct 1 2006, 15:39
Вы правы -
http://en.wikipedia.org/wiki/GOTOНо что интересно:
"there are some tasks that cannot be straightforwardly accomplished in many programming languages without the use of GOTO statements, such as breaking out of nested loops and exception handling."
и имхо это действительно так.
Цитата(J_B @ Sep 29 2006, 18:13)

Почему считается, что "нехорошо" использовать данного оператора?
Дурным тоном в программировании является не само использование оператора goto, а его
частое и неоправданное использование. В таких случаях программа получается запутанной и трудной для понимания, а, стало быть, для отладки или соправождения. Современные языки программирования (Си в том числе) имеют управляющие конструкции, позволяющие в принципе обходится без goto. Однако в ряде случаев использование goto позволяет сделать программу более понятной. Речь идет о тех случаях, когда необходимо сделать выход из вложенных циклов. В таких случаях оператор goto позволяет исключить введение множества флагов, используемых для проверки условия принудительного выхода из циклов. При этом программа получается не только более наглядной, но и более эффективной.
Основное правило использования goto - переход только вперед. Если goto используется для перехода назад, то это означает, что необходимо воспользоваться каким-либо оператором цикла и/или оператором принудительного перехода к очередной итерации цикла - continue.
А вообще, непонятную и нечитаемую программу можно легко написать и не используя оператор goto. Это часто происходит потому, что человек еще не совсем представляет что именно ему нужно. Поэтому, прежде чем писать код, лучше сначала продумать структуру программы. Методы структурного программирования известны не один десяток лет. В современных языках программирования имеются все необходимые конструкции для создания структурированных программ: последовательно исполняемые операторы (простые и составные), операторы ветвления (if, if...else, switch (case), goto), цикла (while, do...while, for).
Мои размышления о "косметики" программ можно найти
здесь.
Что касается AVR и goto, то при использовании оптимизации кода по размеру, этот оператор опасно использовать. При использавании Cross Call могут действительно возникнуть проблемы со стеком. Так что лучше не рисковать! Можно просто поэкпериментировать, компилируя программу с разными настройками оптимизации - хороший код должен работать в любом случае.
Цитата(AVNN @ Oct 2 2006, 11:22)

Что касается AVR и goto, то при использовании оптимизации кода по размеру, этот оператор опасно использовать. При использавании Cross Call могут действительно возникнуть проблемы со стеком. Так что лучше не рисковать! Можно просто поэкпериментировать, компилируя программу с разными настройками оптимизации - хороший код должен работать в любом случае.
А какие тут могут бть проблемы?
defunct
Oct 2 2006, 10:12
Всякий овощ полезен будучи приготовленным надлежащим образом. ©
ValBag
Oct 24 2007, 06:19
Во всех наставлениях по СИ для МК "...настоятельно не рекомендуется использовать оператор безусловного перехода goto, т.к. он затрудняет понимание программ и возможность их модификаций...". В то же время другими операторами СИ не всегда удобно осуществлять переходы, а в ассемблере применение команд jmp и rjmp ограничений почти нет.
Для примера в программе "кодовый замок" из книги Белова А.В., в небольшом тексте программы на CИ в модуле main 7 переходов. И все работает нормально. Может быть, кто то потвердит вводное утверждение и покажет как надо на приложенном тексте.
bodja74
Oct 24 2007, 06:40
В ассемблере вообще ни в чем ограничений нет
Просто для себя нужно уяснить простую вещь,если вы перейдете на подпрограмму по jmp или rjmp
(тот же GOTO) ,вы из нее уже не вернетесь
Чисто в лоб типа такого
Код
while (1)
{
do
{
while (incod() != klfree); // Ожидание отпускания кнопок
while (incod() == klfree); // Ожидание нажатия кнопок
ii=0;
do
{
#asm("cli"); // Запрещаем прерывания
wait(1); // Задержка 1-го типа
codS=incod(); // Ввод кода и запись, как старого
bufr[ii++]=codS; // Запись очередного кода в буфер
if (ii>=bsize) break; // Проверка конца буфера
wait(2); // Задержка 2-го типа
do
{
if (incod() != codS) break; // Проверка не изменилось ли состояние
} while((flz==0)); // Проверка окончания контрольного промежутка времени
}
while(1);
if (PINB.7==1)
{
if (klen!=ii) continue; // Проверка длины кода
}
//------------------------------ Запись кода в EEPROM
klen=ii; // Запись длины кода
for (i=0; i<ii; i++)
bufe[i]=bufr[i]; // Запись всех байтов кода
break;
//------------------------------ Проверка кода
if (klen!=ii) continue; // Проверка длины кода
for (i=0; i<ii; i++)
if (bufe[i]!=bufr[i]) continue; // Проверка самого кода
break;
//------------------------------ Открывание замка
}
while(1);
PORTB.4=1; // Открываем замок
wait(3); // Задержка 3-го типа
PORTB.4=0; // Закрываем замок
};
Может есть ошибки, да и упростить можно, но суть та же goto нафик не нужен
При чем тут AVR кстати ?
Цитата(ValBag @ Oct 24 2007, 10:19)

В то же время другими операторами СИ не всегда удобно осуществлять переходы
Кто такое сказал, автор или Вы?
goto реально упрощает обработку чего-то экстраординарного, но для этого лучше применть блоки try catch в С++
alexander55
Oct 24 2007, 07:01
Цитата(ValBag @ Oct 24 2007, 10:19)

goto считаю атавизмом и С не использую, т.к. потребности никогда не возникает (а в Basic использовал).
Ну результат почти такой же. В текущем примере из-за goto тяжело понять логику, поэтому пришлось импровизировать. Пример можно еще оптимизировать.
А вообще-то стиль написания напомнил asm. Видимо человек до этого долго писал на нем, отсюда логика построения функции.
А в бейсике без него сильно не поработаешь :-)
Цитата(ValBag @ Oct 24 2007, 13:19)

Во всех наставлениях по СИ для МК "...настоятельно не рекомендуется использовать оператор безусловного перехода goto, т.к. он затрудняет понимание программ и возможность их модификаций...". В то же время другими операторами СИ не всегда удобно осуществлять переходы, а в ассемблере применение команд jmp и rjmp ограничений почти нет.
Существует очень мало ситуаций, где этот оператор действительно необходим. В ~90% случаев это
выход из вложенных циклов. Собсно, для этого оператор и оставили в языке. При всяком его применении нужно минимум дважды задуматься, действительно ли он тут необходим или задача может быть решена другими средствами. И уж злоупотребление (т.е. применение где ни попадя) им во всяком случае должно быть предотвращено.
P.S. Вообще-то, это вопрос для FAQ, его постоянно задают начинающие.

И частенко обсуждения достоинств и недостатков этого оператора приводят к "религиозным" войнам, по какой причине в некоторых местах (например, в фидо-эхе su.c-cpp) обсуждение оператора
goto объявлено офтопиком и преследуется модератором по закону.
zltigo
Oct 24 2007, 07:19
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.