Цикл while в C++ | Уроки С++
Обновл. 24 Сен 2020 |
На этом уроке мы детально рассмотрим цикл while, его конструкцию, особенности и использование.
Цикл while
Цикл while является самым простым из 4-х циклов, которые есть в языке C++. Он очень похож на ветвление if/else:
while (условие)
тело цикла;
Цикл while объявляется с использованием ключевого слова while. В начале цикла обрабатывается условие
. Если его значением является true (любое ненулевое значение), то тогда выполняется тело цикла
.
Однако, в отличие от оператора if, после завершения выполнения тела цикла
, управление возвращается обратно к while и процесс проверки условия повторяется. Если условие опять является true, то тогда тело цикла
выполняется еще раз.
Например, следующая программа выводит все числа от 0 до 9:
#include <iostream> int main() { int count = 0; while (count < 10) { std::cout << count << » «; ++count; } std::cout << «done!»; return 0; }
#include <iostream> int main() { int count = 0; while (count < 10) { std::cout << count << » «; ++count; } std::cout << «done!»; return 0; } |
Результат выполнения программы:
0 1 2 3 4 5 6 7 8 9 done!
Рассмотрим детально эту программу. Во-первых, инициализируется переменная: int count = 0;
0 < 10
имеет значение true, поэтому выполняется тело цикла. В первом стейтменте мы выводим 0
, а во втором — выполняем инкремент переменной count
. Затем управление возвращается к началу цикла while для повторной проверки условия. Условие 1 < 10
имеет значение true, поэтому тело цикла выполняется еще раз. Тело цикла будет повторно выполняться до тех пор, пока переменная count
не будет равна 10
, только в том случае, когда результат условия 10 < 10
будет false, цикл завершится.Тело цикла while может и вообще не выполняться, например:
#include <iostream> int main() { int count = 15; while (count < 10) { std::cout << count << » «; ++count; } std::cout << «done!»; return 0; }
#include <iostream> int main() { int count = 15; while (count < 10) { std::cout << count << » «; ++count; } std::cout << «done!»; return 0; } |
Условие 15 < 10
сразу принимает значение false, и тело цикла пропускается. Единственное, что выведет эта программа:
done!
Бесконечные циклы
С другой стороны, если условие цикла всегда принимает значение true, то и сам цикл будет выполняться бесконечно. Это называется бесконечным циклом. Например:
#include <iostream> int main() { int count = 0; while (count < 10) // это условие никогда не будет false std::cout << count << » «; // поэтому эта строка будет выполняться постоянно return 0; // а эта строка никогда не выполнится }
#include <iostream> int main() { int count = 0; while (count < 10) // это условие никогда не будет false std::cout << count << » «; // поэтому эта строка будет выполняться постоянно return 0; // а эта строка никогда не выполнится } |
Поскольку переменная count
не увеличивается на единицу в этой программе, то условие count < 10
всегда будет true. Следовательно, цикл никогда не будет завершен, и программа будет постоянно выводить
.
Мы можем преднамеренно объявить бесконечный цикл следующим образом:
while (1) // или while (true) { // Этот цикл будет выполняться бесконечно }
while (1) // или while (true) { // Этот цикл будет выполняться бесконечно } |
Единственный способ выйти из бесконечного цикла — использовать операторы return, break, goto, выбросить исключение или воспользоваться функцией exit().
Программы, которые работают до тех пор, пока пользователь не решит остановить их, иногда преднамеренно используют бесконечные циклы вместе с операторами return, break или функцией exit() для завершения цикла. Распространена такая практика в серверных веб-приложениях, которые работают непрерывно и постоянно обслуживают веб-запросы.
Счетчик цикла while
Часто нам нужно будет, чтобы цикл выполнялся определенное количество раз. Для этого обычно используется переменная в виде счетчика цикла. Счетчик цикла — это целочисленная переменная, которая объявляется с единственной целью: считать, сколько раз выполнился цикл. В вышеприведенных примерах переменная count
является счетчиком цикла.
Счетчикам цикла часто дают простые имена, такие как i
, j
или k
. Однако в этих именах есть одна серьезная проблема. Если вы захотите узнать, где в вашей программе используется счетчик цикла и воспользуетесь функцией поиска символов i
, j
или k
, то в результате получите половину своей программы, так как i
j
или k
используются во многих именах. Следовательно, лучше использовать iii
, jjj
или kkk
в качестве имен для счетчиков. Они более уникальны, их значительно проще найти, и они выделяются в коде. А еще лучше использовать «реальные» имена для переменных, например, count
или любое другое имя, которое предоставляет контекст использования этой переменной.Также для счетчиков цикла лучше использовать тип signed int. Использование unsigned int может привести к неожиданным результатам. Например:
#include <iostream> int main() { unsigned int count = 10; // Считаем от 10 к 0 while (count >= 0) { if (count == 0) std::cout << «blastoff!»; else std::cout << count << » «; —count; } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include <iostream> int main() { unsigned int count = 10; // Считаем от 10 к 0 while (count >= 0) { if (count == 0) std::cout << «blastoff!»; else std::cout << count << » «; —count; } return 0; } |
Взгляните на эту программу еще раз и постарайтесь найти ошибку.
Оказывается, эта программа представляет собой бесконечный цикл. Она начинается с вывода
, как и предполагалось, но затем «сходит с рельсов» и начинает отсчет с 4294967295
. Почему? Потому что условие цикла count >= 0
никогда не будет ложным! Когда count = 0
, то и условие 0 >= 0
имеет значение true, выводится blastoff
, а затем выполняется декремент переменной count
, происходит переполнение и значением переменной становится 4294967295
. И так как условие 4294967295 >= 0
является истинным, то программа продолжает свое выполнение. А поскольку счетчик цикла является типа unsigned, то он никогда не сможет быть отрицательным, а так как он никогда не сможет быть отрицательным, то цикл никогда не завершится.
Правило: Всегда используйте тип signed int для счетчиков цикла.
Итерации
Каждое выполнение цикла называется итерацией (или «повтором»).
Поскольку тело цикла обычно является блоком, и поскольку этот блок выполняется по новой с каждым повтором, то любые переменные, объявленные внутри тела цикла, создаются, а затем и уничтожаются по новой. В следующем примере переменная z
создается и уничтожается 6 раз:
#include <iostream> int main() { int count = 1; int result = 0; // переменная result определена здесь, поскольку она нам понадобится позже (вне тела цикла) while (count <= 6) // итераций будет 6 { int z; // z создается здесь по новой с каждой итерацией std::cout << «Enter integer #» << count << ‘:’; std::cin >> z; result += z; // Увеличиваем значение счетчика цикла на единицу ++count; } // z уничтожается здесь по новой с каждой итерацией std::cout << «The sum of all numbers entered is: » << result; return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include <iostream> int main() { int count = 1; int result = 0; // переменная result определена здесь, поскольку она нам понадобится позже (вне тела цикла) while (count <= 6) // итераций будет 6 { int z; // z создается здесь по новой с каждой итерацией std::cout << «Enter integer #» << count << ‘:’; std::cin >> z; result += z; // Увеличиваем значение счетчика цикла на единицу ++count; } // z уничтожается здесь по новой с каждой итерацией std::cout << «The sum of all numbers entered is: » << result; return 0; } |
Для фундаментальных типов переменных это нормально. Для не фундаментальных типов переменных (таких как структуры или классы) это может сказаться на производительности. Следовательно, не фундаментальные типы переменных лучше определять перед циклом.
Обратите внимание, переменная count
объявлена вне тела цикла. Это важно и необходимо, поскольку нам нужно, чтобы значение переменной сохранялось на протяжении всех итераций (не уничтожалось по новой с каждым повтором цикла).
Иногда нам может понадобиться выполнить что-то при достижении определенного количества итераций, например, вставить символ новой строки. Это легко осуществить, используя оператор остатка от деления со счетчиком цикла:
#include <iostream> int main() { int count = 1; while (count <= 50) { // Выводим числа до 10 (перед каждым числом добавляем 0) if (count < 10) std::cout << «0» << count << » «; else std::cout << count << » «; // выводим остальные числа // Если счетчик цикла делится на 10 без остатка, то тогда вставляем символ новой строки if (count % 10 == 0) std::cout << «\n»; // Увеличиваем значение счетчика цикла на единицу ++count; } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <iostream> int main() { int count = 1; while (count <= 50) { // Выводим числа до 10 (перед каждым числом добавляем 0) if (count < 10) std::cout << «0» << count << » «; else std::cout << count << » «; // выводим остальные числа // Если счетчик цикла делится на 10 без остатка, то тогда вставляем символ новой строки if (count % 10 == 0) std::cout << «\n»; // Увеличиваем значение счетчика цикла на единицу ++count; } return 0; } |
Результат выполнения программы:
01 02 03 04 05 06 07 08 09 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
Вложенные циклы while
Также одни циклы while могут быть вложены внутри других циклов while. В следующем примере внутренний и внешний циклы имеют свои собственные счетчики. Однако, обратите внимание, условие внутреннего цикла использует счетчик внешнего цикла!
#include <iostream> int main() { int outer = 1; while (outer <= 5) { int inner = 1; while (inner <= outer) std::cout << inner++ << » «; // Вставляем символ новой строки в конце каждого ряда std::cout << «\n»; ++outer; } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include <iostream> int main() { int outer = 1; while (outer <= 5) { int inner = 1; while (inner <= outer) std::cout << inner++ << » «; // Вставляем символ новой строки в конце каждого ряда std::cout << «\n»; ++outer; } return 0; } |
Результат выполнения программы:
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
Тест
Задание №1
Почему в программе, приведенной выше, переменная inner
объявлена внутри блока while, а не сразу после объявления переменной outer
(вне блока while)?
Ответ №1
Переменная inner
объявлена внутри блока while так, чтобы она была восстановлена (и повторно инициализирована значением 1
) каждый раз, когда выполняется внешний цикл. Если бы переменная inner
была объявлена вне внешнего цикла while, то её значение никогда не было бы сброшено до 1
, или нам бы пришлось это сделать самостоятельно с помощью операции присваивания. Кроме того, поскольку переменная inner
используется только внутри внешнего цикла while, то имеет смысл объявить её именно там. Помните, что переменные нужно объявлять максимально близко к их первому использованию!
Задание №2
Напишите программу, которая выводит буквы английского алфавита от a
до z
вместе с кодами из ASCII-таблицы.
Подсказка: Чтобы выводить символы как целые числа — используйте оператор static_cast.
Ответ №2
#include <iostream> int main() { char mychar = ‘a’; while (mychar <= ‘z’) { std::cout << mychar << » » << static_cast<int>(mychar) << «\n»; ++mychar; } return 0; }
#include <iostream> int main() { char mychar = ‘a’; while (mychar <= ‘z’) { std::cout << mychar << » » << static_cast<int>(mychar) << «\n»; ++mychar; } return 0; } |
Задание №3
Измените программу из последнего подраздела «Вложенные циклы» так, чтобы она выводила следующее:
5 4 3 2 1
4 3 2 1
3 2 1
2 1
1
Ответ №3
#include <iostream> int main() { int outer = 5; while (outer >= 1) { int inner = outer; while (inner >= 1) std::cout << inner— << » «; // Вставляем символ новой строки в конце каждого ряда std::cout << «\n»; —outer; } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include <iostream> int main() { int outer = 5; while (outer >= 1) { int inner = outer; while (inner >= 1) std::cout << inner— << » «; // Вставляем символ новой строки в конце каждого ряда std::cout << «\n»; —outer; } return 0; } |
Задание №4
Теперь сделайте так, чтобы цифры выводились следующим образом (используя программу из предыдущего задания):
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
Подсказка: Разберитесь сначала, как вывести числа следующим образом:
X X X X 1
X X X 2 1
X X 3 2 1
X 4 3 2 1
5 4 3 2 1
Ответ №4
#include <iostream> int main() { // Цикл с 1 до 5 int outer = 1; while (outer <= 5) { // Числа в рядах появляются в порядке убывания, поэтому цикл начинаем с 5 и до 1 int inner = 5; while (inner >= 1) { // Первое число в любом ряде совпадает с номером этого ряда, // поэтому числа должны выводиться только если <= номера ряда (в противном случае, выводится пробел) if (inner <= outer) std::cout << inner << » «; else std::cout << » «; // вставляем дополнительные пробелы —inner; } // Этот ряд вывели, переходим к следующему std::cout << «\n»; ++outer; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#include <iostream> int main() { // Цикл с 1 до 5 int outer = 1; while (outer <= 5) { // Числа в рядах появляются в порядке убывания, поэтому цикл начинаем с 5 и до 1 int inner = 5; while (inner >= 1) { // Первое число в любом ряде совпадает с номером этого ряда, // поэтому числа должны выводиться только если <= номера ряда (в противном случае, выводится пробел) if (inner <= outer) std::cout << inner << » «; else std::cout << » «; // вставляем дополнительные пробелы —inner; } // Этот ряд вывели, переходим к следующему std::cout << «\n»; ++outer; } } |
Оценить статью:
Загрузка. ..Поделиться в социальных сетях:
for, foreach, while и do while
В программировании различные типы циклов применяются для того, чтобы повторить некоторое действие нужное количество раз. Например отсортировать элементы массива или найти факториал числа. Цикл состоит из условия и тела цикла. Код, находящийся в теле, выполняется, когда условие равно true. Каждое повторение цикла называется итерацией.
Типы циклов
Цикл For
for (int i=0; i<10; i++) { тело }
i — это переменная-счётчик, которая сначала равна нулю. До тех пор, пока она меньше 10, выполняется тело цикла, затем счетчик увеличивается на единицу. For — цикл с предусловием. Это значит, что сначала проверяется условие, и если оно true, то тело выполняется. В скобках объявляется тип переменной счётчика и её начальное значение. Затем указывается условие конца цикла и способ, которым изменяется значение счётчика.
Цикл Foreach (или совместный цикл)
for (int element :array) { тело }
Тело этого цикла выполнится для каждого элемента коллекции. В переменной element будет доступен по очереди каждый элемент массива array.
Цикл While
while(i < 10) { тело }
Относится к тому же типу циклов, что и For, — цикл с предусловием. С его помощью можно создать безусловный цикл, например while(1) — бесконечный цикл. Чтобы его закончить, нужно использовать служебное слово break.
Цикл Do While
do { тело } while (i<10)
Do While относится к типу циклов с постусловием. Однако здесь код выполнится как минимум один раз, даже если условие false.
Вложенные циклы
int array[][] = {{1, 2, 3}, {3, 4, 5}}
for (i=0;i<3;i++) {
for (j=0;j<3;j++) {
printf(array[i][j])
}
}
Циклы можно помещать внутрь друг друга. Это удобно для перебора многомерных коллекций. Код в примере выше выведет в консоль значение каждого элемента из двумерного массива array.
Операторы циклов
Break
while (true) // бесконечный цикл
{
std::cout << "Введите 0 чтобы выйти, или любое число чтобы продолжить: ";
int val;
std::cin >> val;
// Выходим из цикла, если пользователь ввел 0
if (val == 0)
break;
}
Оператор break используется для досрочного выхода из цикла. Когда программа встречает break, цикл немедленно завершается и начинает выполняться код, следующий за циклом.
Continue
Оператор Continue даёт циклу команду выйти из текущей итерации и перейти к следующей.
Этот код выведет в консоль все нечетные числа из диапазона от 0 до 10:
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
continue;
}
cout << i << "\n";
}
Цикл for и цикл while в Python — 9 примеров
Циклы в Python позволяют разработчикам повторять определенные части своего кода через ряд циклов, которые называются итерациями. Python поддерживает цикл for и цикл while.
Синтаксис цикла for в Python
Цикл for в Python итерирует по заданной последовательности и обладает следующим синтаксисом:
for <variable> in <iterable>:
for <variable> in range(<number>):
for <variable> in range(<start_number>, <end_number>):
for <variable> in range(<start_number>, <end_number>, <step_size>):
for i, <variable> in enumerate(<iterable>): # с индексом i
for <variable1>, <variable2> in zip(<iterable1>, <iterable2>):
Синтаксис цикла while в Python
Цикл while в Python повторяется, пока выполняется определенное логическое условие и обладает следующим синтаксисом:
while <boolean expression>:
. ..
Как работать с циклами в Python?
Ниже собраны примеры решений основных задач, с которыми сталкиваются Python разработчики и дата-саентисты:
Как перебрать значения списка циклом for?
Циклы for перебирают коллекцию элементов, таких как list или dict, и запускают блок кода с каждым элементом из коллекции.
for i in [0, 1, 2, 3, 4]:
print(i)
# Вывод:
# 0
# 1
# 2
# 3
# 4
Вышеприведенный цикл for выполняет итерацию по списку чисел.
Каждая итерация устанавливает значение i для следующего элемента списка. Итак, сначала это будет 0, затем 1, затем 2 и т.д
Аналогично, цикл работает с любыми типами списков, например, со списком строк:
for x in ['one', 'two', 'three', 'four']:
print(x)
# Вывод:
# one
# two
# three
# four
Часто, необходимо сгенерировать последовательность чисел и обойти ее, для этого удобно использовать функцию range:
for x in range(1, 6):
print(x)
# Вывод:
# 1
# 2
# 3
# 4
# 5
Как получить индекс элемента в цикле for в Python?
Если вы хотите зациклить как элементы списка, так и индекс для элементов, вы можете использовать функцию enumerate:
for index, item in enumerate(['one', 'two', 'three', 'four']):
print(index, '::', item)
# Вывод:
# (0, '::', 'one')
# (1, '::', 'two')
# (2, '::', 'three')
# (3, '::', 'four')
Функция enumerate генерирует кортежи, которые распаковываются в индекс (целое число) и элемент (фактическое значение из списка).
Как перебрать словарь (dict) циклом for?
Ключи словаря в Python можно перебрать циклом for следующим образом:
d = {"a": 1, "b": 2, "c": 3}
for key in d:
print(key)
# Вывод:
# "a"
# "b"
# "c"
Это эквивалентно использованию метода словаря keys:
d = {"a": 1, "b": 2, "c": 3}
for key in d.keys():
print(key)
# Вывод:
# "a"
# "b"
# "c"
Для перебора значений словаря в Python необходимо использовать метод словаря values:
d = {"a": 1, "b": 2, "c": 3}
for value in d.values():
print(values)
# Вывод:
# 1
# 2
# 3
Для перебора ключей и значений словаря используйте метод items:
d = {"a": 1, "b": 2, "c": 3}
for key, value in d.items():
print(key, "::", value)
# Вывод:
# a :: 1
# b :: 2
# c :: 3
Метод items возвращает последовательность кортежей, использование for с несколькими переменными (key, value) называется распаковкой. Ее можно применять и для списков:
collection = [('a', 'b', 'c'), ('x', 'y', 'z'), ('1', '2', '3')]
for i1, i2, i3 in collection:
print('i1 =', i1, ':: i2 =', i2, ':: i3 =', i3)
# Вывод:
# i1 = a :: i2 = b :: i3 = c
# i1 = x :: i2 = y :: i3 = z
# i1 = 1 :: i2 = 2 :: i3 = 3
Как работает цикл while в Python?
Цикл while будет повторять код в блоке, пока условие цикла не станет False. Следующий код выполнит код в блоке цикла 4 раза:
i = 0
while i
Если условие всегда истинно, цикл while будет выполняться бесконечно. Бесконечный цикл можно завершить оператором break, return или исключением.
while True:
print "Infinite loop"
# Вывод:
# Infinite loop
# Infinite loop
# Infinite loop
# ...
Что такое pass в Python или как ничего не делать в цикле?
pass — это нулевой оператор и используется, когда оператор требуется синтаксисом Python (например, в теле цикла for или while), но никакие действия не нужны. Этот оператор можно использовать как заполнитель для кода, который ещё не написан.
for x in range(10):
pass # нам не нужно ничего выполнять или пока не знаем что здесь должно быть, поэтому используем pass
В этом примере ничего не произойдёт. Цикл for завершится без ошибок, но никакие команды или код не будут выполнены. pass позволяет нам успешно выполнять наш код без полной реализации всех команд и действий.
Аналогично, pass можно использовать в циклах while, а также в выборках, определениях функций и т.д.
while x == y:
pass
Как выполнить следующий проход цикла используя оператор continue?
Оператор continue перейдет к следующей итерации цикла, минуя остаток текущего блока кода, но продолжая цикл. Оператор continue может использоваться только внутри цикла:
for i in (0, 1, 2, 3, 4, 5):
if i == 2 or i == 4:
continue
print(i)
# Вывод:
# 0
# 1
# 3
# 5
Обратите внимание, что 2 и 4 не выводятся. Это происходит потому, что continue переходит к следующей итерации, а не продолжает выводить i, когда i==2 или i==4.
Как досрочно выйти из цикла используя оператор break?
Оператор break моментально прерывает дальнейшее выполнение кода внутри цикла:
i = 0
while i
Использование операторы break, как и в случае с continue, допускаются только внутри циклов.
Оператор break также доступен внутри циклов for:
for i in (0, 1, 2, 3, 4):
print(i)
if i == 2:
break
# Вывод:
# 0
# 1
# 2
Обратите внимание, что 3 и 4 не выводятся после окончания цикла.
Если цикл имеет условие else, оно не выполняется, когда цикл завершается с помощью оператора break.
Как выполнить код после завершения цикла используя оператор else?
Циклы for и while могут иметь условие else.
Условие else выполняется только после завершения цикла for путем итерации до завершения в случае цикла for или после завершения цикла while, когда его условное выражение становится ложным.
Пример условия else в цикле for:
for i in range(3):
print(i)
else:
print('done')
# Вывод:
# 0
# 1
# 2
# done
Пример условия else в цикле while:
i = 0
while i
Условие else не выполняется, если цикл завершается принудительно (например, с помощью оператора break или путем вызова исключения):
for i in range(2):
print(i)
if i == 1:
break
else:
print('done')
# Вывод:
# 0
# 1
Зачем использовать конструкцию for/while … else?
Частой задачей на использование конструкции for … else является реализация поиска, например:
a = [1, 2, 3, 4]
for i in a:
if type(i) is not int:
print(i)
break
else:
print("no exception")
# Вывод:
# no exception
Для простоты восприятия, можно читать эту конструкцию как «if not break» или «if not found».
Как вернуть значение из цикла оператором return?
Оператор return выводит значение из функции, не выполняя следующий за нем код.
Если у вас есть цикл внутри функции, использование return внутри цикла эквивалентно break, поскольку остальная часть кода цикла не выполняется. Код следующий за циклом также не выполняется:
def break_loop():
for i in range(1, 5):
if (i == 2):
return(i)
print(i)
return(5)
break_loop()
# Вывод:
# 1
# 2
Если вы используете return во вложенных циклах, оператор return прервёт все циклы:
def break_all():
for j in range(1, 5):
for i in range(1, 4):
if i*j == 6:
print('return')
return(i)
print(i*j)
# Вывод:
# 1
# 2
# 3
# 2
# 4
# return (потому что 2*3=6, остальные итерации обоих циклов не выполняются)
# 3 (это результат работы функции из return)
Упражнение для закрепления
Обойдите и распечатайте все четные числа из списка в том же порядке, в котором они были получены. Не печатайте цифры, которые появятся в последовательности после 237.
numbers = [
951, 402, 984, 651, 360, 69, 408, 319, 601, 485, 980, 507, 725, 547, 544,
615, 83, 165, 141, 501, 263, 617, 865, 575, 219, 390, 984, 592, 236, 105, 942, 941,
386, 462, 47, 418, 907, 344, 236, 375, 823, 566, 597, 978, 328, 615, 953, 345,
399, 162, 758, 219, 918, 237, 412, 566, 826, 248, 866, 950, 626, 949, 687, 217,
815, 67, 104, 58, 512, 24, 892, 894, 767, 553, 81, 379, 843, 831, 445, 742, 717,
958, 609, 842, 451, 688, 753, 854, 685, 93, 857, 440, 380, 126, 721, 328, 753, 470,
743, 527
]
# your code goes here
numbers = [
951, 402, 984, 651, 360, 69, 408, 319, 601, 485, 980, 507, 725, 547, 544,
615, 83, 165, 141, 501, 263, 617, 865, 575, 219, 390, 984, 592, 236, 105, 942, 941,
386, 462, 47, 418, 907, 344, 236, 375, 823, 566, 597, 978, 328, 615, 953, 345,
399, 162, 758, 219, 918, 237, 412, 566, 826, 248, 866, 950, 626, 949, 687, 217,
815, 67, 104, 58, 512, 24, 892, 894, 767, 553, 81, 379, 843, 831, 445, 742, 717,
958, 609, 842, 451, 688, 753, 854, 685, 93, 857, 440, 380, 126, 721, 328, 753, 470,
743, 527
]
# your code goes here
for number in numbers:
if number == 237:
break
if number % 2 == 1:
continue
print(number)
test_object("number", undefined_msg="Define a object `number` using the code from the tutorial to print just the desired numbers from the Упражнение description. ",incorrect_msg="Your `number` object is not correct, You should use an `if` statement and a `break` statement to accomplish your goal.")
success_msg("Great work!")
10.1. Циклы | Популярный Linux
Это одна из основных разновидностей циклов. И она значительно отличается от аналога в языке C.
for arg in [list]
do
команда(ы)...
done
На каждом проходе цикла, переменная-аргумент цикла arg последовательно, одно за другим, принимает значения из списка list. |
for arg in "$var1" "$var2" "$var3" ... "$varN"
# На первом проходе, $arg = $var1
# На втором проходе, $arg = $var2
# На третьем проходе, $arg = $var3
# . ..
# На N-ном проходе, $arg = $varN
# Элементы списка заключены в кавычки для того, чтобы предотвратить возможное разбиение их на отдельные аргументы (слова).
Элементы списка могут включать в себя шаблонные символы.
Есл ключевое слово do находится в одной строке со словом for, то после списка аргументов (перед do) необходимо ставить точку с запятой.
for arg in [list] ; do
Пример 10-1. Простой цикл for
#!/bin/bash
# Список планет.
for planet in Меркурий Венера Земля Марс Юпитер Сатурн Уран Нептун Плутон
do
echo $planet
done
echo
# Если 'список аргументов' заключить в кавычки, то он будет восприниматься как единственный аргумент .
for planet in "Меркурий Венера Земля Марс Юпитер Сатурн Уран Нептун Плутон"
do
echo $planet
done
exit 0
Каждый из элементов [списка] может содержать несколько аргументов. Это бывает полезным при обработке групп параметров. В этом случае, для принудительного разбора каждого из аргументов в списке, необходимо использовать инструкцию set (см. Пример 11-14). |
Пример 10-2. Цикл for с двумя параметрами в каждом из элементов списка
#!/bin/bash
# Список планет.
# Имя кажой планеты ассоциировано с расстоянием от планеты до Солнца (млн. миль).
for planet in "Меркурий 36" "Венера 67" "Земля 93" "Марс 142" "Юпитер 483"
do
set — $planet # Разбиение переменной "planet" на множество аргументов (позиционных параметров).
# Конструкция "--" предохраняет от неожиданностей, если $planet "пуста" или начинается с символа "-".
# Если каждый из аргументов потребуется сохранить, поскольку на следующем проходе они будут "забиты" новыми значениями,
# То можно поместить их в массив,
# original_params=("$@")
echo "$1 в $2,000,000 миль от Солнца"
#----две табуляции---к параметру $2 добавлены нули
done
# (Спасибо S.C., за разъяснения.)
exit 0
В качестве списка, в цикле for, можно использовать переменную.
Пример 10-3. Fileinfo: обработка списка файлов, находящегося в переменной
#!/bin/bash
# fileinfo.sh
FILES="/usr/sbin/privatepw
/usr/sbin/pwck
/usr/sbin/go500gw
/usr/bin/fakefile
/sbin/mkreiserfs
/sbin/ypbind" # Список интересующих нас файлов.
# В список добавлен фиктивный файл /usr/bin/fakefile.
echo
for file in $FILES
do
if [ ! -e "$file" ] # Проверка наличия файла.
then
echo "Файл $file не найден."; echo
continue # Переход к следующей итерации.
fi
ls -l $file | awk '{ print $8 " размер: " $5 }' # Печать 2 полей.
whatis `basename $file` # Информация о файле.
echo
done
exit 0
В [списке] цикла for могут быть использованы имена файлов, которые в свою очередь могут содержать символы-шаблоны.
Пример 10-4. Обработка списка файлов в цикле for
#!/bin/bash
# list-glob.sh: Создание список файлов в цикле for с использованием
# операции подстановки имен файлов ("globbing").
echo
for file in *
do
ls -l "$file" # Список всех файлов в $PWD (текущем каталоге).
# Напоминаю, что символу "*" соответствует любое имя файла,
# однако, в операциях подстановки имен файлов ("globbing"),
# имеются исключения — имена файлов, начинающиеся с точки.
# Если в каталоге нет ни одного файла, соответствующего шаблону,
# то за имя файла принимается сам шаблон.
# Чтобы избежать этого, используйте ключ nullglob
# (shopt -s nullglob).
# Спасибо S.C.
done
echo; echo
for file in [jx]*
do
rm -f $file # Удаление файлов, начинающихся с "j" или "x" в $PWD.
echo "Удален файл \"$file\"".
done
echo
exit 0
Если [список] в цикле for не задан, то в качестве оного используется переменная $@ — список аргументов командной строки. Оень остроумно эта особенность проиллюстрирована в Пример A-18.
Пример 10-5. Цикл for без списка аргументов
#!/bin/bash
# Попробуйте вызвать этот сценарий с аргументами и без них и посмотреть на результаты.
for a
do
echo -n "$a "
done
# Список аргументов не задан, поэтому цикл работает с переменной '$@'
#+ (список аргументов командной строки, включая пробельные символы).
echo
exit 0
При создании списка аргументов, в цикле for допускается пользоваться подстановкой команд. См. Пример 12-42, Пример 10-10 и Пример 12-36.
Пример 10-6. Создание списка аргументов в цикле for с помощью операции подстановки команд
#!/bin/bash
# Цикл for со [списком], созданным с помощью подстановки команд.
NUMBERS="9 7 3 8 37.53"
for number in `echo $NUMBERS` # for number in 9 7 3 8 37.53
do
echo -n "$number "
done
echo
exit 0
Более сложный пример использования подстановки команд при создании списка аргументов цикла.
Пример 10-7. grep для бинарных файлов
#!/bin/bash
# bin-grep.sh: Поиск строк в двоичных файлах.
# замена "grep" для бинарных файлов.
# Аналогично команде "grep -a"
E_BADARGS=65
E_NOFILE=66
if [ $# -ne 2 ]
then
echo "Порядок использования: `basename $0` string filename"
exit $E_BADARGS
fi
if [ ! -f "$2" ]
then
echo "Файл \"$2\" не найден. "
exit $E_NOFILE
fi
for word in $( strings "$2" | grep "$1" )
# Инструкция "strings" возвращает список строк в двоичных файлах.
# Который затем передается по конвейеру команде "grep", для выполнения поиска.
do
echo $word
done
# Как указывает S.C., вышепрведенное объявление цикла for может быть упрощено
# strings "$2" | grep "$1" | tr -s "$IFS" '[\n*]'
# Попробуйте что нибудь подобное: "./bin-grep.sh mem /bin/ls"
exit 0
Еще один пример.
Пример 10-8. Список всех пользователей системы
#!/bin/bash
# userlist.sh
PASSWORD_FILE=/etc/passwd
n=1 # Число пользователей
for name in $(awk 'BEGIN{FS=":"}{print $1}' < "$PASSWORD_FILE" )
# Разделитель полей = : ^^^^^^
# Вывод первого поля ^^^^^^^^
# Данные берутся из файла паролей ^^^^^^^^^^^^^^^^^
do
echo "Пользователь #$n = $name"
let "n += 1"
done
# Пользователь #1 = root
# Пользователь #2 = bin
# Пользователь #3 = daemon
# . ..
# Пользователь #30 = bozo
exit 0
И заключительный пример использования подстановки команд при создании [списка].
Пример 10-9. Проверка авторства всех бинарных файлов в текущем каталоге
#!/bin/bash
# findstring.sh:
# Поиск заданной строки в двоичном файле.
directory=/usr/local/bin/
fstring="Free Software Foundation" # Поиск файлов от FSF.
for file in $( find $directory -type f -name '*' | sort )
do
strings -f $file | grep "$fstring" | sed -e "s%$directory%%"
# Команде "sed" передается выражение (ключ -e),
#+ для того, чтобы изменить обычный разделитель "/" строки поиска и строки замены
#+ поскольку "/" - один из отфильтровываемых символов.
# Использование такого символа порождает сообщение об ошибке (попробуйте).
done
exit 0
# Упражнение:
# ---------------
# Измените сценарий таким образом, чтобы он брал
#+ $directory и $fstring из командной строки.
Результат работы цикла for может передаваться другим командам по конвейеру.
Пример 10-10. Список символических ссылок в каталоге
#!/bin/bash
# symlinks.sh: Список символических ссылок в каталоге.
directory=${1-`pwd`}
# По-умолчанию в текущем каталоге,
# Блок кода, который выполняет аналогичные действия.
# ----------------------------------------------------------
# ARGS=1 # Ожидается один аргумент командной строки.
#
# if [ $# -ne "$ARGS" ] # Если каталог поиска не задан...
# then
# directory=`pwd` # текущий каталог
# else
# directory=$1
# fi
# ----------------------------------------------------------
echo "символические ссылки в каталоге \"$directory\""
for file in "$( find $directory -type l )" # -type l = символические ссылки
do
echo "$file"
done | sort # В противном случае получится неотсортированный список.
# Как отмечает Dominik 'Aeneas' Schnitzer,
#+ в случае отсутствия кавычек для $( find $directory -type l )
#+ сценарий "подавится" именами файлов, содержащими пробелы.
exit 0
Вывод цикла может быть перенаправлен со stdout в файл, ниже приводится немного модифицированный вариант предыдущего примера, демонстрирующий эту возможность. в файл.
exit 0
Оператор цикла for имеет и альтернативный синтаксис записи — очень похожий на синтаксис оператора for в языке C. Для этого используются двойные круглые скобки.
Пример 10-12. C-подобный синтаксис оператора цикла for
#!/bin/bash
# Два вапианта оформления цикла.
echo
# Стандартный синтаксис.
for a in 1 2 3 4 5 6 7 8 9 10
do
echo -n "$a "
done
echo; echo
# +==========================================+
# А теперь C-подобный синтаксис.
LIMIT=10
for ((a=1; a <= LIMIT ; a++)) # Двойные круглые скобки и "LIMIT" без "$".
do
echo -n "$a "
done # Конструкция заимствована из 'ksh93'.
echo; echo
# +=========================================================================+
# Попробуем и C-шный оператор "запятая".
for ((a=1, b=1; a <= LIMIT ; a++, b++)) # Запятая разделяет две операции, которые выполняются совместно.
do
echo -n "$a-$b "
done
echo; echo
exit 0
См. так же Пример 25-15, Пример 25-16 и Пример A-7.
---
А сейчас пример сценария, который может найти "реальное" применение.
Пример 10-13. Работа с командой efax в пакетном режиме
#!/bin/bash
EXPECTED_ARGS=2
E_BADARGS=65
if [ $# -ne $EXPECTED_ARGS ]
# Проверка наличия аргументов командной строки.
then
echo "Порядок использования: `basename $0` phone# text-file"
exit $E_BADARGS
fi
if [ ! -f "$2" ]
then
echo "Файл $2 не является текстовым файлом"
exit $E_BADARGS
fi
fax make $2 # Создать fax-файлы из текстовых файлов.
for file in $(ls $2.0*) # Все файлы, получившиеся в результате преобразования.
# Используется шаблонный символ в списке.
do
fil="$fil $file"
done
efax -d /dev/ttyS3 -o1 -t "T$1" $fil # отправить.
# Как указывает S.C., в цикл for может быть вставлена сама команда отправки в виде:
# efax -d /dev/ttyS3 -o1 -t "T$1" $2.0*
# но это не так поучительно [;-)].
exit 0
Оператор while проверяет условие перед началом каждой итерации и если условие истинно (если код возврата равен 0), то управление передается в тело цикла. В отличие от циклов for, циклы while используются в тех случаях, когда количество итераций заранее не известно.
while [condition]
do
command...
done
Как и в случае с циклами for/in, при размещении ключевого слова do в одной строке с объявлением цикла, необходимо вставлять символ ";" перед do.
while [condition] ; do
Обратите внимание: в отдельных случаях, таких как использование конструкции getopts совместно с оператором while, синтаксис несколько отличается от приводимого здесь.
Пример 10-14. Простой цикл while
#!/bin/bash
var0=0
LIMIT=10
while [ "$var0" -lt "$LIMIT" ]
do
echo -n "$var0 " # -n подавляет перевод строки.
var0=`expr $var0 + 1` # допускается var0=$(($var0+1)).
done
echo
exit 0
Пример 10-15. Другой пример цикла while
#!/bin/bash
echo
while [ "$var1" != "end" ] # возможна замена на while test "$var1" != "end"
do
echo "Введите значение переменной #1 (end - выход) "
read var1 # Конструкция 'read $var1' недопустима (почему?).
echo "переменная #1 = $var1" # кавычки обязательны, потому что имеется символ "#".
# Если введено слово 'end', то оно тоже выводится на экран.
# потому, что проверка переменной выполняется в начале итерации (перед вводом).
echo
done
exit 0
Оператор while может иметь несколько условий. Но только последнее из них определяет возможность продолжения цикла. В этом случае синтаксис оператора цикла должен быть несколько иным.
Пример 10-16. Цикл while с несколькими условиями
#!/bin/bash
var1=unset
previous=$var1
while echo "предыдущее значение = $previous"
echo
previous=$var1 # запомнить предыдущее значение
[ "$var1" != end ]
# В операторе "while" присутствуют 4 условия, но только последнее управляет циклом.
# *последнее* условие - единственное, которое вычисляется.
do
echo "Введите значение переменной #1 (end - выход) "
read var1
echo "текущее значение = $var1"
done
# попробуйте самостоятельно разобраться в сценарии works.
exit 0
Как и в случае с for, цикл while может быть записан в C-подобной нотации, с использованием двойных круглых скобок (см. так же Пример 9-29).
Пример 10-17. C-подобный синтаксис оформления цикла while
#!/bin/bash
# wh-loopc.sh: Цикл перебора от 1 до 10.
LIMIT=10
a=1
while [ "$a" -le $LIMIT ]
do
echo -n "$a "
let "a+=1"
done # Пока ничего особенного.
echo; echo
# +=================================================================+
# А теперь оформим в стиле языка C.
((a = 1)) # a=1
# Двойные скобки допускают наличие лишних пробелов в выражениях.
while (( a <= LIMIT )) # В двойных скобках символ "$" перед переменными опускается.
do
echo -n "$a "
((a += 1)) # let "a+=1"
# Двойные скобки позволяют наращивание переменной в стиле языка C.
done
echo
# Теперь, программисты, пишущие на C, могут чувствовать себя в Bash как дома.
exit 0
Стандартное устройство ввода stdin, для цикла while, можно перенаправить на файл с помощью команды перенаправления < в конце цикла. |
Оператор цикла until проверяет условие в начале каждой итерации, но в отличие от while итерация возможна только в том случае, если условие ложно.
until [condition-is-true]
do
command...
done
Обратите внимание: оператор until проверяет условие завершения цикла ПЕРЕД очередной итерацией, а не после, как это принято в некоторых языках программирования.
Как и в случае с циклами for/in, при размещении ключевого слова do в одной строке с объявлением цикла, необходимо вставлять символ ";" перед do.
until [condition-is-true] ; do
Пример 10-18. Цикл until
#!/bin/bash
until [ "$var1" = end ] # Проверка условия производится в начале итерации.
do
echo "Введите значение переменной #1 "
echo "(end - выход)"
read var1
echo "значение переменной #1 = $var1"
done
exit 0
Однажды в Ираке. Документальный фильм Би-би-си
Фильм доступен для просмотра только на территории России, Украины, Армении, Азербайджана, Беларуси, Казахстана, Кыргызстана, Молдовы, Таджикистана, Туркменистана и Узбекистана.
В пятой серии о последствиях вторжения рассуждает профессор университета Мосула Омар Мохамед, который в анонимном блоге документировал историю трех лет, когда город находился под гнетом ИГИЛ-а (деятельность террористической организации ИГИЛ на территории России запрещена). В повествование возвращается Валид Несиф - теперь гражданин Канады с университетским образованием, а также суннитка Ум Кусай, которая, рискуя жизнью, укрывала солдат-шиитов, за которыми охотился ИГИЛ.
В четвертой серии фильма историю павшего диктатора рассказывают переводчик-волонтер Самир Аль-Джассим, который участвовал в поимке Саддама, старший аналитик ЦРУ Джон Никсон, который допрашивал свергнутого президента, и военный полицейский Брэндон Барфилд, сопровождавший Саддама Хусейна на виселицу.
Третья серия рассказывает о самой напряженной битве войны. Центральными героями эпизода стали внештатный фотограф Нью-Йорк Таймс Эшли Гилбертсон, работавший в паре с журналистом Декстером Филкинсом и переживший в Фаллудже личную трагедию, а также жительница Фаллуджи Нидаль Абед, которой в роковой день 4 ноября 2004 года нужно было отвезти к доктору своего двухлетнего сына Мустафу.
Вторая серия рассказывает о следующем этапе войны, когда Ирак охватили восстания против оккупации.
Главные герои - американский подполковник Нейт Сассаман, который оказался не готов к безжалостной партизанской войне, с которой столкнулась армия коалиции, и Аллаа Адел, которой было 12 лет, когда её ранило в лицо шрапнелью от бомбы, предназначавшейся для американских военных.
Первая серия фильма рассказывает о том, с какими чувствами иракцы ожидали весной 2003 года начала войны с США, и о том, чем обернулись для них первые месяцы вторжения.
Центральным героем серии стал Валид Несиф, который, как и многие иракские подростки того времени, считал жизнь при Саддаме угнетающей и увлекался западным образом жизни и западной культурой. Валид пел в рок-группе, учил английский язык по песням и фильмам и, как и многие иракцы, с нетерпением ждал прихода американцев.
Русская служба Би-би-си имеет право на распространение этого документального фильма исключительно на территории России, Украины, Армении, Азербайджана, Беларуси, Казахстана, Кыргызстана, Молдовы, Таджикистана, Туркменистана и Узбекистана.
Лазутчица «Проекта Веритас» разоблачает Си-эн-эн
На снимке руководитель Project Veritas James O’Keefe
Photo: Gage Skidmore
Когда в Миннеаполисе раздавались заключительные речи на процессе бывшего полицейского Дерека Шовина, на следующий день осужденного по всем пунктам, в нью-йоркском Верховном суде был возбужден иск о защите чести и достоинства против соцсети «Твиттер» (я не раз отмечал, а сейчас повторю, что в Нью-Йорке это суд низшей инстанции, тогда как высшей является суд апелляционный).
«Твиттер» закрыл аккаунт «Проекта Веритас» еще в феврале. Личный счет истца, основателя правого «Проекта Веритас» Джеймса О’Кифа, был перманентно забанен «Твиттером» в прошлый четверг после того, как истец начал помещать в нем плоды своей последней тайной операции. Сотрудница «Проекта Веритас» закадрила на сайте знакомств «Тиндер» технического директора Си-эн-эн Чарли Честера и тайно записывала разговоры с ним.
Я предполагаю, это делалось законно, ибо Нью-Йорк является у нас «однопартийным» (one-party) штатом и в том смысле, что в нем разрешается записывать разговоры с ведома одного из их участников (зд. party).
«Что делает любой репортер Си-эн-эн, – откровенничал за столом Честер, – это он говорит им (выступающим), что говорить. Это всегда так, как будто им указывают направление еще до того, как они откроют рот. Единственные люди, которых мы пускаем в эфир, – это в основном те, кто в прошлом четко доказал, что ловит подсказку на лету».
«Гляди, что мы сделали, – заявил с гордостью технический директор, – мы скинули Трампа… Я стопроцентно уверен, что, если бы не Си-эн-эн, я не знаю, прокатили ли бы тогда Трампа».
Это бахвальство было процитировано на сайте «Фокс ньюс» и сопровождалось слсдующим комментарием: «Не думаю, чтобы Си-эн-эн так уже сильно повлияло на результат выборов: ну, сколько вообще у них зрителей? Меньше миллиона в день? Даже если больше, вряд ли намного, ведь Си-эн-эн – это вчерашний канал».
По словам Честера, Си-эн-эн «придумало версию» о неблагополучном здоровье Трампа, «о котором мы ничего не знали». Он прямо назвал это пропагандой, целью которой было избавиться от Оранжевого.
«Трамп, ну, я не знаю, у него вроде дрожала рука или что-то в этом духе, – откровенничал Честер. – Мы приглашали очень много медиков, которые обсуждали версию, это была спекуляция, что у него был неврологический дефект, он выживал из ума, он непригоден, знаешь, и все такое… Мы создавали версию, о которой мы ничего не знали».
Одновременно канал пытался для контраста показать, что Джо Байден пышит здоровьем. «Мы всегда показывали кадры, где он бежит трусцой, – вспоминал он. – Он в летных темных очках… Мы как бы изображали его молодым стариканом».
Честер считает, что Байден дотянет до конца своего первого срока. «Он, б.., не помрет, но я и не переживал бы, – говорил техдиректор. – (Камала Харрис), скорее всего, будет вести себя на заседаниях кабинета как стерва, и вы будете ненавидеть ее как начальницу, но она, б…, настоящая и лучшее из того, что у нас есть».
Среди прочего Честер поделился с барышней своим наблюдением, что «непредвзятых новостей не бывает». Он привел ряд доказательств этого тезиса. Если кто-то наивно решил, что Си-эн-эн освещал эпидемию коронавируса без задних мыслей, то ему нужно послушать его технического директора.
«Ковид? – слишится голос Честера. – Ломовые рейтинги, так? Вот почему мы постоянно показывали число смертей на правой стороне (экрана)… Страх реально движет рейтингом… Начните снова показывать числа, потому что это самое увлекательное, что у нас есть!»
«Грустные новости, которые идут сплошняком, вообще-то не очень котируются, если только они не касаются (зрителя) непосредственно, – делился с барышней Честер. – Никто не говорит это открытым текстом, но это очевидно».
В другом разговоре он предсказал, что, когда публика устанет от ковида, Си-эн-эн «начнет сосредоточиваться главным образом на климате».
«Изменения климата будут для Си-эн-эн новым ковидом, – сказал Честер в другом диалоге. – Мы сосредоточимся на этом».
– Главное направление было избавиться от Трампа, – заметил Честер. – Это не говорилось открыто, но это то, что происходило. Следующим номером нашей программы будет просвещение (зрителя) насчет изменений климата.
– Ты думаешь, будет нагоняться страх по поводу климата? – спросила тайная агентесса О’Кифа.
– Ага, – ответил техдиректор. – Страх хорошо продается.
– Кто это решает?
– Глава канала.
– Кто это? Закер? – спросила лазутчица, имея в виду президента Си-эн-эн Джеффа Закера.
– Закер, он самый.
Владимир КОЗЛОВСКИЙ
в то время как Заявление (C) | Документы Microsoft
- 000Z" data-article-date-source="ms.date"> 11.04.2016
- 2 минуты на чтение
В этой статье
Оператор и
позволяет повторять оператор, пока указанное выражение не станет ложным.
Синтаксис
итерация-инструкция :
while ( выражение ) инструкция
Выражение должно иметь арифметический или указательный тип.Исполнение произведено следующим образом:
Выражается выражение .
Если выражение изначально ложно, тело оператора
, тогда как
никогда не выполняется, и управление переходит от оператора, а
к следующему оператору в программе.Если выражение истинно (ненулевое), тело оператора выполняется, и процесс повторяется, начиная с шага 1.
Оператор и
также может завершиться, когда выполняется разрыв
, goto
или return
в теле оператора. Используйте оператор continue
, чтобы завершить итерацию, не выходя из цикла while
. Оператор continue
передает управление следующей итерации оператора , а оператора
.
Это пример оператора , а
:
в то время как (i> = 0)
{
строка1 [я] = строка2 [я];
я--;
}
В этом примере копируются символы из строка2
в строка1
. Если i
больше или равно 0, строка2 [i]
назначается строка1 [i]
, а i
уменьшается. Когда i
достигает или опускается ниже 0, выполнение оператора , а
прекращается.
См. Также
Оператор while (C ++)
цикл while - cppreference.com
Повторно выполняет инструкцию, пока значение выражения не станет равным нулю. Тест проводится перед каждой итерацией.
[править] Синтаксис
attr-spec-seq (необязательно) while ( выражение ) инструкция | |||||||||
выражение | - | любое выражение скалярного типа.Это выражение оценивается перед каждой итерацией, и если оно равно нулю, цикл завершается. |
выписка | - | любой оператор, обычно составной оператор, который служит телом цикла. |
attr-spec-seq | - | (C23) необязательный список атрибутов, применяемых к оператору цикла |
[править] Объяснение
Оператор while
вызывает повторное выполнение оператора (также называемого телом цикла ) до тех пор, пока выражение (также называемое управляющим выражением ) не станет равным нулю. Повторение происходит независимо от того, вводится ли тело цикла нормально или с помощью перехода в середину оператора.
Вычисление выражения происходит перед каждым выполнением оператора (если оно не введено с помощью goto). Если управляющее выражение необходимо вычислить после тела цикла, можно использовать цикл do-while.
Если выполнение цикла необходимо прервать в какой-то момент, оператор break можно использовать как оператор завершения.
Если выполнение цикла необходимо продолжить в конце тела цикла, оператор continue может использоваться как ярлык.
Программа с бесконечным циклом имеет неопределенное поведение, если цикл не имеет наблюдаемого поведения (ввод-вывод, изменчивый доступ, атомарная операция или операция синхронизации) в любой части своего оператора или выражения. Это позволяет компиляторам оптимизировать все ненаблюдаемые циклы, не доказывая, что они завершаются. Единственным исключением являются петли, в которых
выражение - постоянное выражение; while (true)
всегда бесконечный цикл.
Как и все другие операторы выбора и итерации, оператор while устанавливает область действия блока: любой идентификатор, введенный в выражение, выходит за пределы области действия после оператора. | (начиная с C99) |
[править] Примечания
Логические выражения и выражения указателя часто используются в качестве выражений, управляющих циклом. Логическое значение false
и значение нулевого указателя любого типа указателя сравниваются равными нулю.
[править] Ключевые слова
в то время как
[править] Пример
#include#include #include перечисление {РАЗМЕР = 8}; int main (пусто) { // тривиальный пример массив int [РАЗМЕР], n = 0; while (n <РАЗМЕР) массив [n ++] = rand ()% 2; put ("Массив заполнен!"); п = 0; while (n <РАЗМЕР) printf ("% d", массив [n ++]); printf ("\ п"); // классическая реализация strcpy () // (копирует строку с завершающим нулем из src в dst) char src [] = "Привет, мир", dst [sizeof src], * p = dst, * q = src; в то время как (* p ++ = * q ++) ; // пустой оператор помещает (dst); }
Выход:
Массив заполнен! 1 0 1 1 1 1 0 0 Привет мир
[править] Ссылки
Стандарт- C17 (ISO / IEC 9899: 2018):
- 6. 8.5.1 Оператор while (стр: 109)
- C11 (ISO / IEC 9899: 2011):
- 6.8.5.1 Оператор while (стр: 151)
- C99 (ISO / IEC 9899: 1999):
- 6.8.5.1 Оператор while (стр: 136)
- Стандарт C89 / C90 (ISO / IEC 9899: 1990):
- 3.6.5.1 Оператор while
[править] См. Также
7.7 - Введение в циклы и операторы while
Введение в циклы
А теперь начинается самое интересное - в следующем наборе уроков мы рассмотрим петли. Циклы - это конструкции потока управления, которые позволяют фрагменту кода выполнять многократно, пока не будет выполнено какое-либо условие. Циклы добавляют значительную гибкость вашему набору инструментов программирования, позволяя делать многие вещи, которые в противном случае были бы трудными.
Например, предположим, вы хотите вывести все числа от 1 до 10. Без петель вы можете попробовать что-то вроде этого:
#include int main () { std :: cout << "1 2 3 4 5 6 7 8 9 10"; std :: cout << "готово!"; возврат 0; } |
Это выполнимо, но становится все меньше, когда вы хотите печатать больше чисел: что, если вы хотите напечатать все числа от 1 до 1000? Это было бы совсем немного! Но такая программа доступна для записи, потому что во время компиляции мы знаем, сколько чисел мы хотим напечатать.
А теперь немного изменим параметры. Что, если бы мы хотели попросить пользователя ввести число, а затем распечатать все числа от 1 до числа, введенного пользователем? Число, которое введет пользователь, неизвестно во время компиляции. Итак, как мы можем решить эту проблему?
Пока ведомости
Оператор while (также называемый циклом while) является самым простым из трех типов циклов, которые предоставляет C ++, и имеет определение, очень похожее на определение оператора if
:
в то время как (состояние) утверждение;
Оператор while
объявляется с использованием ключевого слова while. Когда выполняется оператор while,
оценивается условие
. Если условие оценивается как истинно
, соответствующий оператор выполняется.
Однако, в отличие от оператора if
, после завершения выполнения оператора управление возвращается на вершину оператора while, и процесс повторяется. Это означает, что оператор
while,
будет продолжать цикл до тех пор, пока условие оценивается как true
.
Давайте взглянем на простой цикл while, который печатает все числа от 1 до 10:
#include int main () { int count {1}; while (count <= 10) { std :: cout << count << ''; ++ счетчик; } std :: cout << "готово!"; возврат 0; } |
Это выводит:
1 2 3 4 5 6 7 8 9 10 готово!
Давайте подробнее рассмотрим, что делает эта программа. Сначала счетчик
инициализируется как 1
, это первое число, которое мы напечатаем. Условие count <= 10
равно true
, поэтому инструкция выполняется. В этом случае наш оператор является блоком, поэтому все операторы в блоке будут выполнены. Первый оператор в блоке печатает 1
и пробел, а второй увеличивает счетчик
до 2. Теперь управление возвращается к началу оператора while
, и условие снова оценивается. 2 <= 10
оценивается как истина, поэтому кодовый блок выполняется снова. Цикл будет повторяться до тех пор, пока count
не станет 11
, после чего 11 <= 10
будет оценивать как false
, и оператор, связанный с циклом, будет пропущен. На этом петля закончена.
Хотя эта программа представляет собой немного больше кода, чем ввод всех чисел от 1 до 10, подумайте, насколько легко было бы изменить программу для печати всех чисел от 1 до 1000: все, что вам нужно сделать, это изменить count <= 10
до количество <= 1000
.
В то время как утверждения, которые изначально оцениваются как ложные
Обратите внимание, что если условие изначально оценивается как false
, связанный оператор не будет выполняться вообще. Рассмотрим следующую программу:
#include int main () { int count {15}; while (count <= 10) { std :: cout << count << ''; ++ счетчик; } std :: cout << "готово!"; возврат 0; } |
Условие 15 <= 10
оценивается как false
, поэтому связанный оператор пропускается.Программа продолжается, и единственное, что напечатано, - это готово!
.
Бесконечные петли
С другой стороны, если выражение всегда истинно, цикл while будет выполняться вечно. Это называется бесконечным циклом . Вот пример бесконечного цикла:
#include int main () { int count {1}; while (count <= 10) // это условие никогда не будет ложным { std :: cout << count << ''; // поэтому эта строка будет повторно выполняться } return 0; // эта строка никогда не выполнится } |
Поскольку count
никогда не увеличивается в этой программе, count <= 10
всегда будет истинным.Следовательно, цикл никогда не завершится, и программа будет печатать «1 1 1 1 1» ... навсегда.
Преднамеренные бесконечные циклы
Мы можем объявить намеренный бесконечный цикл следующим образом:
while (true) { // этот цикл будет выполняться вечно } |
Единственный способ выйти из бесконечного цикла - это выполнить оператор return, оператор break, оператор exit, оператор goto, создать исключение или убить программу пользователем.
Вот глупый пример, демонстрирующий это:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include int main () { while (true) // бесконечный цикл { std :: cout << "Повторять цикл (да / нет)? "; char c {}; std :: cin >> c; if (c == 'n') return 0; } возврат 0; } |
Эта программа будет непрерывно повторяться до тех пор, пока пользователь не введет n
в качестве входных данных, после чего оператор if
будет оценивать значение true
и связанный с ним возвратит 0;
вызовет выход из функции main ()
, завершив программу.
Такой цикл часто встречается в приложениях веб-сервера, которые работают непрерывно и обслуживают веб-запросы.
Favor while (true)
для преднамеренных бесконечных циклов.
Переменные цикла
Часто нам нужно, чтобы цикл выполнялся определенное количество раз. Для этого обычно используется переменная цикла, часто называемая счетчиком. Переменная цикла - это целое число, которое используется для подсчета количества выполнений цикла. В приведенных выше примерах переменная count
является переменной цикла.
Переменным цикла часто дают простые имена, например i
, j
или k
. Однако, если вы хотите знать, где в вашей программе используется переменная цикла, и вы используете функцию поиска на i
, j
или k
, функция поиска вернет половину вашей программы! По этой причине некоторые разработчики предпочитают имена переменных цикла, например iii
, jjj
или kkk
. Поскольку эти имена более уникальны, это значительно упрощает поиск переменных цикла и помогает им выделиться как переменные цикла.Еще лучшая идея - использовать «настоящие» имена переменных, такие как count
, или имя, которое дает более подробную информацию о том, что вы считаете (например, userCount
).
Переменные цикла должны быть подписаны
Переменные цикла почти всегда должны быть подписаны, поскольку целые числа без знака могут привести к неожиданным проблемам. Рассмотрим следующий код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include int main () { unsigned int count {10}; // отсчет от 10 до 0 while (count> = 0) { if (count == 0) { std :: cout << "blastoff!"; } else { std :: cout << count << ''; } --счет; } возврат 0; } |
Взгляните на приведенный выше пример и посмотрите, сможете ли вы обнаружить ошибку. Это не очень очевидно.
Оказывается, эта программа представляет собой бесконечный цикл. Он начинается с печати 10 9 8 7 6 5 4 3 2 1 взлет!
по желанию, но затем сходит с рельсов и начинает обратный отсчет с 4294967295
. Почему? Потому что условие цикла count> = 0
никогда не будет ложным! Когда count 0
, 0> = 0
истинно. Затем выполняется --count
, и count возвращается к 4294967295
(при условии 32-битных целых чисел).И поскольку 4294967295> = 0
истинно, программа продолжается. Поскольку count
беззнаковый, он никогда не может быть отрицательным, а поскольку он никогда не может быть отрицательным, цикл не завершится.
Переменные цикла должны иметь тип (подписанный) int.
Делать что-то каждые N итераций
Каждый раз, когда выполняется цикл, он называется итерацией.
Часто нам нужно что-то делать на каждой 2-й, 3-й или 4-й итерации, например выводить новую строку. Это легко сделать с помощью оператора модуля на нашем счетчике:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include // Перебираем все числа от 1 до 50 int main () { int count {1}; while (count <= 50) { // распечатываем число (числа в блоке меньше 10 с ведущим 0 для форматирования) if (count <10) { std :: cout < <'0'; } std :: cout << count << ''; // если переменная цикла делится на 10, вывести новую строку if (count% 10 == 0) { std :: cout << '\ n'; } // увеличиваем счетчик цикла ++ count; } возврат 0; } |
Эта программа дает результат:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
Вложенные петли
Также возможно вложить петли внутрь других петель. В следующем примере у внутреннего и внешнего цикла есть свои собственные счетчики. Однако обратите внимание, что выражение цикла для внутреннего цикла также использует счетчик внешнего цикла!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include // Цикл между 1 и 5 int main () { int external {1}; while (external <= 5) { // цикл между 1 и внешним int inner {1}; в то время как (внутренний <= внешний) { std :: cout << inner << ''; ++ внутренний; } // выводим новую строку в конце каждой строки std :: cout << '\ n'; ++ внешний; } возврат 0; } |
Эта программа напечатает:
1 1 2 1 2 3 1 2 3 4 1 2 3 4 5
Время проведения теста
Почему в приведенной выше программе переменная
inner
объявлена внутри блока while, а не сразу после объявления external
?Показать решение
Внутренняя переменная объявляется внутри блока while, поэтому она воссоздается (и повторно инициализируется до 1) каждый раз при выполнении внешнего цикла. Если бы переменная inner была объявлена перед внешним циклом while, ее значение никогда не было бы сброшено до 1, или нам пришлось бы сделать это с помощью оператора присваивания. Кроме того, поскольку переменная inner используется только внутри блока внешнего цикла while, имеет смысл объявить ее там. Помните, что объявляйте переменные в минимально возможной области видимости!
Напишите программу, которая печатает буквы от a до z вместе с их кодами ASCII.
Показать подсказку
Чтобы напечатать символы как целые числа, вы должны использовать static_cast.
Показать решение
#include int main () { char myChar {'a'}; while (myChar <= 'z') { std :: cout << myChar << '' << static_cast ++ myChar; } возврат 0; } |
Инвертируйте пример вложенных циклов, чтобы он напечатал следующее:
5 4 3 2 1 4 3 2 1 3 2 1 2 1 1
Показать решение
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include // Цикл между 5 и 1 int main () { int external {5}; while (external> = 1) { // цикл между внутренним и 1 int inner {outer}; в то время как (внутренний> = 1) { std :: cout << inner-- << ''; } // выводим новую строку в конце каждой строки std :: cout << '\ n'; - наружный; } возврат 0; } |
Теперь напечатайте числа так:
1 2 1 3 2 1 4 3 2 1 5 4 3 2 1
Подсказка: сначала выясните, как заставить его печатать вот так:
Х Х Х Х 1 Х Х Х 2 1 Х Х 3 2 1 4 х 3 2 1 5 4 3 2 1
Показать решение
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | // Спасибо Шиве за это решение #include int main () { // Есть 5 строк, мы можем выполнить цикл от 1 до 5 int external {1 }; while (external <= 5) { // Элементы строки отображаются в порядке убывания, поэтому начните с 5 и перейдете к 1 int inner {5}; while (inner> = 1) { // Первое число в любой строке совпадает с номером строки // Таким образом, число должно быть напечатано, только если оно <= номер строки, пробел в противном случае if (inner <= outer) std :: cout << inner << ''; еще std :: cout << ""; // лишние пробелы исключительно для форматирования --inner; } // Строка напечатана, перейти к следующей строке std :: cout << '\ n'; ++ внешний; } возврат 0; } |
Онлайн-тест C - Циклы while - CCN, CDAC, CGI
В этом разделе онлайн-теста C основное внимание уделяется «циклам пока». Эти тестовые вопросы нужно практиковать, чтобы улучшить свои навыки программирования на языке C, необходимые для различных собеседований (собеседования в кампусе, пешеходные собеседования, собеседования в компании), размещения, вступительных экзаменов и других конкурсных экзаменов. Ответить на эти вопросы может любой, кто занимается изучением языка программирования C. Это могут быть новички, новички, выпускники инженерных специальностей или опытные ИТ-специалисты. Наши вопросы онлайн-теста C содержат подробные объяснения ответов, которые помогают лучше понять концепции C.Вот список вопросов онлайн-теста C по «Циклам пока» с ответами, пояснениями и / или решениями:
1. Что будет на выходе следующего кода C?
#include
int main ()
{
while ()
printf («В цикле while»);
printf («После цикла \ n»);
}
a) В цикле while после цикла
b) После цикла
c) Ошибка времени компиляции
d) Бесконечный цикл
Посмотреть ответ
Ответ: c
Объяснение: Нет.
2. Что будет на выходе следующего кода C?
#include
int main ()
{
do
printf («В цикле while»);
а (0);
printf («После цикла \ n»);
}
a) В цикле while
b)
В цикле while после цикла
c) После цикла
d) Бесконечный цикл
Посмотреть ответ
Ответ: b
Объяснение: Нет.
3. Что будет на выходе следующего кода C?
#include
int main ()
{
int i = 0;
do {
i ++;
printf («В цикле while \ n»);
} в то время как (i <3);
}
а)
В цикле while В цикле while В цикле while
б)
В цикле while В цикле while
c) Зависит от компилятора
d) Ошибка времени компиляции
Посмотреть ответ
Ответ: a
Объяснение: Нет.
4. Сколько раз проверяется значение i в следующем C-коде?
#include
int main ()
{
int i = 0;
do {
i ++;
printf ("в цикле while \ n");
} в то время как (i <3);
}
a) 2
b) 3
c) 4
d) 1
Посмотреть ответ
Ответ: b
Пояснение: Нет.
5. Сколько раз проверяется значение i в следующем C-коде?
#include
int main ()
{
int i = 0;
в то время как (i <3)
i ++;
printf («В цикле while \ n»);
}
a) 2
b) 3
c) 4
d) 1
Посмотреть ответ
Ответ: c
Пояснение: Нет.
6. Что будет на выходе следующего кода C?
#include
void main ()
{
int i = 2;
до
{
printf («Hi»);
} в то время как (i <2)
}
a) Ошибка времени компиляции
b) Hi Hi
c) Hi
d) Варьируется
Посмотреть ответ
Ответ: a
Объяснение: Нет.
7. Что будет на выходе следующего кода C?
#include
void main ()
{
int i = 0;
в то время как (++ i)
{
printf ("H");
}
}
a) H
b) H печатается бесконечное количество раз
c) Ошибка времени компиляции
d) варьируется
Просмотреть ответ
Ответ: b
Объяснение: Нет.
8. Что будет на выходе следующего кода C?
#include
void main ()
{
int i = 0;
до
{
printf («Привет»);
} при этом (i! = 0);
}
a) Ничего
b) H печатается бесконечно
c) Hello
d) Ошибка времени выполнения
Посмотреть ответ
Ответ: c
Объяснение: Нет.
Sanfoundry Global Education & Learning Series - Язык программирования C.
Примите участие в конкурсе сертификации Sanfoundry, чтобы получить бесплатную Почетную грамоту. Присоединяйтесь к нашим социальным сетям ниже и будьте в курсе последних конкурсов, видео, стажировок и вакансий!
Преобразовать For в while, While в Do-While, Do-while в цикл for
Циклы в C
Язык программирования C поддерживает три типа операторов цикла: цикл for, цикл while и цикл do-while. Каждая структура петли была разработана для разных целей. Давайте посмотрим на синтаксисы и их графические схемы.
Для петли
для (
<начальная выписка>;
<выражение условия>;
<Повторить шаг (и)>
)
{
<Операторы цикла>;
}
Для контурной схемы
Синтаксис цикла while
и (<выражение условия>)
{
<Операторы цикла>;
}
Блок-схема цикла while
Синтаксис цикла Do-While
до
{
<Операторы цикла>;
} , а (<выражение условия>);
Синтаксис цикла Do-While
Конверсии петель
Цикл For был разработан для выполнения для определенного количества итераций, и в нем есть секция оператора инициализации для инициализации счетчика итераций.В цикле while или do while нет раздела инициализации. Пользователь должен написать оператор инициализации перед запуском цикла. Циклы Do и while отличаются тем, как они проверяют условие. Цикл while сначала проверяет условие перед входом в цикл. Однако do-while не проверяет условие и входит в цикл для первой итерации.
Преобразование цикла For в цикл while
Чтобы преобразовать цикл for в цикл while, нам нужно просто добавить оператор инициализации перед циклом while.
/ * Для цикла * /
внутр i;
для (i = 0; i <10; i ++)
{
}
/ * Цикл For преобразован в цикл while * /
int i = 0; / *
, а (i <10)
{
i ++;
}
Преобразование «пока» в «цикл»
Чтобы преобразовать цикл while в цикл for, нам нужно опустить оператор инициализации.
/ * цикл while * /
, а (* str ++! = NULL)
{
длина ++;
}
/ * Цикл while преобразован в цикл for * /
для (; * str! = NULL; str ++)
{
длина ++;
}
Выполнить «пока» для преобразования цикла «пока» / «пока»
Цикл Do while очень хорош, когда вам нужно один раз войти в итерацию, а затем проверить условие выхода.Цикл For и while сначала проверяет условие, а затем входит. Поэтому нам нужно добавить оператор, чтобы условие стало истинным перед запуском цикла. Таким образом, цикл for и while войдет в первую итерацию, как цикл do while.
/ * Выполнить цикл while * /
до
{
статус = check_connection ();
} , а (статус == TIMEOUT);
/ * Цикл Do While преобразован в цикл for * /
статус = ТАЙМ-АУТ; / * Условие верно * /
для (; status == TIMEOUT; str ++)
{
статус = check_connection ();
}
/ * Цикл Do While преобразован в цикл for * /
статус = ТАЙМ-АУТ; / * Условие верно * /
, а (статус == TIMEOUT)
{
статус = check_connection ();
}
Цикл For / While, выполняемый при преобразованиях
Цикл Do while входит в итерацию один раз, а затем проверяется условие выхода.В то время как цикл for и while всегда проверяет предыдущее условие. Это причина того, почему циклы While / For и циклы do-while не очень совместимы. Не пытайтесь преобразовать цикл for / while в цикл do-while. Это добавит ненужный дополнительный код.
/ * Для цикла * /
внутр i;
для (i = 0; i <10; i ++)
{
}
/ * цикл while * /
int i = 0;
, а (i <10)
{
i ++;
}
/ * For / While преобразовано в цикл Do while (не рекомендуется) * /
int i = 0;
до
{
, если (i> = 10) перерыв;
i ++;
} , а (ИСТИНА);
Похожие темы
Как писать повторяющиеся операторы на C? [пока, пока, пример, блок-схема]
Написать синтаксис для цикла for, while и do while?
Когда цикл do-while предпочтительнее, чем цикл while, Приведите пример?
Написать операторы бесконечного цикла для while, do-while и for?
О наших авторах : Team EQA
Вы просмотрели 1 страницу из 248.