В языках программирования метка представляет собой последовательность символов , которая идентифицирует местоположение в исходном коде . В большинстве языков метки имеют форму идентификатора , за которым часто следует знак пунктуации (например, двоеточие ). Во многих языках высокого уровня метка служит местом назначения оператора GOTO
. [1] [2] В языке ассемблера метки могут использоваться везде, где может быть адрес (например, в качестве операнда JMP
или MOV
инструкции). [3] Также в Паскале и его производных вариациях. Некоторые языки, такие как Fortran и BASIC , поддерживают числовые метки. [4] Метки также используются для идентификации точки входа в скомпилированную последовательность операторов (например, во время отладки ).
В C метка идентифицирует оператор в коде. Один оператор может иметь несколько меток. Метки просто указывают места в коде, и достижение метки не влияет на фактическое выполнение.
Метки функций состоят из идентификатора, за которым следует двоеточие. Каждая такая метка указывает на оператор функции, и ее идентификатор должен быть уникальным внутри этой функции. Другие функции могут использовать то же имя для метки. Идентификаторы меток занимают собственное пространство имен — можно иметь переменные и функции с тем же именем, что и метка.
void foo ( int number ) { if ( number < 0 ) перейти к ошибке ; бар ( номер ); возвращаться ; ошибка : fprintf ( stderr , «Неверный номер! \n » ); }
Здесь ошибка — это метка. Оператор goto можно использовать для перехода к помеченному оператору в коде. После a goto
выполнение программы продолжается с оператора после метки.
В оператор переключателя можно поместить два типа меток. Метка варианта состоит из ключевого слова case
, за которым следует выражение, результатом которого является целочисленная константа. Метка по умолчанию состоит из ключевого слова default
. Метки регистра используются для связи целочисленного значения с оператором в коде. Когда достигается оператор переключения, выполнение программы продолжается с оператора после метки случая со значением, которое соответствует значению в круглых скобках переключателя. Если такой метки случая нет, но есть метка по умолчанию, выполнение программы продолжается с оператора, следующего за меткой по умолчанию. Если метка по умолчанию отсутствует, выполнение программы продолжается после переключения.
switch ( die ) { default : printf ( "invalid \n " ); перерыв ; случай 1 : случай 3 : случай 5 : printf ( «нечетный \n » ); перерыв ; случай 2 : случай 4 : случай 6 : printf ( «даже \n » ); перерыв ; }
В пределах одного оператора переключения целочисленная константа, связанная с каждой меткой варианта, должна быть уникальной. Оператор по умолчанию может быть, а может и не быть. Нет ограничений на порядок меток внутри переключателя. Требование, чтобы значения меток регистра оценивались как целочисленные константы, дает компилятору больше возможностей для оптимизации.
В синтаксических операторах языка JavaScript может предшествовать метка:
top : //Помечаем самый внешний цикл for. for ( var i = 0 ; i < 4 ; i ++ ) { for ( var j = 0 ; j < 4 ; j ++ ) { if ( j === 3 && i === 2 ) { alert ( " i=" + я + ", j=" + j ); //i=2, j=3 прерываем вершину ; } } } предупреждение ( "i=" + я + ", j=" + j ); //i=2, j=3
Также можно использовать break
оператор для выхода из блоков кода:
вверху : { консоль . log ( "foo" ) консоль . log ( "bar" ) разбить верхнюю консоль . журнал ( «баз» ) } // Что выведет: // > foo // > bar
В Common Lisp существует два способа определения меток. Первый предполагает использование tagbody
специального оператора. В отличие от многих других языков программирования, допускающих глобальную навигацию, таких как C , метки доступны только в контексте этого оператора. Внутри метки tagbody
определяются как формы, начинающиеся с символа; специальная go
форма позволяет передавать управление между этими метками. [5]
( let (( итерация NIL )) ( tagbody start ( print 'started ) ( setf итерация 0 ) увеличение ( итерация печати ) ( incf итерация 1 ) ( go check ) check ( if ( >= итерация 10 ) ( go end ) ( go увеличить )) конец ( печатать готово )))
Второй метод использует макросы считывателя и , первый из которых помечает объект, следующий сразу за ним, второй ссылается на его оцененное значение. [6] Метки в этом смысле представляют собой скорее альтернативу переменным, поскольку они объявляют и инициализируют «переменную» и получают к ней доступ. Заполнитель n обозначает выбранное десятичное целое число без знака, идентифицирующее метку.#n=
#n#
#n=
#n#
( программа №1= "привет" ( напечатайте #1# ))
Кроме того, некоторые формы разрешают или требуют объявления метки для последующего использования, включая специальную форму block
, которая предписывает именование, и loop
макрос, который можно идентифицировать с помощью named
предложения. Немедленный выход из названной формы возможен с помощью return-from
специального оператора.
( блокировать myblock ( цикл для итерации от 0 do ( if ( >= итерация 10 ) ( return-from myblock 'done ) ( итерация печати ))))
( цикл с именем myloop для итерации от 0 do ( if ( >= итерация 10 ) ( return-from myloop 'done ) ( итерация печати )))
Подобно C, макросы case
, ccase
, ecase
, [ 7] typecase
и определяют операторы переключения. [8]ctypecase
etypecase
( let (( my-value 5 )) ( case my-value ( 1 ( выведите «один» )) ( 2 ( выведите «два» ) )) (( 3 4 5 ) ( выведите «три четыре или пять» ) )) ( в противном случае ( выведите «любое другое значение» ))))
( let (( my-value 5 )) ( typecase my-value ( list ( напечатайте "список" )) ( строка ( напечатайте "строку" )) ( число ( напечатайте "число" )) ( иначе ( напечатайте " любой другой тип" ))))