Введение. Циклы с предусловием.
При решении практических задач постоянно возникает необходимость в повторении действия заданное количество раз, или до достижения какого-либо условия. Например, вывести список всех пользователей, замостить плоскость текстурой, провести вычисления над каждым элементом массива данных и т.п.
В си для этих целей используются три вида циклов: с предусловием, постусловием и цикл for со счётчиком (хотя, это условное название, потому что счётчика может и не быть).
Любой цикл состоит из тела и проверки условия, при котором этот цикл должен быть прекращён. Тело цикла — это тот набор инструкций, который необходимо повторять. Каждое повторение цикла называют итерацией.
Рассмотрим цикл с предусловием.
int i = 0; while (i < 10) { printf("%d\n", i); i++; }
Этот цикл выполняется до тех пор, пока истинно условие, заданное после ключевого слова while.
Тело цикла — это две строки, одна выводит число, вторая изменяет его.
Очевидно, что этот цикл будет выполнен 10 раз и выведет на экран
0
1
2
3
и так далее до 9.
Очень важно, чтобы условие выхода из цикла когда-нибудь выполнилось, иначе произойдёт зацикливание, и программа не завершится.
К примеру
int i = 0; while (i < 10) { printf("%d\n", i); }
В этом цикле не изменяется переменная i, которая служит для определения условия останова, поэтому цикл не завершится.
int i = 0; while (i > 0) { printf("%d\n", i); i++; }
В этой программе цикл, конечно, завершится, но из-за неправильного действия он будет выполнен гораздо больше 10 раз. Так как си не следит за переполнением переменной, нужно будет ждать, пока переменная переполнится и станет меньше нуля.
int i; while (i < 10) { printf("%d\n", i); i++; }
У этого примера неопределённое поведение. Так как переменная i заранее не инициализирована, то она хранит мусор, заранее неизвестное значение. При различном содержимом переменной i будет меняться поведение.
Если тело цикла while содержит один оператор, то фигурные скобки можно опустить.
int i = 0; while (i < 10) printf("%d\n", i++);
Здесь мы инкрементируем переменную i при вызове функции printf.
Следует избегать такого стиля кодирования. Отсутствие фигурных скобок, особенно в начале обучения, может приводить к ошибкам. Кроме того, код читается хуже, да и лишние скобки не сильно раздувают листинги.
Вложенные циклы for
Как и другие типы циклов, циклы могут быть вложены внутрь других циклов. В следующем примере мы вкладываем цикл внутрь другого цикла :
При каждой итерации внешнего цикла внутренний цикл выполняется полностью. Следовательно, на выходе получается:
Вот еще несколько подробностей о том, что здесь происходит. Сначала выполняется внешний цикл, и инициализируется значением . Затем вычисляется , что верно, поэтому выполняется тело цикла. Поскольку установлен в , сначала выводится a. Затем полностью выполняется внутренний цикл (который выводит 0, 1 и 2). Затем печатается символ новой строки. Теперь тело внешнего цикла завершено, поэтому внешний цикл возвращается наверх, увеличивается до , и условие цикла повторно вычисляется. Поскольку условие цикла по-прежнему выполняется, начинается следующая итерация внешнего цикла. Это напечатает «b012\n«. И так далее.
Цикл «for»
Более сложный, но при этом самый распространённый цикл — цикл .
Выглядит он так:
Давайте разберёмся, что означает каждая часть, на примере. Цикл ниже выполняет для от до (но не включая) :
Рассмотрим конструкцию подробней:
часть | ||
---|---|---|
начало | Выполняется один раз при входе в цикл | |
условие | Проверяется перед каждой итерацией цикла. Если оно вычислится в , цикл остановится. | |
шаг | Выполняется после тела цикла на каждой итерации перед проверкой условия. | |
тело | Выполняется снова и снова, пока условие вычисляется в . |
В целом, алгоритм работы цикла выглядит следующим образом:
То есть, начало выполняется один раз, а затем каждая итерация заключается в проверке условия, после которой выполняется тело и шаг.
Если тема циклов для вас нова, может быть полезным вернуться к примеру выше и воспроизвести его работу на листе бумаги, шаг за шагом.
Вот в точности то, что происходит в нашем случае:
Встроенное объявление переменной
В примере переменная счётчика была объявлена прямо в цикле. Это так называемое «встроенное» объявление переменной. Такие переменные существуют только внутри цикла.
Вместо объявления новой переменной мы можем использовать уже существующую:
Любая часть может быть пропущена.
Для примера, мы можем пропустить если нам ничего не нужно делать перед стартом цикла.
Вот так:
Можно убрать и :
Это сделает цикл аналогичным .
А можно и вообще убрать всё, получив бесконечный цикл:
При этом сами точки с запятой обязательно должны присутствовать, иначе будет ошибка синтаксиса.
Что такое Bash?
Как я уже говорил, Bash — это интерпретатор команд. По сути, это обычная программа, которая запускается при старте сеанса оболочки. Мы могли бы запускать не Bash, а скажем, интерпретатор python или ruby, и тогда нам пришлось бы выполнять методы этих языков вместо команд Bash для администрирования системы.
Bash принимает команды от пользователя и передает их системному загрузчику, а также обеспечивает взаимодействие между командами, обмен информацией и потоками ввода-вывода. Также оболочка предоставляет пользователю удобный интерфейс для работы с историей команд, поиска и замены, а также исправления ранее выполненных команд, а также автодополнение путей.
Цикл «while»
Цикл имеет следующий синтаксис:
Код из тела цикла выполняется, пока условие истинно.
Например, цикл ниже выводит , пока :
Одно выполнение тела цикла по-научному называется итерация. Цикл в примере выше совершает три итерации.
Если бы строка отсутствовала в примере выше, то цикл бы повторялся (в теории) вечно. На практике, конечно, браузер не позволит такому случиться, он предоставит пользователю возможность остановить «подвисший» скрипт, а JavaScript на стороне сервера придётся «убить» процесс.
Любое выражение или переменная может быть условием цикла, а не только сравнение: условие вычисляется и преобразуется в логическое значение.
Например, – более краткий вариант :
Фигурные скобки не требуются для тела цикла из одной строки
Если тело цикла состоит лишь из одной инструкции, мы можем опустить фигурные скобки :
Итерация последовательных типов данных с помощью RangeClause
В Go циклы for обычно используются для перебора элементов последовательных или коллекционных типов данных, таких как срезы, массивы и строки. Чтобы упростить эту задачу, можно использовать цикл for типа RangeClause. Конечно, можно использовать и синтаксис ForClause, однако RangeClause чище и удобнее читается.
Прежде чем перейти к RangeClause, давайте посмотрим, как можно итерировать следующий срез, используя синтаксис ForClause:
Этот цикл выдаст следующий вывод, отображая каждый элемент среза:
Теперь давайте используем цикл RangeClause для выполнения того же набора действий:
В этом случае выводится каждый элемент в списке. В цикле использованы переменные i и shark, но им можно было присвоить другие допустимые имена и получить такой же результат.
При использовании range в срезе всегда будут возвращаться два значения. Первое значение – индекс текущей итерации цикла, а второе – значение этого индекса. В этом случае для первой итерации индекс был равен 0, а значение было hammerhead.
В некоторых ситуациях нужно извлечь только элементы среза, без индекса. Но если изменить предыдущий код, чтобы выводить только значение, мы получим ошибку компиляции:
Поскольку переменная i объявлена в цикле for, но никогда не используется, компилятор выдаст ошибку: i declared and not used. Эта же ошибка возникает в Go каждый раз, когда вы объявляете переменную и не используете ее.
Для подобных случаев в Go есть , который выражается подчеркиванием (_). В цикле for можно использовать пустой идентификатор, чтобы игнорировать любое значение, возвращаемое ключевым словом range. В этом случае мы будем игнорировать индекс, который является первым возвращаемым аргументом.
Эти выходные данные показывают, что цикл for проитерировал срез строк и без индекса вывел на экран каждый элемент.
Вы также можете использовать ключевое слово range, чтобы добавить элементы в список:
Здесь мы добавили строку-заполнитель “shark” для каждого элемента в срезе sharks.
Обратите внимание: нам не нужно было использовать пустой идентификатор _, чтобы проигнорировать возвращаемые оператором range значения. Go позволяет пропустить все объявление оператора range, если ни одно из возвращаемых значений не нужно
Также можно использовать оператор range для заполнения значений среза:
В этом примере integers среза инициализируется десятью пустыми значениями, но цикл for устанавливает все значения в списке:
В первом выводе значения integers есть только нули. Затем цикл перебирает все индексы и устанавливает значение для текущего индекса. После этого мы выводим значение integers во второй раз, и на этот раз тут находятся числа от 0 до 9.
Мы также можем использовать оператор range для перебора всех символов в строке:
При выполнении итерации по карте range будет возвращать и ключ, и значение:
Примечание: Важно отметить, что значения карты возвращаются в случайном порядке. Каждый запуск программы может выдать другой результат
Цикл do-while
Цикл do-while отличается от while лишь тем, что его тело будет выполнено хотя бы один раз независимо от условия выполнения цикла. Синтаксис цикла do-while можно описать так (фигурные скобки можно опустить, если выражение только одно):
do { выражение1; …; } while (логич_выражение);
Этот цикл называют циклом с постусловием. Его используют намного реже обычного while. В принципе почти всегда можно обойтись без него, но в определенных ситуациях его использование упрощает код. Допустим требуется вывести на экран отдельные цифры числа. Любое число состоит хотя бы из одной цифры, даже число 0. Можно решить эту задачу с использованием цикла while:
while (a > ) { printf("%d\n", a % 10); a = a 10; }
Но в этом случае, если a равно 0, то цикл не выполнится ни разу. Пришлось бы перед циклом использовать инструкцию if, в которой сравнивать переменную с 0. Использование же цикла do-while решает эту проблему, т. к. его тело один раз выполнится даже при нулевом значении переменной:
do { printf("%d\n", a % 10); a = a 10; } while (a > );
Управляющая конструкция if-then
В некоторых сценариях требуется управлять потоком исполнения команд. Например, если некое значение больше пяти, нужно выполнить одно действие, в противном случае — другое. Подобное применимо в очень многих ситуациях, и здесь нам поможет управляющая конструкция . В наиболее простом виде она выглядит так:
А вот рабочий пример:
В данном случае, если выполнение команды завершится успешно, в консоль будет выведен текст «it works».
Воспользуемся имеющимися у нас знаниями и напишем более сложный сценарий. Скажем, надо найти некоего пользователя в , и если найти его удалось, сообщить о том, что он существует.
Вот что получается после запуска этого скрипта.
Поиск пользователя
Здесь мы воспользовались командой для поиска пользователя в файле . Если команда вам незнакома, её описание можно найти здесь.
В этом примере, если пользователь найден, скрипт выведет соответствующее сообщение. А если найти пользователя не удалось? В данном случае скрипт просто завершит выполнение, ничего нам не сообщив. Хотелось бы, чтобы он сказал нам и об этом, поэтому усовершенствуем код.
Вступление
В Bash имеется множество встроенных проверок и сравнений, что очень удобно во многих ситуациях. Вы, наверное, видели, если такие заявления раньше:
if ; then
Условие в этом примере по сути является командой. Это может звучать странно, но сравнение с квадратными скобками аналогично использованию встроенной команды , например:
if test $foo -ge 3; then
Если $foo больше(G) или равно(E) 3, блок после «then» будет выполнен. Если вы всегда задавались вопросом, почему bash использует или вместо >= или ==, это потому, что этот тип условия исходит из команды, где и — параметры.
И это то, что по сути, проверяет состояние завершения команды. Я объясню это более подробно далее в руководстве.
Также есть встроенные проверки, которые более специфичны для оболочек.
if ; then
Вышеуказанное условие выполняется, если файл «regularfile» существует и
это обычный файл. Обычный файл означает, что это не блок или
символьное устройство или каталог. Таким образом, вы можете быть уверены, что
Файл существует, прежде чем что-то делать с ним. Вы даже можете проверить, если
файл читабелен!
if ; then
Приведенное выше условие выполняется, если файл «readablefile» существует и доступен для чтения. Легко, не правда ли?
Объявление циклов ForClause и Condition
Чтобы учесть множество разных вариантов, существует три различных способа создания циклов for в Go, каждый со своими особенностями. В Go циклы for бывают условными (Condition), ForClause и RangeClause. В этом разделе мы посмотрим, как объявлять и использовать ForClause и Condition.
Давайте сначала посмотрим, как использовать цикл for типа ForClause.
Цикл ForClause определяется с помощью начальное значение, за ним идет условие, а затем изменение счетчика. Они складываются в следующий синтаксис:
Чтобы понять, что делают все эти компоненты, давайте рассмотрим цикл for, который увеличивает значение в указанном диапазоне с помощью синтаксиса ForClause:
Давайте разберем этот цикл по частям.
Первая часть цикла – это i := 0. Это начальное значение:
Он говорит, что мы объявляем переменную i и устанавливаем ее исходное значение 0.
Следующий компонент – условие:
В этом условии заявляется, что цикл должен продолжать работу, пока i меньше 5.
В конце идет изменение счетчика:
Согласно ему, переменная i при каждом прохождении цикла увеличивается на единицу (для этого используется ).
Вывод этой программы выглядит так:
Цикл был выполнен 5 раз. Изначально он присвоил переменной i значение 0, а затем проверил, меньше ли оно пяти. Поскольку значение i было меньше 5, цикл повторялся и выполнял действие fmt.Println(i). После завершения цикла был вызван оператор i ++, и значение переменной i увеличивалось на 1.
Примечание: В программировании, как правило, индексация начинается с 0, поэтому на экране 5 чисел – от 0 до 4.
Начинать с 0 или заканчивать определенным числом не обязательно. Мы можем присвоить любое начальное значение, а также остановиться на любом значении. Это позволяет задать в цикле любой желаемый диапазон:
Например, здесь итерация начинается с 20 (включительно) и идет до 25 (исключительно), поэтому вывод выглядит так:
Изменение счетчика также может быть любым – это называется шагом в других языках.
Для начала попробуйте использовать изменение счетчика с положительным значением:
В этом случае цикл for выведет числа от 0 до 15, но с шагом 3, то есть отображаться будет только каждое третье число, вот так:
Мы также можем использовать для этого аргумента отрицательное значение, чтобы выполнить итерацию в обратном направлении, но мы должны соответствующим образом скорректировать исходное значение и аргументы условия:
Здесь мы устанавливаем в переменной i начальное значение 100, используем условие i < 0, чтобы остановиться на 0. Шаг уменьшает значение на 10 с помощью оператора -=. Цикл начинается со значением 100 и заканчивается на 0, с каждой итерацией уменьшаясь на 10. Мы можем увидеть это в выходных данных:
Также можно исключить начальное значение и шаг из синтаксиса for и использовать только условие. Такой цикл называется условным:
На этот раз переменная i объявлена отдельно от цикла for в предыдущей строке кода. В цикле есть только условие, которое проверяет, не меньше ли значение переменной пяти. Пока условие оценивается как true, цикл продолжит итерацию.
В некоторых ситуациях нельзя точно знать, сколько итераций вам потребуется для выполнения определенной задачи. В этом случае вы можете опустить все операторы и использовать ключевое слово break для выхода из цикла:
Например, этот цикл будет полезен при чтении структуры неопределенного размера, такой как :
В предыдущем коде строка buf :=bytes.NewBufferString(“one\ntwo\nthree\nfour\n”) объявляет буфер с некоторыми данными. Поскольку мы не знаем, когда буфер завершится, мы создаем цикл for только с условием, без начального значения и шага. Внутри цикла мы используем строку line, err := buf.ReadString(‘\n’), чтобы цикл мог прочитать строку из буфера и проверить, не было ли при этом ошибки. Если ошибка есть, мы исправляем ее и используем ключевое слово break для выхода из цикла for. Благодаря break не нужно включать условие для остановки цикла.
В этом разделе вы узнали, как объявить цикл ForClause и использовать его для итерации по известному диапазону значений. Также вы научились использовать цикл Condition для итерации по неизвестному диапазону – такой цикл работает, пока не будет выполнено определенное условие. Далее мы посмотрим на RangeClause.
Вложенные циклы
Внимание: для освоения этого раздела необходимо понимание принципов работы с массивами. Часто используют циклы, один из которых выполняется в теле другого, — их называют вложенными
Это может потребоваться для обхода двумерных массивов, генерации данных и много чего ещё. Вкладывать друг в друга можно разные циклы неограниченное количество раз
Часто используют циклы, один из которых выполняется в теле другого, — их называют вложенными. Это может потребоваться для обхода двумерных массивов, генерации данных и много чего ещё. Вкладывать друг в друга можно разные циклы неограниченное количество раз.
Вот примеры кода:
В этом фрагменте был создан двумерный массив chars, по которому мы прошли с помощью одного цикла for, вложенного в другой — тоже for. Для каждой итерации внешнего цикла выполняются все итерации вложенного в него внутреннего. Таким образом, для массива размерности 5 на 5 будет совершено 25 итераций — внешний цикл идёт по строкам, внутренний — по столбцам.
Ещё пример, но теперь уже трёх вложенных циклов:
Тут мы прошлись по значениям из трёх массивов и сгенерировали шесть сообщений с разными приветствиями, именами и вопросами.
Бывают ситуации, когда нужно внутри вложенного цикла прекратить выполнение текущего и того, в который он вложен. Если использовать для этого просто break, мы выйдем только из текущего цикла, а внешний продолжит работать:
Как видно из примера, ожидаемого результата (прекратить работу обоих циклов, если найдено число 5) мы не получили. В таких ситуациях можно использовать, например, проверку с помощью boolean-значения:
Мы вводим во внешний цикл логическую переменную check и присваиваем ей значение false. Если внутри второго цикла работа прекращается оператором break, перед этим check присваивается значение true. После завершения работы вложенного цикла проверяем во внешнем, что находится в нашей переменной check. Если true, значит, вложенный цикл был прерван и требуется прервать текущий.
Вложенные циклы for
Подобно другим типам циклов, одни циклы for могут быть вложены в другие циклы for. В следующем примере мы разместили один for внутри другого for:
#include <iostream>
int main()
{
for (char c = ‘a’; c <= ‘e’; ++c) // внешний цикл по буквам
{
std::cout << c; // сначала выводим букву
for (int i = 0; i < 3; ++i) // внутренний цикл по числам
std::cout << i;
std::cout << ‘\n’;
}
return 0;
}
1 |
#include <iostream> intmain() { for(charc=’a’;c<=’e’;++c)// внешний цикл по буквам { std::cout<<c;// сначала выводим букву for(inti=;i<3;++i)// внутренний цикл по числам std::cout<<i; std::cout<<‘\n’; } return; } |
С одной итерацией внешнего цикла выполняется три итерации внутреннего цикла. Следовательно, результат выполнения программы:
Подстановка команд
Одна из самых полезных возможностей bash-скриптов — это возможность извлекать информацию из вывода команд и назначать её переменным, что позволяет использовать эту информацию где угодно в файле сценария.
Сделать это можно двумя способами.
- С помощью значка обратного апострофа «`»
- С помощью конструкции
Используя первый подход, проследите за тем, чтобы вместо обратного апострофа не ввести одиночную кавычку. Команду нужно заключить в два таких значка:
При втором подходе то же самое записывают так:
А скрипт, в итоге, может выглядеть так:
В ходе его работы вывод команды будет сохранён в переменной , содержимое которой, с помощью команды , попадёт в консоль.
Скрипт, сохраняющий результаты работы команды в переменной
Цикл for
Одним из самых используемых является цикл со счётчиком for. Его синтаксис
for (<инициализация>; <условие продолжения>; <изменение счётчика>){ <тело цикла> }
Например, выведем квадраты первых ста чисел.
int i; for (i = 1; i < 101; i++) { printf("%d ", i*i); }
Одним из замечательных моментов цикла for является то, что он может работать не только с целыми числами.
float num; for (num = 5.3f; num > 0f; num -= 0.2) { printf("%.2f ", num); }
Этот цикл выведет числа от 5.3 до 0.1.
Цикл for может не иметь некоторых «блоков» кода, например, может отсутствовать инициализация, проверка (тогда цикл становится бесконечным) или изменение счётчика.
Вот пример с интегралом, реализованный с применением счётчика for
#include<conio.h> #include<stdio.h> int main() { double sum = 0.0; double a = 0.0; double b = 1.0; double h = 0.01; double x; for (x = a; x < b; x += h) { sum += x*x * h; } printf("%.3f", sum); getch(); }
Давайте рассмотрим кусок кода
double x ; for (x = a; x < b; x += h) { sum += x*x * h; }
Его можно изменить так
double x = a; for (; x < b; x+=h) { sum += x*x*h; }
Более того, используя оператор break, можно убрать условие и написать
double x; for (x = a;; x += h){ if (x>b){ break; } sum += x*x*h; }
или так
double x = a; for (;;){ if (x > b){ break; } sum += x*x*h; x += h; }
кроме того, используя оператор «,», можно часть действий перенести
double x ; for (x = a; x < b; x += h, sum += x*x*h) ;
ЗАМЕЧАНИЕ: несмотря на то, что так можно делать, пожалуйста, не делайте так! Это ухудшает читаемость кода и приводит к трудноуловимым ошибкам.
Давайте решим какую-нибудь практическую задачу посложнее.
Пусть у нас имеется функция f(x). Найдём максимум её производной на отрезке.
Как найти производную функции численно? Очевидно, по определению). Производная функции в точке — это тангенс угла наклона касательной.
Рис. 5 Численное дифференцирование функцииf⁡x′=dxdy
Возьмём точку на кривой с координатами (x; f(x)), сдвинемся на шаг h вперёд, получим точку (x+h, f(x+h)), тогда производная будет
dxdy=f⁡(x+h)-f⁡x(x+h-x)=tg⁡α
То есть, отношение малого приращения функции к малому приращению аргумента.
Внимательный читатель может задать вопрос, почему мы двигаемся вперёд по функции, а не назад. Ну пойдёмте назад
dxdy=f⁡x-f⁡(x-h)h=tg⁡β
Возьмём среднее от этих двух значений, получим
f⁡(x+h)-f⁡(x-h)2h
В общем-то теперь задача становится тривиальной: идём от точки a до точки b и находим минимальное значение производной, а также точку, в которой производная принимает это значение.
Для решения нам понадобятся, как и в задаче с интегралом, переменные для границ области поиска a и b, текущее значение x и шаг h.
Кроме того, необходимо максимальное значение maxVal и координата maxX этого максимального значения.
Для работы возьмём функцию
x•sin⁡x
#include<conio.h> #include<math.h> #include<stdio.h> int main() { double a = 0; double b = 3.0; double h = 0.001; double h2 = h * 2.0; double maxVal = a*sin(a); double maxX = a; double curVal; double x; // Проходим по всей области от a до b // и ищем максимум первой производной // Используем функцию x*sin(x) for (x = a; x < b; x += h) { curVal = ( (x+h)*sin(x+h)-(x-h)*sin(x-h) )/h2; if (curVal > maxVal) { maxVal = curVal; maxX = x; } } printf("max value = %.3f at %.3f", maxVal, maxX); getch(); }
На выходе программа выдаёт
max value = 1.391 at 1.077
Рис. 6 График производной функции x*sin(x)
Численное решение даёт такие же (с точностью до погрешности) результаты, что и наша программа.
Цикл do…while (с постусловием)
Кроме цикла с предусловием while существует вариант, который выполняет хотя бы одну итерацию, а после этого проверяет условие. Это цикл do…while, который называется циклом с постусловием.
Синтаксис do…while:
Сначала отрабатывает действие в <теле цикла>, а потом проверяется <условие выполнения цикла>. Если оно возвращает true, то цикл выполнит действие повторно.
Предположим, что нам обязательно нужно вывести на консоль слово «Привет» хотя бы один раз. Для этого можно использовать следующую конструкцию:
Цикл do…while редко применяется на практике, но его всё же используют:
- если нужно сделать что-то хотя бы единожды — например, вывести слово «Привет», как выше;
- если значение, от которого зависит условие, инициализируется внутри тела цикла.
Пример кода:
С помощью конструкции new Random().nextInt() здесь берётся очередное случайное число. Итог работы таков: цикл будет находить и выводить на консоль случайные числа до тех пор, пока их значение не будет превышать 50.
Диаграмма работы цикла do…while:
Итого
Мы рассмотрели 3 вида циклов:
- – Проверяет условие перед каждой итерацией.
- – Проверяет условие после каждой итерации.
- – Проверяет условие перед каждой итерацией, есть возможность задать дополнительные настройки.
Чтобы организовать бесконечный цикл, используют конструкцию . При этом он, как и любой другой цикл, может быть прерван директивой .
Если на данной итерации цикла делать больше ничего не надо, но полностью прекращать цикл не следует – используют директиву .
Обе этих директивы поддерживают метки, которые ставятся перед циклом. Метки – единственный способ для выйти за пределы текущего цикла, повлиять на выполнение внешнего.
Заметим, что метки не позволяют прыгнуть в произвольное место кода, в JavaScript нет такой возможности.