Перейти
Goto ( goto , GOTO , GO TO , GoTo или другие комбинации регистров, в зависимости от языка программирования) — это оператор , встречающийся во многих языках программирования . Он выполняет одностороннюю передачу управления другой строке кода; напротив, вызов функции обычно возвращает управление. Места перехода обычно обозначаются с помощью меток , хотя в некоторых языках используются номера строк . На машинного кода уровне goto
— это форма оператора ветвления или перехода , в некоторых случаях сочетающаяся с корректировкой стека. Многие языки поддерживают goto
утверждение, а многие этого не делают (см. § языковая поддержка ).
Теорема о структурированной программе доказала, что goto
оператор не является необходимым для написания программ, которые можно выразить в виде блок-схем ; некоторая комбинация трех программных конструкций: последовательность, выбор/повторение/итерация достаточна для любых вычислений, которые может выполнить машина Тьюринга , с оговоркой, что дублирования кода и дополнительных переменных. может потребоваться введение [1]
Раньше использование goto было обычным явлением, но с появлением структурного программирования в 1960-х и 1970-х годах его использование значительно сократилось. Он по-прежнему используется в некоторых распространенных шаблонах использования , но альтернативы обычно используются , если они доступны. В прошлом в академических кругах и промышленности велись серьезные дебаты по поводу преимуществ использования операторов goto. Основная критика заключается в том, что код, использующий операторы goto, труднее понять, чем альтернативные конструкции. Дебаты по поводу его (более ограниченного) использования продолжаются в академических кругах и индустрии программного обеспечения.
Использование
[ редактировать ]goto label
The goto
Оператор часто сочетается с оператором if, чтобы вызвать условную передачу управления.
IF condition THEN goto label
Языки программирования накладывают различные ограничения в отношении места назначения. goto
заявление. Например, язык программирования C не допускает перехода к метке, содержащейся внутри другой функции. [2] однако переходы внутри одной цепочки вызовов возможны с использованием функций setjmp/longjmp .
Критика
[ редактировать ]На встрече , посвященной разработке Алгола, состоявшейся в 1959 году, Хайнц Земанек явно поставил под сомнение необходимость операторов GOTO; в то время никто [ нужна ссылка ] На его замечание обратил внимание, в том числе, Эдсгер В. Дейкстра , который впоследствии стал знаковым противником GOTO. [3] В 1970-х и 1980-х годах использование операторов GOTO снизилось в пользу структурированного программирования парадигмы , причем GOTO критиковали за то, что он ведет к созданию неподдерживаемого спагетти-кода . Некоторые стандарты кодирования стилей программирования , например стандарты кодирования GNU Pascal, не рекомендуют использовать операторы GOTO. [4] Доказательство Бема-Якопини (1966) не решило вопрос о том, следует ли применять структурное программирование для разработки программного обеспечения, отчасти потому, что такая конструкция скорее затеняла программу, чем улучшала ее, поскольку ее применение требует введения дополнительных локальных переменных. [5] Однако это вызвало бурные дебаты среди ученых-компьютерщиков, преподавателей, разработчиков языков и программистов приложений, которые стали свидетелями медленного, но неуклонного отхода от ранее повсеместного использования GOTO. Вероятно, самой известной критикой GOTO является письмо Эдсгера Дейкстры от 1968 года под названием « Заявление о переходе считается вредным ». [3] В этом письме Дейкстра утверждал, что неограниченные операторы GOTO должны быть отменены из языков более высокого уровня, поскольку они усложняют задачу анализа и проверки правильности программ (особенно тех, которые включают циклы). [6] Само письмо вызвало дебаты, в том числе письмо «ПЕРЕЙДИТЕ, считается вредным», считается вредным. [7] отправлено в Коммуникации ACM ( CACM) в марте 1987 года, а также дальнейшие ответы других людей, в том числе « О несколько разочаровывающей переписке» Дейкстры . [8]
Альтернативная точка зрения представлена в книге Дональда Кнута « Структурное программирование с переходом к операторам» , в которой анализируются многие распространенные задачи программирования и обнаруживается, что в некоторых из них GOTO является оптимальной языковой конструкцией для использования. [9] В книге «Язык программирования C» Брайан Керниган и Деннис Ритчи предупреждают, что goto
является «бесконечно злоупотребляемым», но также предполагают, что его можно использовать для обработчиков ошибок конца функции и для многоуровневых выходов из циклов. [10] Эти два шаблона можно найти во многих последующих книгах других авторов по C; [11] [12]
[13] [14] во вводном учебнике 2007 года отмечается, что шаблон обработки ошибок — это способ обойти «отсутствие встроенной обработки исключений в языке C». [11] Другие программисты, в том числе Linux разработчик ядра и программист Линус Торвальдс или инженер-программист и автор книги Стив МакКоннелл , также возражают против точки зрения Дейкстры, заявляя, что GOTO могут быть полезной функцией языка, улучшающей скорость программы, размер и ясность кода, но только тогда, когда разумно используется сравнительно разумным программистом. [15] [16] По словам профессора информатики Джона Регера , в 2013 году в коде ядра Linux было около 100 000 экземпляров goto. [17]
Другие ученые придерживались более радикальной точки зрения и утверждали, что даже такие инструкции, как break
и return
из середины циклов является плохой практикой, поскольку они не нужны в результате Бема-Якопини, и поэтому они выступали за то, чтобы циклы имели единственную точку выхода. [18] Например, Бертран Мейер написал в своем учебнике 2009 года, что такие инструкции, как break
и continue
"просто старые goto
в овечьей шкуре». [19] Однако слегка измененная форма результата Бема-Якопини позволяет избежать дополнительных переменных в структурном программировании, если разрешены многоуровневые выходы из циклов. [20] Поскольку некоторые языки, такие как C, не допускают многоуровневых разрывов через свои break
ключевое слово, некоторые учебники советуют программисту использовать goto
в таких обстоятельствах. [14] MISRA C 2004. Запреты стандарта goto
, continue
, а также несколько return
и break
заявления. [21] В выпуске стандарта MISRA C 2012 года запрет на goto
из статуса «обязательный» в статус «рекомендательный»; в издании 2012 года есть дополнительное обязательное правило, запрещающее прыжки только назад, но не вперед с goto
. [22] [23]
FORTRAN представил конструкции структурированного программирования в 1978 году, и в последующих версиях относительно свободные семантические правила, регулирующие допустимое использование goto, были ужесточены; «расширенный диапазон», в котором программист мог использовать GOTO для выхода и повторного входа в все еще выполняющийся цикл DO, был удален из языка в 1978 году, [24] а к 1995 году несколько форм GOTO на Фортране, включая вычисляемый GOTO и назначенный GOTO, были удалены. [25] В некоторых широко используемых современных языках программирования, таких как Java и Python, отсутствует оператор GOTO (см. языковую поддержку ), хотя большинство из них предоставляют некоторые средства выхода из выбора или выхода из него или перехода к следующему шагу итерации. Точку зрения, что нарушение потока управления в коде нежелательно, можно увидеть в конструкции некоторых языков программирования, например Ada. [26] визуально подчеркивает определения меток с помощью угловых скобок .
Запись 17.10 в списке часто задаваемых вопросов comp.lang.c [27] обращается к проблеме использования GOTO напрямую, заявляя
Стиль программирования, как и стиль письма, представляет собой своего рода искусство и не может быть систематизирован с помощью негибких правил, хотя дискуссии о стиле часто концентрируются исключительно вокруг таких правил. В случае с оператором goto уже давно замечено, что неограниченное использование оператора goto быстро приводит к неподдерживаемому спагетти-коду. Однако простой и бездумный запрет на оператор goto не обязательно сразу же приводит к красивому программированию: неструктурированный программист точно так же способен построить византийский клубок без использования каких-либо операторов перехода (возможно, заменив вместо этого нечетно вложенные циклы и логические управляющие переменные). . Многие программисты придерживаются умеренной позиции: операторов goto обычно следует избегать, но они приемлемы в некоторых строго ограниченных ситуациях, если это необходимо: в качестве многоуровневых операторов прерывания, для объединения общих действий внутри оператора переключателя или для централизации задач очистки в функция с несколькими возвратами ошибок. (...) Слепое избегание определенных конструкций или следование правилам без их понимания может привести к такому же количеству проблем, которые правила должны были предотвратить. Более того, многие мнения о стиле программирования — это всего лишь мнения. Они могут сильно аргументироваться и сильно ощущаться, они могут быть подкреплены кажущимися убедительными доказательствами и аргументами, но противоположные мнения могут так же сильно ощущаться, поддерживаться и аргументироваться. Обычно бесполезно втягиваться в «войны стилей», потому что по определенным вопросам оппоненты никогда не могут прийти к согласию, или согласиться не согласиться, или перестать спорить.
Общие шаблоны использования
[ редактировать ]Хотя общее использование goto сокращается, в некоторых языках все еще существуют ситуации, когда goto обеспечивает самый короткий и простой способ выразить логику программы (хотя ту же логику можно выразить и без переходов, эквивалентный код будет длиннее). и зачастую труднее понять). В других языках существуют структурированные альтернативы, в частности исключения и хвостовые вызовы.
Ситуации, в которых goto часто бывает полезен, включают:
- Чтобы сделать код более читабельным и простым для понимания [15] [28]
- Делать программы меньшего размера и избавиться от дублирования кода. [15] [28]
- Реализуйте конечный автомат , используя таблицу переходов состояний и goto для переключения между состояниями (при отсутствии устранения хвостового вызова ), особенно в автоматически генерируемом коде C. [29] Например, goto в каноническом парсере LR .
- Реализация многоуровневого разрыва и продолжения, если это не поддерживается напрямую в языке; это распространенная идиома в C. [14] Хотя в Java зарезервировано ключевое слово goto, на самом деле оно не реализовано. Вместо этого Java реализует помеченные операторы Break и помеченные операторы продолжения. [30] Согласно документации Java, использование переходов для многоуровневых разрывов было наиболее распространенным (90%) использованием переходов в C. [31] Java не был первым языком, применившим такой подход — запрещающий переход, но обеспечивающий многоуровневые разрывы — язык программирования BLISS (точнее, его версия BLISS-11) предшествовал ему в этом отношении. [32]
- Заменители одноуровневых операторов прерывания или продолжения (повторной попытки), когда потенциальное введение дополнительных циклов может неправильно повлиять на поток управления. Такая практика наблюдалась в коде Netbsd . [33]
- Обработка ошибок (при отсутствии исключений), особенно код очистки, например освобождение ресурсов. [11] [14] [33] [29] [34] C++ предлагает альтернативу оператору goto для этого варианта использования, а именно: инициализация сбора ресурсов (RAII) посредством использования деструкторов или использования исключений try и catch, используемых при обработке исключений . [35] setjmp и longjmp — еще одна альтернатива, преимуществом которой является возможность развернуть часть стека вызовов .
- Вставка стека, например, Algol, PL/I.
- Специализированные языки сценариев, работающие линейно, например диалоговая система для видеоигр. [36]
Такое использование относительно распространено в C, но гораздо реже в C++ или других языках с функциями более высокого уровня. [34] Однако в некоторых языках выдача и перехват исключения внутри функции может быть чрезвычайно неэффективным; Ярким примером является Objective-C , где goto — гораздо более быстрая альтернатива. [37]
Другим применением операторов перехода является модификация плохо факторизованного унаследованного кода , где отказ от перехода потребует обширного рефакторинга или дублирования кода . Например, для большой функции, где интерес представляет только определенный код, оператор goto позволяет перейти только к соответствующему коду или обратно, не изменяя функцию иным образом. Такое использование считается запахом кода . [38] но находит случайное применение.
Альтернативы
[ редактировать ]Структурированное программирование
[ редактировать ]Современное понятие подпрограммы было изобретено Дэвидом Уилером при программировании EDSAC . Для реализации вызова и возврата на машине без инструкции вызова подпрограммы он использовал специальный шаблон самомодифицирующегося кода, известный как прыжок Уиллера . [39] Это привело к возможности структурировать программы, используя хорошо вложенные выполнения подпрограмм, взятых из библиотеки. Это было бы невозможно, используя только goto
, поскольку целевой код, полученный из библиотеки, не будет знать, куда вернуться.
Позже языки высокого уровня, такие как Паскаль, были разработаны с учетом поддержки структурного программирования , которое обобщалось от подпрограмм (также известных как процедуры или функции) до дополнительные структуры управления, такие как:
- Циклы с использованием
while
,repeat until
илиdo
, иfor
заявления switch
он жеcase
операторы, форма многостороннего ветвления
Эти новые языковые механизмы заменили эквивалентные потоки, которые ранее были написаны с использованием goto
песок if
с. Многоходовое ветвление заменяет «вычисленный переход», при котором инструкция перехода определяется динамически (условно).
При определенных условиях можно исключить локальные операторы перехода к устаревшим программам, заменив их операторами выхода из многоуровневого цикла. [40]
Исключения
[ редактировать ]На практике строгое следование базовому трехструктурному шаблону структурного программирования приводит к сильно вложенному коду из-за невозможности преждевременного выхода из структурированного модуля и комбинаторному взрыву с довольно сложными данными о состоянии программы для обработки всех возможных условий.
Обычно были приняты два решения: способ преждевременного выхода из структурированного модуля и, в более общем плане, исключения - в обоих случаях они поднимаются по структуре, возвращая управление включающим блокам или функциям, но не переходят к произвольным местам кода. Это аналогично использованию оператора возврата в нетерминальной позиции – не строго структурированного из-за раннего выхода, а с мягким ослаблением ограничений структурного программирования. В С, break
и continue
позволяют завершить цикл или перейти к следующей итерации , не требуя дополнительных действий. while
или if
заявление. В некоторых языках также возможны многоуровневые разрывы. Для обработки исключительных ситуаций были добавлены специализированные конструкции обработки исключений , такие как try
/ catch
/ finally
на Яве.
Механизмы обработки исключений throw-catch также можно легко использовать для создания непрозрачных структур управления, точно так же, как можно злоупотреблять goto. [41]
Хвостовые вызовы
[ редактировать ]В докладе, представленном на конференции ACM в Сиэтле в 1977 году, Гай Л. Стил подвел итог дебатам по поводу GOTO и структурного программирования и заметил, что вызовы процедур в хвостовой позиции процедуры наиболее оптимально можно рассматривать как прямую передачу управления. к вызываемой процедуре, обычно устраняя ненужные операции манипуляции стеком. [42] Поскольку такие «хвостовые вызовы» очень распространены в Lisp , языке, где вызовы процедур встречаются повсеместно, эта форма оптимизации значительно снижает стоимость вызова процедуры по сравнению с GOTO, используемым в других языках. Стил утверждал, что плохо реализованные вызовы процедур привели к искусственному восприятию того, что GOTO дешевле по сравнению с вызовом процедур. Стил далее утверждал, что «в целом вызовы процедур можно с пользой рассматривать как операторы GOTO, которые также передают параметры, и могут быть единообразно закодированы как инструкции JUMP машинного кода », при этом инструкции по манипуляции стеком машинного кода «считаются оптимизацией (а не наоборот). !)". [42] Стил привел доказательства того, что хорошо оптимизированные численные алгоритмы в Lisp могут выполняться быстрее, чем код, созданный доступными на тот момент коммерческими компиляторами Fortran, поскольку стоимость вызова процедуры в Lisp была намного ниже. В Scheme , диалекте Лиспа, разработанном Стилом совместно с Джеральдом Джеем Сассманом , оптимизация хвостовых вызовов является обязательной. [43]
Хотя статья Стила не привнесла многого нового в информатику, по крайней мере, в том виде, в котором она практиковалась в Массачусетском технологическом институте, она выявила возможности оптимизации вызовов процедур, что сделало свойства процедур, способствующие модульности, более надежной альтернативой тогдашние привычки кодирования больших монолитных процедур со сложными структурами внутреннего контроля и обширными государственными данными. В частности, оптимизация хвостовых вызовов, обсуждаемая Стилом, превратила процедуру в надежный способ реализации итерации посредством одиночной хвостовой рекурсии (хвостовая рекурсия вызывает одну и ту же функцию). Кроме того, оптимизация хвостовых вызовов допускает взаимную рекурсию неограниченной глубины, предполагая хвостовые вызовы — это позволяет передавать управление, как в конечных автоматах , что в противном случае обычно достигается с помощью операторов goto.
Сопрограммы
[ редактировать ]Сопрограммы — это более радикальное смягчение структурного программирования, позволяющее не только иметь несколько точек выхода (как при возврате в позиции без хвоста), но и несколько точек входа, аналогично операторам goto. Сопрограммы более ограничены, чем goto, поскольку они могут возобновить текущую сопрограмму только в указанных точках (продолжая после выхода) вместо перехода к произвольной точке кода. Ограниченной формой сопрограмм являются генераторы , которых достаточно для некоторых целей. Еще более ограниченными являются замыкания – подпрограммы, которые сохраняют состояние (через статические переменные ), но не позицию выполнения. Комбинация переменных состояния и структурированного управления, в частности общего оператора переключения, может позволить подпрограмме возобновить выполнение в произвольной точке при последующих вызовах и является структурированной альтернативой операторам перехода при отсутствии сопрограмм; это, например, распространенная идиома в C.
Продолжение
[ редактировать ]Продолжение похоже на GOTO тем , что оно передает управление из произвольной точки программы в ранее отмеченную точку. Продолжение более гибко, чем GOTO, в тех языках, которые его поддерживают, поскольку оно может передавать управление из текущей функции, чего GOTO не может сделать в большинстве языков структурированного программирования. программы В тех реализациях языка, которые поддерживают фреймы стека для хранения локальных переменных и аргументов функций, выполнение продолжения включает в себя настройку стека вызовов в дополнение к переходу. Функция longjmp языка программирования C является примером escape-продолжения, которое можно использовать для перехода из текущего контекста в окружающий. Оператор Common Lisp GO также имеет это свойство разворачивания стека, несмотря на то, что конструкция имеет лексическую область видимости , поскольку на метку, на которую осуществляется переход, можно ссылаться из замыкания .
В Scheme продолжения при желании могут даже перемещать управление из внешнего контекста во внутренний. Этот почти безграничный контроль над тем, какой код будет выполняться следующим, позволяет относительно легко писать сложные структуры управления, такие как сопрограммы и кооперативная многозадачность. [43]
Передача сообщений
[ редактировать ]В непроцедурных парадигмах goto менее актуален или вообще отсутствует. Одной из основных альтернатив является передача сообщений , которая имеет особое значение в параллельных вычислениях , межпроцессном взаимодействии и объектно-ориентированном программировании . В этих случаях отдельные компоненты не имеют произвольной передачи управления, но общее управление может быть запланировано сложными способами, например, посредством вытеснения . Влиятельные языки Simula и Smalltalk были одними из первых, кто ввел концепции сообщений и объектов. Инкапсулируя . данные о состоянии, объектно-ориентированное программирование свело сложность программного обеспечения к взаимодействиям (сообщениям) между объектами
Вариации
[ редактировать ]имеется ряд различных языковых конструкций В классе операторов goto .
Вычисление GOTO и Назначено ПЕРЕЙТИ
[ редактировать ]На Фортране вычисляется GOTO
переходит к одной из нескольких меток в списке в зависимости от значения выражения. Примером является goto (20,30,40) i
. [44] Эквивалентной конструкцией в C является оператор переключения , а в более новых версиях Фортрана SELECT CASE
конструкция является рекомендуемой синтаксической альтернативой. [45] В Бейсике был 'On GoTo'
оператор, который достиг той же цели, но в Visual Basic эта конструкция больше не поддерживается. [46]
В версиях до Fortran 95 Fortran также имел назначенный вариант перехода , который передает управление метке оператора (номеру строки), которая хранится (назначается) в целочисленной переменной. К сожалению, переход к целочисленной переменной, которой не было присвоено значение ASSIGN, был основным источником ошибок, связанных с назначенными переходами. [47] Фортран assign
Оператор позволяет присваивать целочисленной переменной только постоянный (существующий) номер строки. Однако некоторые компиляторы позволяли впоследствии случайно обрабатывать эту переменную как целое число, например увеличивать ее, что приводило к неопределенному поведению при goto
время. Следующий код демонстрирует поведение goto i
когда строка i не указана:
assign 200 to i
i = i+1
goto i ! unspecified behavior
200 write(*,*) "this is valid line number"
Некоторые компиляторы C реализуют два нестандартных расширения C/C++, относящиеся к gotos, первоначально представленные gcc . [48] Расширение GNU позволяет получить адрес метки внутри текущей функции как void*
использование унарного оператора значения метки префикса &&
. Инструкция goto также расширена и позволяет перейти к произвольному элементу. void*
выражение. Это расширение C называется вычисляемым переходом в документации компиляторов C, которые его поддерживают; его семантика является расширенным набором назначенного перехода Фортрана, поскольку он позволяет использовать произвольные выражения указателя в качестве цели перехода, в то время как назначенный переход Фортрана не допускает произвольные выражения в качестве цели перехода. [49] Как и в случае со стандартным переходом в C, расширение GNU C позволяет цели вычисленного перехода находиться только в текущей функции. Попытка выйти за пределы текущей функции приводит к неопределенному поведению. [49]
Некоторые варианты BASIC также поддерживают вычисляемый GOTO в том смысле, который используется в GNU C, т.е. в котором целью может быть любой номер строки, а не только одна из списка. Например, на MTS BASIC можно было бы написать GOTO i*1000
чтобы перейти к строке с номером, в 1000 раз превышающим значение переменной i (которая может представлять, например, выбранный пункт меню). [50]
PL/I Переменные меток достигают эффекта вычисленных или присвоенных GOTO
с.
ИЗМЕНИТЬ
[ редактировать ]До стандарта ANSI COBOL 1985 года существовал оператор ALTER, который можно было использовать для изменения назначения существующего GO TO, который должен был находиться в отдельном абзаце. [51] Функция, допускавшая полиморфизм , часто осуждалась и редко использовалась. [52]
Перл ПЕРЕХОДИТЬ
[ редактировать ]В Perl есть вариант goto
оператор, который вообще не является традиционным оператором GOTO. Он принимает имя функции и передает управление путем эффективной замены одного вызова функции на другой ( хвостовой вызов ): новая функция вернется не к GOTO, а к тому месту, из которого была вызвана исходная функция. [53]
Эмулируемый ПЕРЕЙТИ
[ редактировать ]Существует несколько языков программирования, которые по умолчанию не поддерживают GOTO. Используя эмуляцию GOTO, в этих языках программирования все еще можно использовать GOTO, хотя и с некоторыми ограничениями. Можно эмулировать GOTO в Java, [54] JavaScript, [55] и Питон. [56] [57]
PL/I метки переменных
[ редактировать ]PL/I имеет тип данных LABEL , который можно использовать для реализации как «назначенного перехода», так и «вычисленного перехода». PL/I разрешает ветвления из текущего блока. Вызывающая процедура может передать метку в качестве аргумента вызываемой процедуре, которая затем может завершиться с разветвлением. Значение переменной метки включает в себя адрес кадра стека, а переход из блока извлекает стек.
/* This implements the equivalent of */ /* the assigned goto */ declare where label; where = somewhere; goto where; ... somewhere: /* statement */ ; ...
/* This implements the equivalent of */ /* the computed goto */ declare where (5) label; declare inx fixed; where(1) = abc; where(2) = xyz; ... goto where(inx); ... abc: /* statement */ ; ... xyz: /* statement */ ; ...
Более простой способ получить эквивалентный результат — использовать массив констант меток , который даже не требует явного объявления переменной типа LABEL :
/* This implements the equivalent of */ /* the computed goto */ declare inx fixed; ... goto where(inx); ... where(1): /* statement */ ; ... where(2): /* statement */ ; ...
MS/DOS ПЕРЕЙТИ К
[ редактировать ]В пакетном файле DOS Goto направляет выполнение на метку, которая начинается с двоеточия. Целью Goto может быть переменная.
@echo off
SET D8str=%date%
SET D8dow=%D8str:~0,3%
FOR %%D in (Mon Wed Fri) do if "%%D" == "%D8dow%" goto SHOP%%D
echo Today, %D8dow%, is not a shopping day.
goto end
:SHOPMon
echo buy pizza for lunch - Monday is Pizza day.
goto end
:SHOPWed
echo buy Calzone to take home - today is Wednesday.
goto end
:SHOPFri
echo buy Seltzer in case somebody wants a zero calorie drink.
:end
Языковая поддержка
[ редактировать ]Многие языки поддерживают goto
заявление, а многие этого не делают. На Яве , goto
это зарезервированное слово , но его нельзя использовать, хотя оно и скомпилировано .class
файлы генерируют GOTO и LABEL. [58] В Python нет поддержки goto, хотя существует несколько шуточных модулей, которые ее предоставляют. [56] [57] нет оператора перехода В Seed7 , а скрытые операторы перехода, такие как операторы прерывания и продолжения, также опущены. [59] В PHP не было встроенной поддержки goto
до версии 5.3 (были доступны библиотеки для эмуляции его функциональности). [60]
C# и Visual Basic .NET поддерживают goto
. [61] [62] Однако он не позволяет переходить к метке за пределами текущей области видимости и учитывает удаление объектов и, наконец, конструкции, что делает его значительно менее мощным и опасным, чем goto
ключевое слово в других языках программирования. Он также создает метки операторов case и default , областью действия которых является включающий оператор switch ; goto case или goto default часто используются как явная замена неявного провала, который не допускается в C#.
В языке программирования PL /I есть оператор GOTO, который разворачивает стек для передачи из блока и не позволяет осуществлять переход в блок из-за его пределов.
В других языках могут быть свои отдельные ключевые слова для явных провалов, которые можно рассматривать как версию goto
ограничивается этой конкретной целью. Например, Go использует fallthrough
ключевое слово и вообще не допускает неявного провала, [63] в то время как Perl 5 использует next
для явного провала по умолчанию, но также позволяет установить неявный провал в качестве поведения по умолчанию для модуля.
В большинстве языков, в которых есть операторы goto, это называется именно так, но на заре вычислительной техники использовались и другие названия. Например, в MAD использовался оператор TRANSFER TO. [64] APL использует стрелку, указывающую вправо, →
для перехода.
C имеет goto и обычно используется в различных идиомах, как обсуждалось выше.
В языках функционального программирования, таких как Scheme, обычно нет перехода, вместо этого используются продолжения.
См. также
[ редактировать ]- COMEFROM
- Поток управления
- ГОСУБ
- Оператор Switch – многоходовая ветвь (или условный переход)
- Неструктурированное программирование
Примечания
[ редактировать ]- ^ Ватт и Финдли 2004 .
- ^ Керниган и Ричи 1988 , с. 224, A9.6 Операторы перехода.
- ^ Jump up to: а б Дейкстра, 1968 год .
- ^ Команда разработчиков GNU Pascal, 2005 г. , 5.1 Различные советы по программированию на Pascal.
- ^ Лауден и Ламберт 2012 .
- ^ «Необузданное использование оператора goto приводит к тому, что становится ужасно трудно найти значимый набор координат, в которых можно описать ход процесса. ... Оператор goto в его нынешнем виде слишком примитивен. , это слишком сильное приглашение испортить свою программу».
- ^ Рубин 1987 .
- ^ Дейкстра, Эдсгер В. О несколько разочаровывающей переписке (EWD-1009) (PDF) . Архив Э. В. Дейкстры. Центр американской истории Техасского университета в Остине . ( транскрипция ) (май, 1987 г.)
- ^ Кнут 1974 .
- ^ Керниган и Ричи 1988 , стр. 65–66, 3.8 Goto и Labels.
- ^ Jump up to: а б с Вайн 2007 , стр. 262.
- ^ Гейслер 2011 .
- ^ Обсуждение 2013 г.
- ^ Jump up to: а б с д Сахни и Чмелик 1995 .
- ^ Jump up to: а б с Эндрюс 2003 .
- ^ МакКоннелл 2004 .
- ^ Регер 2013 .
- ^ Робертс 1995 .
- ^ Мейер 2009 .
- ^ Козен и Ценг 2008 .
- ^ Вопросы о переполнении стека, 2012 г.
- ^ Питчфорд и Тэпп 2013 .
- ^ Уильямс 2013 .
- ^ ANSI X3.9-1978. Американский национальный стандарт – язык программирования FORTRAN. Американский национальный институт стандартов. Также известен как ISO 1539-1980, неофициально известный как FORTRAN 77.
- ^ ИСО/МЭК 1539-1:1997. Информационные технологии – Языки программирования – Фортран – Часть 1: Базовый язык. Неофициально известный как Фортран 95. Этот стандарт состоит из еще двух частей. Часть 1 была официально принята ANSI.
- ^ Барнс 2006 .
- ^ Саммит 1995 года .
- ^ Jump up to: а б Торвальдс 2016 .
- ^ Jump up to: а б Козенс 2004 .
- ^ Учебник по Java 2012 .
- ^ Гослинг и МакГилтон 1996 .
- ^ Брендер 2002 , стр. 960–965.
- ^ Jump up to: а б Спинеллис 2003 .
- ^ Jump up to: а б Алан 2019 .
- ^ Страуструп 2012 .
- ^ Хоад, Натан (28 июля 2022 г.). "nathanhoad/godot_dialogue_manager" . Гитхаб . Проверено 3 февраля 2023 г.
- ^ Чисналл 2012 .
- ^ Контейнеры 2021 .
- ^ Уилкс, Уилер и Гилл 1951 .
- ^ Рамшоу 1988 .
- ^ Сидерслебен 2006 .
- ^ Jump up to: а б Стил 1977 .
- ^ Jump up to: а б Келси, Клингер и Рис, 1998 .
- ^ , что означает, что программа переходит к метке 20, 30 или 40, в случае, если i меньше, равно или больше нуля.
- ^ Lahey Computer Systems, Inc 2004 .
- ^ Microsoft 2021 .
- ^ Вейр 1997 .
- ^ z/OS 2.5.0 в документации IBM 2021 .
- ^ Jump up to: а б GCC, Коллекция компиляторов GNU 2021 .
- ^ Фрончак и Любберс 1974 , с. 226.
- ^ Оператор ALTER был признан устаревшим в стандарте COBOL 1985 года и удален в 2002 году; см. COBOL > Самоизменяющийся код.
- ^ Ван Тассель 2004 .
- ^ Руководство по синтаксису Perl, 2021 г.
- ^ ПЕРЕЙДИТЕ к Java 2009 .
- ^ Секстон 2012 .
- ^ Jump up to: а б Хиндл 2004 .
- ^ Jump up to: а б Ноак и др. 2015 .
- ^ Гослинг и др. (2005) В отличие от C и C++, язык программирования Java не имеет оператора перехода; Метки операторов-идентификаторов используются с операторами прерывания (§14.15) или продолжения (§14.16), появляющимися в любом месте внутри помеченного оператора. Ключевые слова const и goto зарезервированы, хотя в настоящее время они не используются. Это может позволить компилятору Java выдавать более точные сообщения об ошибках, если эти ключевые слова C++ неправильно отображаются в программах.
- ^ Руководство по языку программирования Seed7 2021 .
- ^ Руководство по PHP 2021 .
- ^ Вагнер 2021 .
- ^ «Оператор GoTo — Visual Basic | Microsoft Learn» . Microsoft Learn . 15 сентября 2021 г. Проверено 25 сентября 2023 г.
- ^ Спецификация языка программирования Go 2021 .
- ^ Галлер 1962 , стр. 26–28, 197, 211.
Ссылки
[ редактировать ]- Аллен, Алекс (2019). «Когда использовать Goto в C» . Проверено 14 ноября 2021 г.
- Эндрюс, Джереми (13 января 2003 г.). «Linux: использование goto в коде ядра» . Архивировано из оригинала 28 ноября 2005 года . Проверено 14 ноября 2021 г.
- Барнс, Джон (30 июня 2006 г.). Программирование на Аде 2005 . Эддисон Уэсли . п. 114-115. ISBN 978-0-321-34078-8 .
- Брендер, Рональд Ф. (2002). «Язык программирования BLISS: история» (PDF) . Программное обеспечение: практика и опыт . 32 (10): 955–981. дои : 10.1002/спе.470 . S2CID 45466625 .
- Чисналл, Дэвид (2012). Разговорник Objective-C . Аддисон-Уэсли Профессионал. п. 249 . ISBN 978-0-321-81375-6 .
- Контьери, Макси (2 ноября 2021 г.). «Код Smell 100 — GoTo» . Максимилиано Контьери — Разработка программного обеспечения . Проверено 14 ноября 2021 г.
- Козенс, Саймон (16 апреля 2004 г.). «Хорошее использование goto» . Архивировано из оригинала 19 марта 2011 г.
- Дейкстра, Эдсгер В. (март 1968 г.). «Письма в редакцию: Перейти к заявлению, признанному вредным» (PDF) . Коммуникации АКМ . 11 (3): 147–148. дои : 10.1145/362929.362947 . S2CID 17469809 .
- Дейкстра, Эдсгер В. О несколько разочаровывающей переписке (EWD-1009) (PDF) . Архив Э. В. Дейкстры. Центр американской истории Техасского университета в Остине . ( транскрипция )
- Фрончак, Эдвард Дж.; Любберс, Кларк Э. (сентябрь 1974 г.). МТС, Терминальная система Мичигана . Вычислительный центр Мичиганского университета. Единица измерения: 39015034770076.
- Галлер, Бернард А. (1 января 1962 г.). Язык компьютеров (PDF) . МакГроу-Хилл.
- GCC, Коллекция компиляторов GNU (2021 г.). «Ярлыки как значения — использование коллекции компиляторов GNU (GCC)» . Gcc.gnu.org . Проверено 13 ноября 2021 г.
- Гейслер, Сандра (2011). C Настольный справочник «все в одном» для чайников . Джон Уайли и сыновья. стр. 217–220. ISBN 978-1-118-05424-6 .
- Команда разработчиков GNU Pascal (2005 г.). «Стандарты кодирования GNU Pascal» . www.gnu-pascal.de . Фонд свободного программного обеспечения . Проверено 10 ноября 2021 г.
- Гослинг, Джеймс ; МакГилтон, Генри (май 1996 г.). «Языковая среда Java» . Oracle.com . Проверено 22 июля 2014 г.
- Гослинг, Джеймс; Джой, Билл ; Стил, Гай Льюис ; Браха, Гилад (2005). Спецификация языка Java (3-е изд.). Аддисон-Уэсли. ISBN 0-321-24678-0 . Архивировано из оригинала 14 февраля 2012 года . Проверено 8 февраля 2019 г.
- GOTO для Java (6 июля 2009 г.). «GOTO для Java» . стейк . Архивировано из оригинала 15 июня 2012 года . Проверено 28 апреля 2012 г.
- Хиндл, Ричи (1 апреля 2004 г.). «перейти к Python» . Энтрийские решения . Хартфорд, Великобритания: Entrian Solutions Ltd. Проверено 10 ноября 2021 г.
- Учебник по Java (28 февраля 2012 г.). «Операторы ветвления (Учебные пособия по Java > Изучение языка Java > Основы языка)» . Docs.oracle.com . Проверено 10 ноября 2021 г.
- Келси, Р.; Клингер, В.; Рис, Дж.; и др. (август 1998 г.). «Пересмотренный 5 Отчет об алгоритмической языковой схеме» . Высшие порядки и символические вычисления . 11 (1): 7–105. doi : 10.1023/A:1010051815785 . S2CID 14069423 .
- Керниган, Брайан Уилсон ; Ричи, Деннис Макалистер (1988). Язык программирования C (2-е изд.). Прентис Холл. ISBN 978-0-13-308621-8 .
- Кнут, Дональд (1974). «Структурное программирование с переходом к операторам» (PDF) . Вычислительные опросы . 6 (4): 261–301. CiteSeerX 10.1.1.103.6084 . дои : 10.1145/356635.356640 . S2CID 207630080 . Архивировано из оригинала (PDF) 17 июля 2017 г. Проверено 26 января 2017 г.
- Козен, Декстер ; Ценг, Вэй-Лунг Дастин (июль 2008 г.). «Теорема Бема_Якопини ложна с точки зрения утверждения» (PDF) . В Одебо, Филипп; Полен-Моринг, Кристина (ред.). Математика построения программ . 9-я Международная конференция MPC 2008. Конспект лекций по информатике. Том. 5133. Марсель Франция. стр. 177_192. CiteSeerX 10.1.1.218.9241 . дои : 10.1007/978-3-540-70594-9_11 . ISBN 978-3-540-70593-2 .
- Lahey Computer Systems, Inc (2004). «Вычисляемый оператор GOTO (устаревший)» . Lahey Computer Systems, Inc. Архивировано из оригинала 26 мая 2016 г. Проверено 10 ноября 2021 г.
- Лауден, Кеннет К.; Ламберт, Кеннет А. (2012). Языки программирования: принципы и практика . Cengage Обучение. п. 422 . ISBN 978-1-111-52941-3 .
- Руководство по языку программирования Seed7 (2021 г.). «Особенности Seed7» . Проверено 10 ноября 2021 г.
{{cite web}}
: CS1 maint: числовые имена: список авторов ( ссылка )
- МакКоннелл, Стив (декабрь 2004 г.). Code Complete: Практическое руководство по созданию программного обеспечения, второе издание (2-е изд.). Майкрософт Пресс. ISBN 978-0735619678 .
- Мейер, Бертран (2009). Прикосновение к классу: учимся хорошо программировать с объектами и контрактами . Springer Science & Business Media. п. 189. ИСБН 978-3-540-92144-8 .
- Майкрософт (2021). « Операторы «On GoTo» и «On GoSub» больше не поддерживаются» . Майкрософт . Проверено 10 ноября 2021 г.
- Ноак, Себастьян; Бланк, Дуглас; Грейнджер, Томас; космический странник (19 сентября 2015 г.). «snoack/python-goto: декоратор функции, который перезаписывает байт-код, чтобы включить переход в Python» . Гитхаб . Проверено 10 ноября 2021 г.
- Руководство по синтаксису Perl (2021 г.). Перейти (Отчет) . Проверено 14 ноября 2021 г.
- Руководство по PHP (2021 г.). "перейти" . PHP . Проверено 13 ноября 2021 г.
- Питчфорд, Марк; Тэпп, Крис (25 февраля 2013 г.). «MISRA C:2012: множество веских причин для изменений» . Электронный дизайн . Проверено 22 июля 2014 г.
- Прата, Стивен (2013). С Праймер Плюс . Аддисон-Уэсли. стр. 287–289. ISBN 978-0-13-343238-1 .
- Рамшоу, Л. (1988). «Устранение переходов при сохранении структуры программы» . Журнал АКМ . 35 (4): 893–920. дои : 10.1145/48014.48021 . S2CID 31001665 .
- Регер, Джон (4 февраля 2013 г.). «Использование Goto в системном коде – встроено в академические круги» . blog.regehr.org .
- Робертс, Эрик С. (март 1995 г.). «Выходы из цикла и структурированное программирование: возобновление дискуссии» . Бюллетень ACM SIGCSE . 27 (1): 268–272. дои : 10.1145/199691.199815 .
- Рубин, Фрэнк (март 1987 г.). « Перейти к считается вредным» считается вредным» (PDF) . Коммуникации АКМ . 30 (3): 195–196. дои : 10.1145/214748.315722 . S2CID 6853038 . Архивировано из оригинала (PDF) 20 марта 2009 г.
- Сахни, Сартадж; Цмелик, Боб (1995). Разработка программного обеспечения на C. Силиконовый пресс. п. 135. ИСБН 978-0-929306-16-2 .
- Секстон, Алекс (2012). «Лето Goto | Официальный дом Goto.js» . Архивировано из оригинала 25 октября 2015 года.
{{cite web}}
: CS1 maint: неподходящий URL ( ссылка )
- Сидерслебен, Йоханнес (2006). «Ошибки и исключения – права и обязанности». В Кристофе Дони (ред.). Дополнительные темы по методам обработки исключений . Springer Science & Business Media. п. 277 . ISBN 978-3-540-37443-5 .
- Спинеллис, Диомидис (27 мая 2003 г.). Чтение кода: взгляд на открытый исходный код . Аддисон-Уэсли Профессионал. стр. 43–44. ISBN 978-0-672-33370-5 .
- Вопросы о переполнении стека (11 июня 2012 г.). «Почему «продолжить» считается нарушением C в MISRA C:2004?» . Переполнение стека . Проверено 10 ноября 2021 г.
- Стил, Гай Льюис (январь 1977 г.). «Развенчивание мифа о «дорогом вызове процедур» или реализациях вызова процедур, считающихся вредными, или LAMBDA». Материалы ежегодной конференции 1977 года по ACM '77 . стр. 153–162. дои : 10.1145/800179.810196 . ISBN 9781450323086 . S2CID 9807843 .
- Страуструп, Бьярне (9 января 2012 г.). «Основной доклад первого дня — Бьерн Страуструп: стиль C++11 | GoingNative 2012 | Channel 9» . Channel9.msdn.com . Проверено 10 ноября 2021 г.
- Саммит, Стив (1995). "comp.lang.c Список часто задаваемых вопросов · Вопрос 17.10" . C-faq.com . Проверено 10 ноября 2021 г.
- Спецификация языка программирования Go (26 июля 2021 г.). «Спецификация языка программирования Go — язык программирования Go» .
- Торвальдс, Линус (2016). «Стиль кодирования ядра Linux» . Документация ядра Linux . Проверено 10 ноября 2021 г.
- Ван Тассель, Денни (8 июля 2004 г.). «История меток в языках программирования» . Проверено 4 января 2011 г.
- Вайн, Майкл А. (2007). Программирование на C для абсолютных новичков . Cengage Обучение. ISBN 978-1-59863-634-5 .
- Вагнер, Билл (2021). «оператор перехода — Справочник по C#» . docs.microsoft.com . Проверено 9 ноября 2021 г.
- Ватт, Дэвид Энтони; Финдли, Уильям (2004). Концепции проектирования языков программирования . Джон Уайли и сыновья. п. 228 . ISBN 978-0-470-85320-7 .
- Вер, Джейсон (1997). «Перейти к (назначено)» . www.personal.psu.edu/jhm/f90/201.html . Проверено 13 ноября 2021 г.
- Уилкс, Морис В .; Уиллер, Дэвид Дж .; Гилл, Стэнли (1951). Подготовка программ для электронной цифровой вычислительной машины . Аддисон-Уэсли .
(иногда называемая WWG по инициалам авторов) была первой книгой по компьютерному программированию.
- Уильямс, Том (март 2013 г.). «Правила проверки C: обеспечение надежности и безопасности» . Журнал РТК . 22 (3): 12–15 . Проверено 10 ноября 2021 г.
- z/OS 2.5.0 в документации IBM (2021 г.). «Вычисляемый оператор перехода (расширение IBM)» . ИБМ . Проверено 13 ноября 2021 г.
В этом документе описываются синтаксис, семантика и реализация IBM z/OS XL C/C++ языков программирования C и C++. Справочник по стандарту C или C++ общего назначения см. на сайте cppreference.com.
{{cite web}}
: CS1 maint: числовые имена: список авторов ( ссылка )