Лекція
Тема: Програмування циклів
План:
Цикл з передумовою
Цикл з постумовою
Цикл з параметром
У Сі, як і в Паскале, існують усі три типи операторів циклу : цикл з передумовою, цикл з постумовою і цикл з параметром.
Цикл з передумовою
Формат оператора циклу з передумовою:
while (вираження) оператор;
Цикл повторює своє виконання, поки значення вираження відмінне від нуля, тобто умова циклу, що знаходиться в нім, істинна.
В якості прикладу використання оператора циклу розглянемо програму обчислення факторіалу цілого позитивного числа N!. Зіставимо програму рішення цієї задачі, написану на Паскале, з програмою на Сі.
Приклад 1.
Зверніть увагу на оператори в тілі циклу. Звичайно, і в Сі-програмі можна було написати двох операторів привласнення, об'єднавши їх фігурними дужками. Проте використаний спосіб запису лаконічніший і характерніший для Сі. Цей же самий оператор можна було записати ще коротше: F*=i++.
При практичному використанні цієї програми не слід забувати, що факторіал — дуже швидко зростаюча функція, і тому при певних значеннях N вийде з діапазону, що відповідає типу long int. Задавши для змінної F тип unsigned long, можна зрушити цю межу, але цього може виявитися недостатньо. Пропонуємо в якості самостійного завдання досліджувати граничні значення N для двох вказаних типів змінної F.
Цікава властивість наступного оператора :
while(1);
Це нескінченний порожній цикл. Використання в якості вираження константи 1 призводить до того, що умова повторення циклу увесь час залишається істинною і робота циклу ніколи не закінчується. Тілом в цьому циклі є порожній оператор. При виконанні такого оператора програма «топтатиметься на місці».
Розглянемо ще один приклад використання оператора циклу while. Повернемося до завдання ітераційного обчислення суми гармонійного ряду : 1+1/2+1/3+... із заданою точністю ε (див. розд. 3.10, приклад 2). Знову зіставимо програму на Сі з програмою на Паскале.
Приклад 2.
Файл limits.h, що підключається препроцесором, містить визначення граничних констант для цілих типів даних. Зокрема, константа з ім'ям INT_MAX дорівнює максимальному значенню типу int в цій реалізації компілятора. Якщо для типу int використовується двобайтове представлення, то INT_MAX=32767. У цьому ж заголовному файлі визначені і інші константи: INT_MIN=-32768; LONG_MAX=2147483647 і так далі
Цикл з постумовою
Формат оператора циклу з постумовою:
do оператор while (вираження);
Цикл виконується до тих пір, поки вираження відмінне від нуля, тобто умова циклу, що знаходиться в нім, істинна. Вихід з циклу походить після того, як значення вираження стане помилковим, іншими словами рівним нулю. Таким чином, на відміну від оператора repeat... until, використовуваного в Паскале, де у кінці пишеться умова виходу з циклу, в операторові do ... while в Сі у кінці пишеться умова повторення циклу. В якості прикладу розглянемо програму обчислення N!, у якій використовується цикл з постумовою, і зіставимо її з аналогічною програмою на Паскале.
Приклад 3.
Цикл з параметром
Формат оператора циклу з параметром:
for (вираження_1; вираження_2; вираження_3) оператор;
Вираження 1 виконується тільки один раз на початку циклу. Зазвичай воно визначає початкове значення параметра циклу (ініціалізував параметр циклу). Вираження 2 — ця умова виконання циклу, вираження 3 зазвичай визначає зміну параметра циклу, оператор — тіло циклу, яке може бути простим або складеним. У останньому випадку використовуються фігурні дужки.
Алгоритм виконання циклу for представлений на блок-схемі на мал. 1.
Зверніть увагу на те, що після обчислення вираження 3 відбувається повернення до обчислення вираження 2 — перевірці умови повторення циклу.
За допомогою циклу for знаходження N! можна організувати таким чином:
F=l;
for(i=l;i<=N;i++) F=F*i;
Використовуючи операцію «кома», можна у вираження 1 внести ініціалізацію значень відразу декількох змінних :
for(F=l, i=l;i<=N;i++) F=F*i;
Деяких елементів в операторові for може не бути, проте крапки, що розділяють їх, з комою обов'язково мають бути присутніми. У наступному прикладі частина, що ініціалізувала, винесена з оператора for :
F=l;
i=l;
for(;i<=N;i++) F=F*i;
Нижче показаний ще один варіант обчислення N!. У нім на місці тіла циклу знаходиться порожній оператор, а обчислювальна частина внесена у вираження 3.
for(F=l, i=l;i<=N;F=F*i, i++);
Цей же оператор можна записати в наступній формі:
for(F=l, i=l;i<=N;F*=i++);
У мові Сі оператор for є досить універсальним засобом для організації циклів. З його допомогою можна програмувати навіть ітераційні цикли, що неможливо в Паскале. Ось приклад обчислення суми елементів гармонійного ряду, що перевищують задану величину ε:
for(n=l, S=0;1.0/n>eps && n<INT_MAX;n++) S+=1.0/n;
І нарешті, це ж саме завдання з порожнім тілом циклу :
for(n=l, S=0;1.0/n>eps && n<INT_MAX;S+=1.0/n++);
Наступний фрагмент програми на Сі++ містить два вкладені цикли for. У нім запрограмовано отримання на екрані таблиці множення.
for(x=2;х<=9;х++)
for(y=2;y<=9;y++)
cout<<"\n"<<x<<"*"<<y<<"="<<x*y;
На екрані буде отриманий наступний результат:
2*2=4
2*3=6
. . .
9*8=72
9*9=81
Оператор continue. Якщо виконання чергового кроку циклу вимагається завершити до того, як буде досягнутий кінець тіла циклу, використовується оператор continue. Наступний фрагмент програми забезпечує вивід на екран усіх парних чисел в діапазоні від 1 до 100.
for(i=l;i<=100;i++)
{if(i%2) continue; cout<<"\t"<<i;}
Для непарних значень змінної i залишок від ділення на 2 дорівнюватиме одиниці, цей результат сприймається як значення «істина» в умові галуження, і виконується оператор continue. Він завершить черговий крок циклу, виконання циклу перейде до наступного кроку.
Оператор goto. Оператор безумовного переходу goto існує в мові Сі, як і в усіх інших мовах програмування високого рівня. Проте з точки зору структурного підходу до програмування його використання рекомендується обмежити. Формат оператора :
goto мітка;
Мітка є ідентифікатором з подальшою двокрапкою, ставиться перед оператором, що позначається.
Одна з ситуацій, в яких використання goto є виправданим, — це необхідність «дострокового» виходу з вкладеного циклу. Ось приклад такої ситуації :
for(...)
{ while (...)
{ for(...)
{... goto exit ...}
}
}
exit: cout<<"Bыход з циклу";
При використанні оператора безумовного переходу необхідно враховувати наступні обмеження:
• не можна входити всередину блоку ззовні;
• не можна входити всередину умовного оператора (if ...else...);
• не можна входити всередину перемикача;
• не можна входити всередину циклу.
Контрольні питання
Вправи
1. Використовуючи цикли while, do - while і for, написати три варіанти програми отримання на екрані таблиці синусів для значень аргументу в діапазоні від 0 до π/2 із заданим числом кроків.
2. Вичислити і вивести усі члени числового ряду
значення яких перевищує 10-5.
3. Надрукувати в зростаючому порядку усі тризначні числа, в десятковому записі яких немає однакових цифр.
4. Дано ціле n > 2. Надрукувати усі прості числа з діапазону [2, n].
5. Скласти програму перекладу цілого десяткового числа в двійкову систему числення.
6. Скласти програму перекладу цілого десяткового числа в шістнадцятиричну систему числення.