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