# Глава 4.2. Циклы for и range-for Цикл `for` удобен для обхода элементов контейнера и для выполнения действий заранее известное количество раз. Он применяется, если в теле цикла не требуется изменять его условие. ## Цикл for Вместо формального определения начнём с примера. Перепишем этот `while` на `for`: ```cpp {.example_for_playground .example_for_playground_002} int i = 5; while(i <= 25) { std::print("{} ", i); i += 5; } ``` ``` 5 10 15 20 25 ``` Так выглядит цикл `for`, делающий то же самое: ```cpp {.example_for_playground .example_for_playground_003} for (int i = 5; i <= 25; i += 5) { std::print("{} ", i); } ``` Внутри круглых скобок цикла `for` точкой с запятой разделены три выражения: {#block-for-explanation} - Инициализация. Срабатывает один раз в начале цикла. Мы создали счётчик `i` и присвоили ему стартовое значение 5. - Условие. Проверяется перед каждым выполнением тела цикла. Как только условие возвращает `false`, цикл прерывается. В нашем случае условие — это `i <= 25`. - Итерация. Это действие, совершаемое после завершения каждого витка цикла для перехода на новый. Здесь мы увеличиваем счётчик: `i += 5`. Так цикл `for` выглядит в общем виде: ```cpp for (инициализация; условие; итерация) { // Тело цикла } ``` Любое из этих выражений может отсутствовать. Если опустить все три, то получится вечный цикл: ```cpp for(;;) { // Бесконечный цикл } ``` Напишите функцию `common_prefix_len()`, которая принимает две строки и возвращает `std::size_t` — длину их общего префикса. {.task_text} Например, для строк `"sort"`, `"something"` функция вернёт 2, потому что общий префикс равен `"so"`. А для строк `"test"`, `"cow"` функция вернёт 0. {.task_text} В своём решении используйте цикл `for`. {.task_text} ```cpp {.task_source #cpp_chapter_0042_task_0020} ``` В инициализаторе цикла заведите счётчик. В условии цикла проверьте, что он меньше длин обеих строк. В теле цикла сравните символы строк по этому индексу. {.task_hint} ```cpp {.task_answer} std::size_t common_prefix_len(std::string s1, std::string s2) { std::size_t len = 0; for (std::size_t i = 0; i < std::min(s1.size(), s2.size()); ++i) { if (s1[i] != s2[i]) { break; } ++len; } return len; } ``` Напишите функцию, которая выводит в консоль таблицу умножения чисел от 1 до `n` в вертикальном представлении. {.task_text} Если `n` меньше 1, функция не должна ничего выводить. {.task_text} Для вывода текста с переносом строки есть функция `std::println()` (вызов от пустой строки `""` приведёт к переносу строки). Для вывода без переноса есть функция `std::print()`. {.task_text} Рассмотрим вывод для `n=3`. Обратите внимание, что между соседними столбцами ставится пробел, но после последнего — только перенос строки: {.task_text} 1x1=1 2x1=2 3x1=3 1x2=2 2x2=4 3x2=6 1x3=3 2x3=6 3x3=9 {.task_text} ```cpp {.task_source #cpp_chapter_0042_task_0030} void show_multiplication_table(int n) { } ``` Организуйте вложенный цикл. {.task_hint} ```cpp {.task_answer} void show_multiplication_table(int n) { for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { const std::string trailing_symbol = (j == n) ? "" : " "; std::print("{}x{}={}{}", j, i, j*i, trailing_symbol); } std::println(); } } ``` ## Цикл range-for {#block-range-for} С помощью `for` можно организовать ещё один вариант циклов. Он известен как `range-for` и применяется для итерации по диапазону (range) значений. Например, по контейнеру. Так выглядит подсчёт гласных букв английского алфавита в строке с помощью `range-for`: ```cpp {.example_for_playground .example_for_playground_004} const std::string vowels = "aeiou"; const std::string text = "what are vowels?"; std::size_t count = 0; for (char c: text) { if (vowels.contains(c)) { ++count; } } std::println("Number of vowels in text: {}", count); ``` ``` Number of vowels in text: 5 ``` Общий вид цикла `range-for`: ```cpp for(инициализация переменной: диапазон) { // Тело цикла } ``` В круглых скобках цикла заводится переменная того же типа, что и элементы диапазона. Затем после двоеточия указывается сам диапазон. Напишите функцию `count_letter()`, которая принимает два аргумента: строку и символ. Она должна вернуть значение типа `std::size_t` — количество вхождений данного символа в строку. {.task_text} В своём решении воспользуйтесь циклом range-for. {.task_text} ```cpp {.task_source #cpp_chapter_0042_task_0040} ``` Пример цикла: `for (char letter: s)`. {.task_hint} ```cpp {.task_answer} std::size_t count_letter(std::string s, char c) { std::size_t count = 0; for (char letter: s) { if (letter == c) { ++count; } } return count; } ``` ---------- ## Резюме - У цикла `for` есть вариация: `range-for` для прохода по диапазонам. - Цикл `for` применяется, если в теле цикла не требуется изменять его условие.
Отправка...
Наша группа в telegram. Здесь можно задавать вопросы и общаться.
Задонатить. Если вам нравится курс, вы можете поддержать развитие площадки!