Тема 5. Розгалуження та цикли
C#, розгалуження, умовні оператори, if, else, switch, тернарний оператор, цикли, for, while, do-while, foreach, оператор break, continue
Лекція охоплює основи розгалужень і циклів у C#. Студенти дізнаються про умовні оператори if-else та switch, а також про використання тернарного оператора. У другій частині лекції розглядаються цикли for, while, do-while і foreach, їх призначення та відмінності. Також пояснюється використання операторів break і continue для керування потоком виконання програм. Лекція супроводжується прикладами коду та практичними завданнями.
5.1.Оператори розгалуження
У C# для реалізації розгалужень коду використовуються спеціальні оператори: if-else, switch.
5.1.1. Оператор if-else
Якщо є потреба перевірити у коді програми виконання якоїсь умови та за її результатами перейти до одного із блоків програми зазвичай використовують оператор if-else. Загальний вигляд формату використання оператора if-else зображений у лістингу 4.1.
Лістинг 5.1.Формат використання оператора if-else
Вираз «умова» завжди повинен повертати результат у вигляді елемента логічного типу. Тобто, «умова» може бути або true, або false.
Якщо «умова» рівна true, то виконається інструкція (або код) записана у дужках після if. Якщо ж «умова» рівна false, то виконається інструкція записана у дужках після else.
Якщо після if або else тільки одна інструкція (можна ототожнити з один рядком коду), то «фігурні» дужки {} не є обов’язковими.
Розглянемо приклад: написати програму, що визначає парність/непарність числа. Тобто, користувач вводить число, а програма показує на консоль у текстовому вигляді: «парне» або «непарне» (лістинг 5.2).
Лістинг 5.2. Перевірка числа на парність
int a = int.Parse(Console.ReadLine());
if(a % 2 == 0)
Console.WriteLine("парне");
else
Console.WriteLine("непарне");Конструкції if-else можуть вкладеними одна в одну без обмежень по глибині (лістинг 5.3). Проте дуже глибокої вкладеності варто уникати, адже це ускладнює читання та розуміння коду програми.
if є обов’язковим і повинно існувати у всіх подібних конструкціях, у той же час else – необов’язковий.
Лістинг 5.3. Приклад використання вкладених операторів if-else
Також конструкція if-else може мати структуру дерева із багатьма розгалуженнями. Така структура зазвичай записується якif-else-if (лістинг 5.4).
Лістинг 5.4. Формат запису if-else-if
Вирази обчислюються зверху-вниз. Якщо один із виразів («умова») отримає істинний результат, то програмний код, пов’язаний із цією гілкою розгалуження виконається, а всі інші гілки будуть пропущені. Якщо ж не виконається жодна з умов, то буде запущено код всередині останньої інструкції else (у цьому випадку else теж не обов’язковий).
5.1.2. Оператор switch
Наступною інструкцією для реалізації розгалуження, або точніше вибору значення є switch. Switch забезпечує багатонаправлене розгалуження і дозволяє вибрати один із варіантів із даної множини альтернатив. Ця конструкція працює наступним чином:
- Значення виразу послідовно порівнюється з константами із заданого списку.
- При виявленні збігу для однієї з умов порівняння виконується послідовність інструкцій, пов’язана з цією умовою.
Оператор switch приймає значення цілочисельного типу (наприклад, char, byte, int, long тощо) або тип string. Типи даних, що представляють числа з дробовою частиною не можуть бути використані даному випадку.
Switch складається з набору case конструкцій. Кожна конструкція case представлена у вигляді літерала такого ж типу даних як і значення, що приймає switch. Усі case конструкції у межах одного switch можуть мати тільки унікальні константи. Формат оголошення продемонстровано у лістингу 4.5.
Лістинг 5.5. Формат оголошення switch
switch (значення)
{
case костанта1:
//інструкція
break;
case костанта2:
//інструкція;
break;
...
default:
//інструкція
break;
}Case-конструкції перевіряються у порядку розміщення. Вкінці кожного case повинно бути ключове слово break, що означає вихід із switch.
Також у switch використовують конструкцію default, яка не є обов’язковою і виконується лише у випадку, якщо жодна із case-конструкцій так і не відпрацювала.
Для розуміння принципів роботи switch розглянемо приклад. Написати програму, яка у залежності від введеної цифри виводить на консоль пору року: 1 — «Зима», 2 — «Весна», 3 — «Літо», 4 — «Осінь», інше число — «Введіть число із діапазону [1;4]» (Лістинг 5.6).
Лістинг 5.6. Розв’язання задачі «Пори року» з використанням switch
Console.Write("Введіть номер пори року [1;4]:\t");
int res = int.Parse(Console.ReadLine());
switch (res)
{
case 1:
Console.WriteLine("Зима");
break;
case 2:
Console.WriteLine("Весна");
break;
case 3:
Console.WriteLine("Літо");
break;
case 4:
Console.WriteLine("Зима");
break;
default:
Console.WriteLine("Введіть число від 1 до 4");
break;
}Результат виконання:
Введіть номер пори року [1;4]: 2
Весна
У випадку, якщо потрібно, щоб одна і та ж інструкція виконувалася для кількох різних значень констант код switch може мати вигляд як на лістингу 4.7.
Лістинг 5.7. Приклад використання switch
Console.Write("Введіть оцінку [1-12]:\t");
int res = int.Parse(Console.ReadLine());
switch (res)
{
case 1:
case 2:
case 3:
Console.WriteLine("Низький рівень");
break;
...
case 10:
case 11:
case 12:
Console.WriteLine("Високий рівень");
break;
}У прикладі показано виведення шкільких оцінок відповідно до 12-ти бальної системи по рівнях.
5.1.3. Тернарний оператор
Інколи для простої заміни оператора if-else використовують тернарний оператор. Тернарний оператор отримав свою назву від кількості задіяних виразів (3) і позначається символами ?:. Загальний формат запису тернарного оператора має вигляд:
Вираз_1 ? Вираз_2 : Вираз_3
де Вираз_1 — логічний вираз, за рузультатом обчислення якого визначається наступна дія, Вираз_2 — значення, що повертається, якщо результатом Виразу_1 є true, Вираз_3 — значення, що повертається, якщо результатом Виразу_1 є false.
Для демонстрації роботи тернарного оператора спробуємо розвязати задачу визначення модуля цілого числа. Можна було б для також задачі скористатися оператором if-else, проте тернарний оператор спрощує синтаксис запису такого коду (лістинг 5.8).
Лістинг 5.8. Приклад використання тернарного оператора: визначення модуля числа
Console.Write("Введіть ціле число:\t");
int a = Convert.ToInt32(Console.ReadLine());
int absval = (a > 0) ? a : -a;
Console.WriteLine("ABS: {0}", absval);Увага! Для знаходження модуля числа у C# існує спеціальний метод Math.Abs(значення).
5.2. Використання циклів під час написання програм
Для виконання повторюваних операцій у програмуванні використовуються цикли. Цикл – це спеціальна конструкція мови програмування для багаторазового виконання набору інструкцій. У C# існують 4 типи циклів: for, while, do-while, foreach.
5.2.1. Цикл for
Загальний синтаксис оголошення циклу for має вигляд як на лістингу 4.9. Блок «ініціалізація» використовується для оголошення керуючих змінних циклу. У другому блоці оголошення циклу перевіряється умова можливості продовження виконання циклу. Якщо «умова» повератає false, то виконання циклу завершується. Блок «інструкції» довляє виконувати дії над змінними програми. Найчастіше у цьому блоці відбуваються дії над керуючими змінними.
Лістинг 5.9. Синтаксис оголошення циклу for
Усі три блоки «ініціалізація», «умова» та «інструкції» не є обов’язковим у оголошенні циклу for, проте розділювачі потрібно записати обов’язково (Лістинг 5.10).
Лістинг 5.10. Вічний цикл for
Розглянемо приклад задачі: знайти суму усіх чисел від 1 до 10-ти включно (Лістинг 5.11).
Лістинг 5.11. Приклад використання циклу for
Якщо після for тільки одна інструкція, то «фігурні» дужки {} не є обов’язковими.
Для деталізації розглянемо ще один приклад програми і розберемо його (Лістинг 5.12).
Лістинг 5.12. Приклад використання циклу for
Проаналізуємо, як повинна відпрацювати дана програма та які значення будуть мати змінні на кожній ітерації циклу.
Також у циклах можуть використовуватися ключові слова break та continue.
Ключове слово break зупиняє виконання циклу і переходить до виконання наступного після циклу коду. Ключове слово continue переводить цикл на нову ітерацію.
На прикладі лістингу 4.13. розглянемо використання цих операторів. Програма працює наступним чином: цикл послідовно проходить по усіх числах та виводить їх на екран; якщо число кратне 3-м, то цикл переходить на нову ітерацію; якщо число кратне 7-ми, то цикл закінчується.
Лістинг 5.13. Приклад використання операторів break та continue у циклах
Результат виконання:
5.2.2.Цикли while та do-while
Цикл while у мінімально модифікованому вигляді є частиною практично усіх мов програмування. Тіло циклу виконується до тих пір, поки залишається істинною умова while. Синтаксис оголошення має вигляд:
Цикл while може працювати з передумовою та післяумовою. Цикл з передумовою спочатку перевіряє умову, а після цього виконує або не виконує ітерацію циклу. Цикл з післяумовою спочатку виконується (одна ітерація), а потім тільки перевіряється умова. Таким чином можна зробити висновок, що цикл з післяумовою виконається мінімум 1 раз. Синтаксис огололшення циклу while з післяумовою:
Для порівняння циклів while розглянемо лістинги 4.14 та 4.15. У першому випадку не буде виведено на консоль нічого, у другому буде виведено «5».
Лістинг 5.14. Приклад використання циклу while з передумовою
Лістинг 5.15. Приклад використання циклу while з післяумовою
Робота з циклом foreach буде розглянута у розділі 6 разом із вивченням масивів.
Приклади розв’язання задач
Приклад 4.1. Написати програму, яка генерує і виводить на консоль 10 випадкових чисел із діапазону від 10 до 50.
Розв’язок:
Приклад 4.2. Написати програму, яка серед 5-ти введених чисел знаходить найменше. Програма працює наступним чином: користувач вводить за запитом системи числа, а потім на консоль виводиться найменше з них.
Розв’язок:
int min = int.MaxValue;
for (int i = 0; i < 5; ++i)
{
Console.Write("Введіть {0} число:\t", i + 1);
int num = int.Parse(Console.ReadLine());
min = num < min ? num : min;
}
Console.WriteLine("Найменше число:\t{0}",min);Приклад 5.3. Написати програму, що моделює роботу навігації. Програма повинна пропонувати користувачу вибір дії шляхом введення символа з клавіатури. Доступними діями є: - [x] Hello - виводить на консоль текст «Hello, user!» - [x] Time - виводить години, хвилини та секунди на поточному ПК - [x] Exit - завершує роботу програми.
Розв’язок:
while (true)
{
Console.WriteLine("\nMake a choice:");
Console.Write(" [H]ello\n [T]ime\n E[x]it\n\t\t:>");
string res = Console.ReadLine();
switch (res)
{
case "H":
case "h":
Console.WriteLine("Hello, user!");
break;
case "T":
case "t":
Console.WriteLine(
DateTime.Now.ToString("HH:mm:ss",
new CultureInfo("uk")));
break;
case "X":
case "x":
return;
break;
default:
Console.WriteLine("Wrong choice");
break;
}
}Задачі
Задача 5.1.
Написати програму, що знаходить добуток чисел у вказаному користувачем діапазоні.
Задача 5.2.
Дано цілі додатні числа \(i\) та \(k\) . Реалізувати функцію, що обчислює значення виразу:
\[ z = i - k, при i кратному k \] \[z = k - i, при k кратному i\] \[z = k + i, при{ }всіх{ }інших{ }умовах\]
Задача 5.3.
Обчислити значення виразу \(y=\frac{(x + 5)^3}{\sqrt{x + 1}}\) для усіх \(x\) з діапазону \([10; 100]\) кратних \(7\)-ми. На консоль вивести результат у вигляді, наприклад:
x y
7 125.21
14 100.41
...
Примітка. Вивести на консоль не більше двох знаків після розділювача дробової та цілої частини (крапки) для значень \(y\).
Задача 5.4
Написати програму, яка генерує і виводить на консоль \(8\) випадкових чисел із діапазону від \(1 до 10\). Якщо згенероване число є непарним, то його значення замінюється на \(0\) і виводиться у фигляді \(0(непарне число)\).
Наприклад, виведення може мати вигляд:
2 4 0(7) 0(1) 8 4 2 6 0(9) 0(1) 6
Задача 5.5.
Обчислити значення виразу \(y=\frac{cos(x^2 + 5)^3}{\sqrt{x - ln(x)}}\) для усіх \(x\) з діапазону \([100; 200]\) кратних \(10\)-ти. На консоль вивести результат у вигляді, наприклад:
x y
100 0.8710
110 -0.0247
...
Примітка. Вивести на консоль не більше чотирьох знаків після розділювача дробової та цілої частини (крапки) для значень \(y\). Також зверніть увагу на виведення чисел з від’ємним та додатними значеннями.
Задача 5.6.
Написати програму, що виводить на консоль таблицю множення на вказане користувачем число. Наприклад, якщо користувач ввів число \(5\), то результат виконання програми матиме вигляд:
5 x 1 = 5
5 x 2 = 10
...
// і так далі...
...
5 x 10 = 50
Задача 5.7.
Відомо, що \(1 дюйм\) рівний \(2.54 см\). Розробити додаток, що переводить дюйми в сантиметри і навпаки. Діалог з користувачем реалізувати через систему меню.
Задача 5.8.
Написати програму, що знаходить суму усіх чисел кратних \(7\) у діапазоні від \(0\) до \(100\).
Задача 5.9.
Написати програму, що обчислює суму цифр введено числа.
Задача 5.10.
Написати програму, що виводить на екран цифри введеного числа у зворотному порядку. Наприклад, \(248641 > 146842\).
Задача 5.11.
Написати програму, дозволяє вивести на консоль в порядку спадання непарні числа із діапазону \([5;90]\), кратні \(3\) та не кратні \(5\). одночасно.
Задача 5.12.
Розробити програму, що працює як найпростіший калькулятор, який виконує арифметичні дії +, -, *, / (скористатися оператором switch).
Пояснення. Програма повинна працювати у режимі постійного діалогу з користувачем.
--- МЕНЮ ---
[+] - Додати
[-] - Відняти
[*] - Множити
[/] - Ділити
[0] - Вийти з програми
Ваш вибір :> *
Введіть число 1: 4
Введіть число 2: 5
Резльутат: 20
// повторне виведення меню
Задача 5.13.
Знайти найбільший спільний дільник двох натуральних чисел, використавши алгоритм Евкліда. Алгоритм Евкліда полягає в наступному: від більшого числа віднімається менше до тих пір, поки вони не стануть рівними; отримане в результаті число і буде найбільшим спільним дільником.
Задача 5.14.
Написати програму, яка виводить на екран лінію з символів. Число символів та сам символ, і яка буде лінія вертикальна, або горизонтальна - вказує користувач.
Задача 5.15.
Написати програму, яка виводить на консоль фігури, зображені нижче. Примітка. Розміри фігур вказує користувач.
Фігура 1.
****************
****************
****************
****************
****************
Фігура 2.
****************
* *
* *
* *
****************
Фігура 3.
*****
****
***
**
*
Задача 5.16.
Написати програму, що генерує та виводить на консоль 5 випадкових чисел, кратних 7-ми та некратних 5-ти одночасно з діапазону \([50; 150]\).
Задача 5.17.
Написати програму, що передбачає вгадування користувачем числа, загаданого комп’ютером. Після кожної спроби вгадати число комп’ютер повідомляє чи загадане значення більше (>) чи менше (<) від запропонованого користувачем. Після вгадування на екран виводиться кількість спроб.
Припустимо, що компютер має право загадувати число у діапазоні \([1; 10000)\).
Примітка. Потрібне вміння генерувати випадкові числа за допомогою класу Random.
Задача 5.18.
Згенерувати 10 випадкових чисел у діапазоні \([10, 100)\). Вивести числа на консоль.
Дорогі друзі, якщо Ви помітили, що для написання матеріалів використані джерела, які я не вказав - прошу надіслати мені інформацію на пошту. Дякую.