Урок №70. Цикл while

  Юрій  | 

  Оновл. 18 Чер 2020  | 

 282

У цьому уроці ми детально розглянемо цикл while, його конструкцію, особливості та використання.

Цикл while

Цикл while є найпростішим з 4-х циклів в С++ і дуже схожий на розгалуження if/else:

while (умова)
    тіло циклу;

Цикл while оголошується з використанням ключового слова while. Спочатку оброблюється умова. Якщо її значенням є true (будь-яке ненульове значення), то тоді виконується тіло циклу.

Однак, на відміну від оператора if, після завершення виконання тіла циклу, управління повертається назад до while і процес перевірки умови повторюється. Якщо умова знову є true, то тоді тіло циклу виконується ще раз.

Наприклад, наступна програма виводить всі числа від 0 до 9:

Результат виконання програми:

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 може і взагалі не виконуватися. Наприклад:

Умова 15 < 10 відразу приймає значення false, і тіло циклу пропускається. Єдине, що виведе ця програма:

done!

Нескінченні цикли

З іншого боку, якщо умова циклу завжди приймає значення true, то і сам цикл буде виконуватися нескінченно. Це називається нескінченним циклом. Наприклад:

Оскільки змінна count не збільшується на одиницю в програмі, то умова count < 10 завжди буде true. Відповідно, цикл ніколи не завершиться і програма буде постійно виводити 0 0 0 0 0 ... .

Ми можемо навмисно оголосити нескінченний цикл наступним чином:

Єдиний спосіб вийти з нескінченного циклу — використати один з наступних операторів: return, break, exit, goto або згенерувати виняток.

Програми, які працюють до тих пір, поки користувач не вирішить зупинити їх, іноді навмисно використовують нескінченні цикли разом з операторами return, break або exit для завершення циклу. Поширена така практика в серверних веб-додатках, які працюють безперервно і постійно обслуговують веб-запити.

Лічильник циклу while

Часто нам потрібно буде, щоб цикл виконувався певну кількість разів. Для цього зазвичай використовується змінна у вигляді лічильника циклу. Лічильник циклу — це цілочисельна змінна, яка оголошується з єдиною метою: рахувати, скільки разів виконався цикл. У прикладах вище змінна count є лічильником циклу.

Лічильникам циклу часто дають прості імена, такі як i, j чи k. Проте в цих іменах є одна серйозна проблема. Якщо ви захочете дізнатися, де у вашій програмі використовується лічильник циклу і скористаєтеся функцією пошуку i, j чи k, то в результаті отримаєте половину своєї програми, так як i, j та k використовуються в багатьох іменах. Отже, краще використовувати iii, jjj чи kkk в якості імен для лічильників. Вони більш унікальні, їх значно простіше знайти, і вони виділяються в коді. А ще краще використовувати «реальні» імена для змінних, наприклад, count або будь-яке інше ім’я, яке надає контекст використання цієї змінної.

Також для лічильників циклу краще використовувати тип signed int. Використання unsigned int може призвести до несподіваних результатів, наприклад:

Погляньте на програму вище ще раз і постарайтеся знайти помилку.

Виявляється, ця програма являє собою нескінченний цикл. Вона починається з виведення 10 9 8 7 6 5 4 3 2 1 blastoff! як і передбачалося, але потім все йде шкереберть і починається відлік з 4294967295. Чому? Тому що умова циклу count >= 0 ніколи не буде хибною! Коли count = 0, то і умова 0 >= 0 має значення true, виводиться blastoff, а потім виконується декремент змінної count, відбувається переповнення і значенням змінної стає 4294967295. І так як умова 4294967295 >= 0 є істинною, то програма продовжує своє виконання. А оскільки лічильник циклу є типу unsigned, то він ніколи не зможе бути від’ємним і цикл ніколи не завершиться.

Правило: Завжди використовуйте тип signed int для лічильників циклу. 

Ітерації

Кожне виконання циклу називається ітерацією (або ще “повтором“).

Оскільки тіло циклу зазвичай є блоком, і оскільки цей блок виконується з кожним повтором по новому, то будь-які змінні, оголошені всередині тіла циклу, створюються, а потім і знищуються по новому. У наступному прикладі змінна z створюється і знищується 6 разів:

Для фундаментальних типів змінних це нормально. Для НЕ фундаментальних типів змінних (таких як структури або класи) це може позначитися на продуктивності. Отже, не фундаментальні типи змінних краще визначати перед циклом.

Зверніть увагу, що змінна count оголошена поза тілом циклу. Це важливо і необхідно, оскільки нам потрібно, щоб значення змінної зберігалося протягом усіх ітерацій (а не знищувалося по новому з кожною ітерацією).

Іноді нам може знадобитися виконати щось при досягненні певної кількості ітерацій, наприклад, вставити символ нового рядка. Це легко здійснити, використовуючи оператор залишку від ділення з лічильником циклу:

Результат виконання програми:

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. У наступному прикладі внутрішній і зовнішній цикли мають свої власні лічильники. Однак зверніть увагу, що умова внутрішнього циклу використовує лічильник зовнішнього циклу!

Результат виконання програми:

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

Завдання №3

Інвертуйте програму з останнього підрозділу “Вкладені цикли while” так, щоб вона виводила наступне:

5 4 3 2 1
4 3 2 1
3 2 1
2 1
1

Відповідь №3

Завдання №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

Оцінити статтю:

1 Зірка2 Зірки3 Зірки4 Зірки5 Зірок (4 оцінок, середня: 5,00 з 5)
Loading...

Залишити відповідь

Ваш E-mail не буде опублікований. Обов'язкові поля відмічені *