3 / Циклические конструкции

Регулярно в программировании необходимо повторять какое-либо действие до тех пор, пока выполняется условие. Эту задачу решают циклические конструкции.

Цикл while

Ты мог наблюдать ситуацию, когда нажимаешь кнопку на сайте и ничего не происходит. Причин может быть множество: например, нестабильное интернет-соединение или сервер с базой данных перегружен. В таком случае, когда подключение сразу не прошло, его стоит повторить. И только после нескольких попыток выдать сообщение об ошибке.

Тогда наш алгоритм будет иметь следующие шаги:

1) Отправить запрос на подключение к базе.
2) Если не получилось и количество попыток меньше 3:
вфвв• Увеличить количество попыток на 1;
вфвв• Вернуться к шагу 1.
3) Если подключение удалось, идём дальше.
4) Если подключение не удалось, то выдаём ошибку.

Получается, что при определённых условиях мы должны повторять одни и те же действия.

Давай теперь рассмотрим более простой пример и разберём его:

function loop(n) {
let number = 1;
let result = "";
while (number <= n) {
result = result + number + " ";
number = number + 1;
}
return result;
}
  • Данная функция выводит числа от до n через пробел.
  • Внутри цикла while пробел " " мы добавляем, чтобы числа не сливались.
  • Вызови функцию и передай в качестве параметра число 5. Результат: "1 2 3 4 5 ".

Как работает данная функция?

Для начала мы создали две переменные:
  • number, которой присвоили 1, далее будет увеличиваться на единицу до n;
  • result, которой присвоили пустую строку "".

Давай по шагам посмотрим, как будут меняться значения переменных number и result:

Шаги цикла

  • Можно заметить, что переменная result равна своему значению на предыдущем шаге с добавлением number. Например, на шаге два result сначала равен "1". Потом мы к result добавляем number (который равен 2) и пробел. А в конце второго шага result уже будет равен "1 2".
  • И повторяем эти действия, пока number меньше либо равен (в нашем примере пяти).
fff· Для этого используем слово while (пока).
fff· После него в круглых скобках пишем условие, при выполнении которого будут выполняться команды.
fff· А в фигурных скобках пишем сами команды, которые необходимо повторять.

  • Как только number станет больше n, цикл завершится, и браузер перейдёт к командам, написанным после закрывающей фигурной скобки.
  • В конце возвращаем результат: return result;
function loop(n) {
let number = 1; // создаём переменную number и присваиваем ей 1
let result = ""; // создаём переменную result и присваиваем ей пустую строку ""
while (number <= n) { // пока number меньше либо равен n
result = result + number + " "; // добавляем к result значение number и пробел
number = number + 1; // увеличиваем number на 1
} // конец цикла
return result; // возвращаем результат
}
Упражнения
3.1.1. Напиши функцию, которая выводит подряд числа через пробел. На вход она должна принимать два параметра: с какого и по какое выводить числа. Если первый параметр больше второго — выводить ошибку.
3.1.2. Напиши функцию, которая выводит подряд числа через пробел. На вход она должна принимать три параметра: с какого числа выводить, по какое число выводить и на сколько увеличить число каждый шаг. Если первый параметр больше второго — выводить ошибку. Например, loop(4, 10, 2) вернёт "4 6 8 10 ".
3.1.3. Напиши функцию, которая выводит числа в обратном порядке через пробел. На вход она должна принимать два параметра: с какого и по какое выводить числа. Если первый параметр больше второго — выводить ошибку.
3.1.4. Напиши функцию, которая cчитает произведение чисел от 1 до n. На вход она должна принимать параметр n.

Цикл do-while

В JS существует ещё один тип циклов do-while, но принцип его работы отличается. В цикле while мы сначала проверяем условие, а потом выполняем действие. А в цикле do-while наоборот — сначала выполняем действие, потом проверяем условие.

Перепишем пример выше с использованием цикла do-while:
function loop(n) {
let number = 1;
let result = "";
do {
result = result + number + " ";
number = number + 1;
} while (number <= n);
return result;
}
Цикл начинается со слова do, после которого в фигурных скобках идёт тело цикла. А заканчивается словом while — условием, при котором этот цикл выполняется.

Вызови функцию с параметром 5
Результат будет такой же, как в прошлом примере: "1 2 3 4 5". В чём же тогда отличие?

Вызови функцию с параметром 0
Результат будет: "1", хотя в цикле while результатом была бы пустая строка "". Это связано с тем, что сначала выполняется тело цикла — в переменную result записывается "1". Затем условие цикла выдаёт false (ложь), но в переменной result остаётся значение "1".

Когда использовать цикл do-while удобнее, чем просто цикл while?

Давай рассмотрим ситуацию, когда программа запрашивает у пользователя какие-то данные, затем анализирует их. Если данные введены неверно, запрашивает их ещё раз. Затем ещё и ещё, пока пользователь не введёт верные данные.
let phone = getPhone(); // запрашиваем телефон
while (notCorrect(phone)) { // пока телефон указан неправильно
phone = getPhone(); // запрашиваем телефон ещё раз
} // конец цикла
Можно написать то же самое короче. В примере выше мы запрашиваем телефон дважды: один раз перед циклом, один раз внутри.
let phone = ""; // создаём переменную для хранения телефона
do { // начало цикла
phone = getPhone(); // запрашиваем телефон
} while (notCorrect(phone)); // повторяем цикл, пока телефон указан неправильно
P.S. На практике цикл while встречается чаще, чем цикл do-while. Но ещё чаще встречается цикл#nbps;for, рассмотрим его далее.
Упражнения
3.2.1. Напиши функцию, которая принимает два параметра: строку и число. Функция должна выводить строку из первого параметра столько раз, сколько задано во втором параметре (но не меньше одного раза). Подсказка: используй оператор + для объединения строк.
3.2.2. Напиши функцию, которая принимает на вход два числа. Первое число показывает, сколько раз надо умножить второе число само на себя (но не меньше одного раза). Функция возвращает результат умножения.
3.2.3. Перепиши функции из упражнений на цикл while с использованием цикла do-while.

Цикл for

В случае, когда мы заранее знаем количество итераций (повторов) цикла, стоит использовать цикл for.
function loop(n) {
let result = "";
for (let number = 1; number <= n; number = number + 1) {
result = result + number + " ";
}
return result;
}
Вызови функцию и убедись, что результат такой же, как в предыдущих примерах.

Вначале мы объявили переменную result.

Далее с помощью слова for объявили начало конструкции цикла.

Далее в круглых скобках мы указали 3 операции, разделённые точкой с запятой:

  1. В первой операции мы объявили переменную number и присвоили ей значение 1. Эта операция будет выполнена только один раз, перед началом цикла.
  2. Во второй мы написали условие, при котором выполняется цикл.
  3. В третьей мы написали, как будет изменяться number при каждой итерации.

Далее в фигурных скобках написали тело цикла: изменение result.
Посмотри ещё раз, как описан цикл while и for. По сути, используются те же сущности.
  • JS сначала выполнит первую операцию let number = 1
  • Затем проверит условие number <= n
  • Если оно истинно, выполнит тело цикла result = result + number + " "
  • Затем выполнит третью операцию number = number + 1
  • Снова проверит условие
  • Если оно истинно, выполнит тело цикла
  • Снова выполнит третью операцию
  • И так до тех пор, пока условие не будет ложно
function loop(n) {
let result = ""; // создаём переменную result и присваиваем ей ""
for (let number = 1; number <= n; number = number + 1) {
// переменная number равна 1, пока number меньше n, увеличивай её на 1
// давай прочитаем этот блок так, как бы его озвучил человек
// с математическим образованием:
// для переменной number от 1 до n, где number каждый раз увеличивается на 1
result = result + number + " "; // добавляем к result значение number и пробел
} // конец цикла return result;
}
Получается, что цикл for — это тот же самый цикл while, но в более простой для чтения записи.

В зависимости от задачи бывает удобно использовать тот или иной цикл.

Как правило цикл while используется тогда, когда мы не знаем заранее какое количество итераций будет в цикле.

На практике тебе придётся вкладывать один цикл в другой. Давай рассмотрим простейший пример, что можно получить с помощью вложенных циклов.

Как написать цикл, который будет выводить числа от до n несколько раз?
function loop(m, n) {
let result = "";
for (let line = 1; line <= m; line = line + 1) {
for (let number = 1; number <= n; number = number + 1) {
result = result + number + " ";
}
result = result + "\n";
}
return result;
}
Вызови функцию loop(3, 5), результат:
"1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
"
Итого: функция вернула на трёх строках (первый параметр вызова) числа от 1 до 5 (второй параметр вызова).

  • Первый for создаёт строки на основе первого параметра вызова, мы говорим циклу, сколько подходов нужно сделать, в нашем случае это три.
  • Далее мы вложили ещё один цикл for, который определяет количество символов в строке.
  • В каждой строке к переменной result добавляем числа от до n (в нашем случае до пяти).
  • Так как нам надо сделать перенос строки после каждого блока, необходимо к переменной result добавить спецсимвол "\n". Обрати внимание, что спецсимвол пишется в кавычках, как строка.

\n — это так называемый специальный символ в JS, обозначающий перенос строки. Например, "Привет,\nМир!" выведется в консоль так: "Привет,
Мир!".

В JS есть и другие специальные символы, все они начинаются с обратного слэша:

  • \t — табуляция,
  • \\ — обратный слэш,
  • \' — одинарная кавычка,
  • \" — двойная кавычка.

После переноса строки переменная line увеличивается на 1. Затем проверяется условие line <= m. Затем снова в переменную result записываются числа от до и перенос строки \n.
Упражнения
3.3.1. Перепиши функции из упражнений на цикл while с использованием цикла for.
3.3.2. Напиши функцию, которая принимает два параметра: ширину и высоту, и выводит прямоугольник звёздочек *. Например:

*****
*****
*****
3.3.3. Напиши функцию, которая принимает один параметр: высота квадрата, и выводит символ по диагонали воображаемого квадрата. Например:

*
*
*
*
*
3.3.4. Напиши функцию, которая выводит на экран таблицу умножения от 1 до 9.