Урок 8 - Ключевые слова-операторы

...

  • break в разных циклах;
  • continue: опасная игра в «замри с продолжением»

Прежде чем приступить к занятиям, расскажу одну историю.

Это было в 10 классе. Заболел наш физик, и пришёл другой. Он очень интересно рассказывал, а потом дал несколько задач с подробным объяснением решений. На следующем уроке он устроил контрольную. Задачки были очень похожи на прошлые, мы честно передули все решения. И весь класс получил двойки (я, правда, получил тройку, чем страшно горжусь).

Это к тому, что очень легко использовать операторы и ключевые слова, когда покажут, куда их надо вписать. Но при самостоятельном выполнении, вроде бы, аналогичной задачи, можно зайти в тупик самому (что ещё не так страшно) или отправить туда компьютер (что несколько хуже). Поэтому очень важно разобраться не только как, но и почему.

Эти ключевые слова-операторы — такие маленькие, но иногда очень зловредные живчики. В сегодняшнем уроке мы немного прогуляемся «над пропастью», и постарайтесь не упустить ни одной логической мелочи, ибо компьютер не понимает, что такое мелочь, и жестоко мстит за нашу человечность.

Break

Это ключевое слово используется в операторах switch, for, while и do...while — то есть в тех операторах, где программа производит перебор вариантов. Оно прерывает, останавливает перебор дальнейших вариантов. Иногда его называют оператором прерывания. Как это работает в switch, мы уже разбирали. Там все варианты заранее определены программистом, так что достаточно просто поставить это слово в нужном месте.

В операторах циклов программист определяет лишь алгоритм подбора, а конкретные варианты программа ищет уже сама. Поэтому break требует заданного условия.

Break и for

Вот ещё один вариант итерации уже надоевшей нам арифметической прогрессии:

var i, x = 0; for (i = 1; ; i++) { if (i == 11) break x += i if (i == 10) {document.write(x + ".")} else {document.writeln(x + ";")} }

Обратите внимание: в условии цикла не указан диапазон значаний (то есть такой цикл будет продолжаться бесконечно). Но поскольку синтаксис требует наличия трёх элементов в заголовке оператора, мы оставляем вторую точку с запятой. Это так называемый плейсхолдер — «держатель места» отсутствующего значения.

Предупреждение: такие «бесконечные» циклы опасны. Если забыть вставить break или сделать это неграмотно, машина может повиснуть.

Перед тем, как задать значение счётчика, мы задаём условие прерывания. Почему 11? Потому что десятый виток нам ещё нужен. А одиннадцатом (то есть сразу после десятого) инструкция сработает, и цикл принудительно завершится.

Дальше — уже знакомый код выполнения цикла.

Break и while, break и do...while

В операторах while и do...while инструкции с break вставляются после инструкции для шага счётчика (но внутри фигурной скобки, завершающей цикл). Например, чтобы убрать из нашей таблицы умножения последнюю строку, нужно сделать следующее:

var i = 2, j = 2, k; document.write("<table border='1' cellspacing='0' cellpadding='2' align='center'>") while (i <= 10) { document.write("<tr>") k = j while (j < 10) {document.write ("<td>" + k + "&times;" + i + "=" + (i * k) + "</td> ") k++ } document.write("<tr>") i++ if (i == 10) break } document.write("</table>")

Результат:

Аналогично можно поиграть количеством столбцов, задав break для k после k++. На правильность результатов это не повлияет, поскольку саму формулу умножения мы не трогаем.

В do...while всё происходит абсолютно точно так же.

А можно ли, как в предыдущем цикле, снять основной ограничитель и перепоручить всё break?

Можно. Например, если вместо while (i<=10) поставить while (i>=0). Только заниматься подобным экспериментированием всё же не советую.

Continue

Есть такая детская игра: «замри» и «замри с продолжением».

Сейчас продемонстрирую одну довольно опасную штуковину, иллюстрирующую «бородатый» анекдот.

<script type="text/javascript"> <!-- var a = "И ничего...<br>", i = 1, k = 0; document.write("А меня в детстве тётя патефоном ударила.<br>") while (i <= 1) {document.write(a) i++ } //--> </script>

Пока что всё вполне невинно: цикл хоть формально и присутствует, но выполняется один раз:

(Особо дотошные спросят, зачем здесь переменная k. Это приготовленный заранее «спасательный круг». Впрочем, скоро всё узнаете...)

А вот теперь долбанём его патефоном, введём туда такую бяку (не выходя за пределы наших единичек):

<script type="text/javascript"> <!-- var a = "И ничего...<br>", i = 1, k = 0; document.write("А меня в детстве тётя патефоном ударила.<br>") while (i <= 1) {document.write(a) if (i == 1) continue i++ } //--> </script>

И скрипт наш «замер с продолжением», выводя document.write(a) по инструкции continue...

Результат:

FORMAT C:)

Механизм ясен? Достигая continue, программа снова выполняет while, достигая continue, программа сно...

Кстати, теперь понятно, «с чего начинаются вирусы»?

В упомянутой детской игре, если Вы помните, есть команда «отомри». Эту команду у нас выполнит старый знакомый break. Но если мы просто «брякнем» i, то у нас ничего не выйдет: она неизлечимо зациклена на своей единице. Вспомним прежние уроки и воспользуемся переменной k. Только как?..

Помните, была такая шутка про концертмейстера («тут играем, там не играем...»)?

Надо очень точно понять, что где и как будет «играть».

Нам нужно, чтобы с каждым зацикливанием переменная k набирала очко (k++), чтобы, набрав их, допустим, 20, отключить цикл. Если мы поставим это в конец, туда же, где i++, то это нам ничего не даст: после continue цикл возвращается обратно, и туда он просто не доходит. Единственное разумное место — это сразу после document.write(a).

Инструкцию if (k == 20) break тоже бесполезно ставить в конец, по той же причине. Столь же бесполезно ставить её раньше, чем k++. А вот сразу после, и перед if (i == 1) continue, — в самый раз:

<script type="text/javascript"> <!-- var a = "И ничего...<br>", i = 1, k = 0; document.write("А меня в детстве тётя патефоном ударила.<br>") while (i <= 1) {document.write(a) k++ if (k == 20) break if (i == 1) continue i++ } //--> </script>

Действия:

Цикл

1. Выводит «сакраментальную фразу»;

2. Засчитывает очко для k;

3. Проверяет break:

    а) если очков ещё мало, то переход к шагу 4;

    б) если очков 20, то остановка цикла. Конец программы.

4. Начинает всё сначала.

Результат:

Обратите внимание: на переменную k при объявлении был назначен нуль. Если бы этого назначения не было, его нужно было бы сделать дополнительно перед циклом while.

Примечание к синтаксису: может быть, Вы обратили внимание (а если не обратили, то плохо), что break и continue в наших «ифах» не заключены в фигурные скобки (хотя по идее должны быть заключены). Дело в том, что если в инструкции оператора if...else находится только одно выражение, то эти скобки не обязательны. Впрочем, можно и поставить.

Слово-оператор continue может использоваться и в других видах циклов. Только помните о технике безопасности!

Для начала, пожалуй, хватит. Есть и некоторые другие, менее важные, «помощники операторов», но с ними мы будем знакомиться в конкретных примерах.

А сейчас самое время заняться массивами.

Итак, мы узнали:

как прервать цикл или, наоборот, «зациклить».

К следующему уроку

К списку уроков JavaScript

(© А. Фролов)