Java, як і інші мови програмування, підтримує умовні інструкції та цикли, що визначають порядок виконання інструкцій у програмі. В англійській мові для цього поняття застосовують термін control flow — керування течією. Блоки Перед тим як знайомитись з керувальними структурами, спочатку необхідно ознайомитися з блоками. Блок або складена інструкція – це будь-яка кількість простих інструкцій, які оточені парою фігурних дужок. Блок визначає область видимості ваших змінних. Блоки можуть бути вкладені в середину інших блоків. Ви вже зустрічалися з блоками при створенні найпростіших програм у методі main(). Наступний приклад демонструє вкладення блоку у блок методу main: public static void main(String[] args) { int n; . . .
int k; . . . } // змінна k визначена лише до цього місця } Проте не можна визначати однакові змінні в двох вкладених блоках (на відміну від С++, де це можливо). public static void main(String[] args) { int n; . . .
int k; int n; // помилка! – не можна перевизначити n у внутрішньому блоці . . .
Умовні інструкції
Умовна інструкція в Java має форму:
if (умова) інструкція;
Умова повинна бути оточена дужками і, якщо, умова вірна (true) буде виконана інструкція за умовою, інакше вона не буде виконана, а буде виконана наступна інструкція після умовної інструкції.
Приклад: int a = 5; if (a < 100) System.out.println("Число менше ста"); Зазвичай, необхідно виконати не одну інструкцію, в такому разі інструкції розміщають у блоці: if (умова){ iнструкція 1; ….. iнструкція n; } В такому разі при істинності умови, виконуються усі інструкції у блоці, якщо умова невірна, то виконується наступна інструкція після закриваючої дужки блоку. Якщо ж необхідно здійснити певну дію в разі не виконання умови, то в такому разі застосовують умовну інструкцію наступного виду: if (умова) інструкція1; else інструкція2; if (yourSales >= target) { performance = "Satisfactory"; bonus = 100 + 0.01 * (yourSales - target); } else { performance = "Unsatisfactory"; bonus = 0; } Інструкції if можуть іти одна за одною без використання else: if (x <= 0) if (x == 0) sign = 0; else sign = -1; Для того, щоб програма була більш читабельна бажано застосовувати фігурні дужки: if (x <= 0) { if (x == 0) sign = 0; else sign = -1; } Вони нічого не змінюють, але вираз стає більш зрозумілим. Інструкція чи блок інструкцій виконується лише в разі виконання усіх умов.
Щоправда дану інструкцію можна також переписати ускладнивши умову використавши булевий оператор і (&&):
If (x <= 0 && x==0) sign = 0; else sign=-1; Можна також використовувати повторюваність інструкцій if….else. if (yourSales >= 2 * target) { performance = "Excellent"; bonus = 1000; } else if (yourSales >= 1.5 * target) { performance = "Fine"; bonus = 500; } else if (yourSales >= target) { performance = "Satisfactory"; bonus = 100; } else { System.out.println("You're fired"); } Це дає можливість перевірити ряд умов, якщо попередні умови не виконуються.
Цикли Цикли – це послідовність інструкцій, які можуть повторно виконуватись певну кількість раз в залежності від заданої в програмі умови. Розрізняють цикли з передумовою, з післяумовою та з лічильником.
Цикл while Цикл while (перекладається як «доки») – це цикл з передумовою, тіло якого (тобто інструкція або блок інструкцій) виконується, якщо умова істинна. Якщо умова з самого початку хибна, то цикл не виконається жодного разу.
Загальний вигляд: while (умова) інструкція;
Якщо немає фігурних дужок, то перша інструкція, яка йде після оголошення циклу, вважається тілом циклу. Всі інші інструкції знаходяться поза циклом. Якщо в циклі повинні виконуватись кілька інструкцій, то необхідно використати фігурні дужки. Вони також можуть використовуватись при одній інструкції заради кращого візуального розуміння коду. while (умова){ інструкція 1; ... інструкція N; } В наступному прикладі демонструється мінігра із вгадуванням числа від 0 до 10, яка створена з використанням циклу while:
import java.util.*;
public class Game { public static void main(String[] args) { Scanner in = new Scanner(System.in); // створюємо сканер для введення даних з консолі Random generator = new Random(); //створюємо генератор випадкових чисел System.out.println("Спробуйте відгадати число від 0 до 10"); int gn; String more = "Y";
while (more.equals("Y") || more.equals("y")) { // поки змінна more рівна “Y” або “y”
gn = generator.nextInt(10); // генерація випадкового числа від 0 до 10; System.out.print("Введіть число від 0 до 10: "); int number = in.nextInt(); // зчитуємо число з клавіатури
if (gn == number) System.out.print("Вгадали!!! Спробуєте ще раз? (Y/N)"); else System.out.print("Не вгадали. Спробуєте ще раз? (Y/N)");
more = in.next(); // отримати відповідь
Результат виконання: Спробуйте відгадати число від 0 до 10 Введіть число від 0 до 10: 6 Не вгадали. Спробуєте ще раз? (Y/N)y Введіть число від 0 до 10: 7 Вгадали!!! Спробуєте ще раз? (Y/N) n Програма генерує випадкове число при кожному повторі циклу і пропонує вгадати його. Після вводу користувачем числа - виводить відповідне повідомлення вгадано чи ні. Після цього пропонується здійснити нову спробу. Якщо користувач вводить з клавіатури “Y" або “y”, то гра продовжується, якщо введе щось інше, то завершується.
Для генерації випадкових чисел використано клас Random, що містить методи для генерації випадкових чисел. Зокрема, у нашій програмі використано метод nextInt(), який дозволяє генерувати випадкові числа.
Для зчитування з клавіатури використано клас Scanner, який був доданий в java 5.0, для зручного вводу з клавіатури. Метод nextInt() – читає ціле число, next() – читає цілий рядок з клавіатури.
Для того, щоб переконатися, що користувач хоче продовжити гру використано метод equals() з класу String - Strint1.equals (String2), що перевіряє чи один рядок (String1) тексту рівний іншому (String2).
У вищенаведеній програмі пояснення потребують три рядка. Для початку Вам необхідно лише в загальному зрозуміти їхнє призначення. import java.util.*; Random generator = new Random(); gn=generator.nextInt(10);
Нам необхідний генератор цілих чисел, який реалізовує класс Random у пакеті java.util. Для цього ми імпортуємо відповідний клас (в С/С++ аналогом є підключення бібліотеки). Далі в програмі створюємо змінну generator, яка вказуватиме на екземпляр класу random і дозволятиме звернення до методів даного класу. new Random() - створює відповідний об'єкт. Для генерації випадкових чисел ми використовуємо метод nextInt() класу Random.
Цикл do/while Якщо необхідно, щоб умова виконувалася хоча б один раз можна скористатися циклом з післяумовою do/while: do інструкція while (умова); Зокрема, в програмі з вгадуванням чисел, більш логічніше було б застосувати саме даний цикл, оскільки необхідне хоча б одне виконання тіла циклу. import java.util.*;
public class Tmp { public static void main(String[] args) { Scanner in = new Scanner(System.in); // створюємо Сканер для введення даних з консолі Random generator = new Random(); // створюємо генератор випадкових чисел System.out.println("Спробуйте відгадати число від 0 до 10"); int gn; String more;
do {
gn = generator.nextInt(10); //генерація випадкового числа від 0 до 10; System.out.print("Введіть число від 0 до 10: "); int number = in.nextInt();
if (gn == number) System.out.print("Вгадали!!! Спробуєте ще раз? (Y/N)"); else System.out.print("Не вгадали. Спробуєте ще раз? (Y/N)");
more = in.next();
} while (more.equals("Y") || more.equals("y"));
Цикл з лічильником for
Цикл for – доволі часто вживаний цикл. Він застосовується при необхідності виконати інструкції певну кількість раз з одночасним збільшенням або зменшенням певної змінної. Часто використовується для здійснення перебору певних масивів даних, зокрема, також для сортування масивів. Приклад використання: for (int i = 1; i <= 10; i++) { System.out.println(i); } Наведений вище приклад виведе на консолі в стовпчик числа від 1 до 10. Як бачимо в умові циклу перший слот відводиться для ініціалізації змінної, причому оголосити змінну можна і в іншому місці. Другий слот – для умови, яка перевіряється перед виконанням ітерації, третій слот – вказує як модифікувати змінну-лічильник. Тобто в наведеному прикладі при кожному виконанні ітерації, лічильник "і" буде збільшуватися на одиницю поки не стане рівним десяти.
Найчастіше даний цикл використовується для перебору елементів масиву. Масив – це впорядкований набір даних одного типу. Найпростіший масив можна оголосити та ініціалізувати таким чином: int a[]={1, 5, 6, 1, 3};. Для того, щоб звернутися до певного елементу масиву використовуються квадратні дужки з відповідним індексом елементу. Наприклад а – звернення до четвертого елементу масиву (номери елементів відраховуються з нуля). В наступному прикладі створюється масив і послідовно виводяться його елементи: public class MyArray { public static void main(String[] args) { int a[] = {1, 5, 6, 1, 3}; // створюємо масив і заповнюємо його числами int size = a.length; System.out.println("Елементи масиву:"); for (int j = 0; j < size; j++) { System.out.println("а[" + j + "]=" + a[j]);
Результат виконання: Елементи масиву: а=1 а=5 а=6 а=1 а=3 В дужках циклу for, при потребі, одночасно можна проходити по кількох змінних: for (int i=0,j=20; i<=j+2;i++,j--) { //code
Цикл «for each» Починаючи з java SE 5.0 в мові з’явився новий цикл, призначення якого є перебір елементів масиву або подібних до масиву типів даних (колекції).
Загальний вигляд циклу наступний: for (type var : arr) { //тіло циклу }
Наприклад, вивести елементи масиву a, можна таким чином: for (int element : a) System.out.println(element); Використання даного циклу, дозволяє уникнути проблем пов’язаних з помилками при заданні умови в класичному циклі for. В інших мовах програмування цикл такого виду так і називається foreach, проте, щоб уникнути необхідності значних змін в пакетах, в java пішли простішим шляхом і перевантажили цикл for.
Інструкції, що порушують порядок виконання
В java відсутня інструкція goto, яка дозволяла переходити в будь-яке місце в програмі. Її використання давно вважається поганим стилем програмування, оскільки робить текст програми заплутаним. Про це, зокрема, писав ще Дональд Кнут і він же зазначав, що інколи все таки корисно її застосовувати, щоб припинити виконання певного методу, циклу чи блоку і вийти за їхні межі. Для цієї мети в java існують спеціальні інструкції. Зокрема, інструкцію break можна використати для передчасного виходу з циклу. while (years <= 100) { balance += payment; double interest = balance * interestRate / 100; balance += interest; if (balance >= goal) break; years++; } Таким чином додано дві умови для виходу з циклу. Хоча даний фрагмент можна також переписати наступним чином: while (years <= 100 && balance < goal) { balance += payment; double interest = balance * interestRate / 100; balance += interest; if (balance < goal) years++; } Якщо ми використовуємо вкладені цикли (один цикл в іншому), то інструкція break припинить цикл, в якому вона знаходиться. Якщо вона знаходиться у внутрішньому циклі, то він припинить своє виконання, а зовнішній же цикл буде виконуватись і далі. Якщо потрібно повністю припинити виконання і внутрішнього і зовнішнього, то використовується інструкція break з міткою. Scanner in = new Scanner(System.in); int n; read_data: while (. . .) // this loop statement is tagged with the label { . . . for (. . .) // this inner loop is not labeled
System.out.print("Enter a number >= 0: "); n = in.nextInt(); if (n < 0) // should never happen—can't go on break read_data; // break out of read_data loop . . .
// наступна інструкція буде виконана зразу ж після інструкції break з міткою if (n < 0) // check for bad situation { // deal with bad situation } else { // carry out normal processing } Після використання break з міткою, часто виникає необхідність перевірити чому саме цикл припинив виконання, що і робиться в кінці наведеного вище фрагменті коду програми.