Основні властивості програм і перші приклади 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Основні властивості програм і перші приклади




Перед тим, як перейти безпосередньо до прикладів програм, обговоримо питання про те, якими якостями повинна володіти хороша програма.
Виявляється, що таких властивостей досить багато: коректність, ефективність, зручність експлуатації, надійність, зручність супроводу, зрозумілість і ще цілий ряд інших. Трьома найголовнішими з них є коректність або правильність, ефективність і зрозумілість і модифікованості.

Так як програма на мові Java є просто записом алгоритму вирішення певної задачі, перш за все вона повинна бути правильною, тобто реалізує коректний алгоритм розв'язання вихідної задачі. Виявляється, що не так просто не тільки навчитися писати правильні програми, але навіть і просто сформулювати, що це таке. Тільки після попереднього вивчення основ теорії предикатів, ми зможемо дати точне визначення поняттю правильна програма.

Обговоренню питань ефективності програм присвячена значна частина 4, в якому дуже переконливо доводиться важливість швидких алгоритмів. Зараз же обмежимося лише одним прикладом: часи роботи швидкої і звичайною програм, упорядковують в порядку зростання мільйон чисел, відрізняються в 50000 разів!

Властивості зрозумілості та модифікованості програм пов'язані найтіснішим чином: дуже важко змінити програму, яку не розумієш. У реальному житті програміста завдання на модифікацію вже написаних кимось раніше програм зустрічаються чи не частіше, ніж завдання на розробку програм з нуля. Рішення задач на модифікацію є також і вельми ефективним способом вивчення як мови, так і методів програмування.

Навчитися писати зрозумілі і легко модифікуються програми істотно легше, ніж правильні й ефективні. Для цього достатньо лише дотримуватися кількох простих загальних правил, які ми сформулюємо в застосуванні до мови Java:

• використовуйте в програмі осмислені імена для всіх змінних, відмінних від лічильників та інших подібних величин;
• всім константам, відмінним від нуля і одиниці, надавайте імена;
• дотримуйтесь прийнятий в мові стиль написання імен (імена класів повинні починатися з великої літери, змінних і методів - з малої, констант - складатися повністю з великих літер);
• застосовуйте розумне форматування тексту програми;
• там, де це необхідно, використовуйте коментарі.

Програма на мові Java пишеться у звичайному текстовому файлі, що містить у собі визначення одного або декілька класів. Ім'я файлу зобов'язана співпадати з ім'ям основного класу, визначеного в ньому, і мати розширення java. Компілятор, що запускається зазвичай за допомогою команди javac Filename.java, при відсутності помилок компіляції породжує один або кілька вихідних файлів з іменами, що збігаються з іменами містяться у вихідному фалі класів, і розширенням class. Для запуску скомпільованій програми після цього необхідно виконати команду java Filename.


Відповідно до давно усталеної традиції розглянемо у якості першого завдання наступну програму привітання.

Текст програми.
public class Hello {
public static void main (String [] args) {
System.out.println ("Привіт, світ!");
}
}

Наведений вище текст обов'язково повинен міститися у файлі з ім'ям Hello.java (зверніть увагу на те, що перша буква в імені є прописною, а решта - малими літерами).

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

Наведена вище програма складається з наступної ланцюжка лексем: ключові слова public, class, ідентифікатор Hello, роздільник {, ключові слова public, static і void, ідентифікатор main, роздільник (, ідентифікатор String, роздільники [і], ідентифікатор args, роздільники) і {, ідентифікатор System, роздільник., ідентифікатор out, роздільник., ідентифікатор println, роздільник (, строковий літерал "Здрастуй, світ!", роздільники),;, і двічі}. Дана програма не містить лексем тільки ще одного типу, існуючого у мові - констант, прикладом якої є, скажімо, число 5.

Людина, однак, не машина, і йому далеко не байдуже, як відформатований Текст програми:Невдале форматування істотно ускладнює правильне сприйняття тексту і породжує потенційні помилки. Не обговорюючи зараз питання про те, який саме стиль форматування програм на мові Java є найбільш правильним, ми закликаємо читача слідувати тим зразкам, які він знайде в книзі, - вони пропонують завідомо не найгірший варіант.

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

Послідовне виконання двох команд javac Hello.java і java Hello має призвести до того, що на екрані з'явиться результат роботи програми - рядок Привіт, світ!.
Ми не будемо приводити детальний розбір того, який сенс окремих частин розглянутої програми, - цей коментар можна знайти в будь-якій книзі з мови Java. Замість цього ми обговоримо рішення наступної задачі, в якій будуть використані методи вже анонсованого вище класу Xterm.


Задача 6.1. Напишіть програму друку на экрані вітання із новим навчальним роком.

Текст програми.
public class NewYear {
/ / Magic!
public static void main (String [] args) {
Xterm.clear ();
Xterm.setPosition (25,8);
Xterm.print ("З новим роком", Xterm.Red);
Xterm.print ("(навчальним)", Xterm.Blue);
Xterm.print ("!", Xterm.Red);
Xterm.setPosition (0,16);
/ *
Кінець програми
* /
}
}
У цій програмі використовуються два види коментарів з трьох, що існують у мові Java. Текст, розташований після символів / / аж до кінця рядка, і довільну кількість рядків тексту між символами / * і * /, компілятором просто ігнорується. Знайомство з третім видом коментарів, призначеним для автоматичного документування програм, відкладемо до третього розділу книги. Другий з коментарів, включених у наведену вище програму, є типовим прикладом коментаря, що погіршує код. Не включайте в свої програми непотрібні коментарі!

Деякі фрагменти цієї (і багатьох наступних) програми обговорюватиметься до початку другого розділу не будуть. Тільки тоді, після повноцінного знайомства з основними концепціями об'ктно-орієнтованого програмування на мові Java, можна буде розібратися з тим, що ж означає рядок public static void main (String [] args). Поки ми будемо просто вважати, що так треба!

Змістовна ж частина наведеної програми (тіло функції main, тобто текст, розташований між внутрішніми фігурними дужками) зараз буде детально розібрана. Рекомендується відкомпілювати і запустити цю програму для того, щоб побачити результат її роботи, - це допоможе краще зрозуміти її. При цьому слід мати на увазі, що крім файлу NewYear.java в даному випадку необхідний ще й файл Xterm.java (його вміст наведено для довідки в останній секції цього пункту параграфа).

Об'єкт, з яким ведеться робота в програмі, - Xterm. Детально він розглядається трохи нижче, а поки зазначимо тільки те, що він визначає термінал (засіб), який забезпечує введення чисел і виведення рядків тексту. Об'єкт Xterm містить у собі деяку інформацію або, як кажуть знаходиться в деякому стані. Стан характеризується тим текстом, який відображається у вікні терміналу, і положенням курсору, що відповідає за позицію, в якій з'явиться черговий виведений символ.

Насправді в класі Xterm немає компонент, що містять зазначену інформацію (вона зберігається зовсім в іншому об'єкті), однак таке спрощення реальної ситуації є досить зручним.

Множина всіх станів, у яких може знаходитися об'єкт, називається простором станів. По відношенню до об'єкту можуть бути виконані деякі, заздалегідь певні дії - методи (methods), а процес виконання цих дій називають викликом методу. У результаті цих дій стан об'єкта може змінитися.

У мові Java для виклику методу необхідно спочатку вказати об'єкт, до якого застосовується той чи інший метод, а потім після крапки записати ім'я методу. Саме цей синтаксис, в якому головна роль відводиться об'єкту, над яким виробляється дія, послужив основою для назви парадигми - <<об'єктно-орієнтована>>.

Деякі з методів вимагають для свого виконання вказівки додаткових об'єктів.Такі додаткові об'єкти називають параметрами або аргументами і перераховують їх через кому в круглих дужках після імені методу. У випадку методу без параметрів дужки тим не менш обов'язкові. Завершується будь-який оператор в мові Java крапкою з комою.

Розглянута програма містить виклик трьох різних методів класу Xterm: clear, setPosition і print. Перший з них очищає вікно терміналу і не має параметрів, другий переміщає курсор у позицію, що задається параметрами методу, а третій дозволяє вивести рядок тексту. При цьому перший параметр методу print визначає виведений рядок, а другий задає колір символів.

Усі вищезазначені в даній програмі методи не повертають значень, однак це зовсім не є обов'язковим. Метод може повертати як результат своєї роботи об'єкт довільного типу за допомогою оператора return.

Типи, змінні, оператори

Усі типи даних у мові Java діляться на прості (primitive) і указникові (reference). До простих відносяться дані логічного типу boolean, символьного char, цілих типів byte, short, int і long, та типів задання дійсних чисел float и double. Указникові типи дозволяють працювати із об’єєктами і масивами.

Множина усіх об’єктів з однаковим простором станів і однаковим набором методів називається класом (class). Клас є одним із основних понять мови.

Логічний тип використається для маніпулювання із двома специфічними величинами False (Хибність) або True (Істина), а символьний тип дозволяє працювати із символами різних алфавітів.

В основному різні маніпуляції з величинами у програмі виконуються за допомоги змінних (variables). Присвоєння змінній певного значення іншої змінної, результату виклику методу або обчислення виразу виконується за допомогою оператору прсвоєння =.

В мові Java всі змінні мають бути описані, тобто, для кожної змінної до її першого використання має бути її визначення типу. Загальний вигляд визначення:

тип ідентифікатор [= значення] [, ідентифікатор [= значення ]...];

 

Ім’я (ідентифікатор) є послідовністю із букв, цифр, символів підчеркування і долара, до того ж перший символ не може бути цифрою, а прописні і заглавні букв и різняться.

Квадратн і дужки тут означають фрагменти, які можуть не використовуватися. Наприклад змінна може огписуватися без ініціілізації. В Java усі такі змінні автоматично ініціалізуються нулем.

Java – строго типізована мова. Що частково означає заборону різнотипного присвоєння. Таке неспівпадіння приведедо повідомлення про помилку на етапі коппіляції. Для кожного типу жорстко визначені межі допустимих значень і дозволених операцій.

Але із цього правила є і виключення. Наприклад проходить автоматичне перетворення цілих чисел в дійсні. Обернене перетворення неможливе. У ситуаціє коли потрібно взяти цілу частину числа можна скористатися оператором перетворення типу:

double f = 1.1;

int n = (int) f, m = (int) (f + 0.8);

Для перетворення типу змінної або виразу потрібно перед ним вказати в круглих дужках новий тип. У нашому прикладі змінні m і n в результаті стануть рівними одиниці окажутся равными

единице.

Оператори мови є унарними (з одним аргументом), бінарними (з двома) і тернарними (з трьома). Більшість операторів мови Java є

бінарними: наприклад, операції додавання і множення чисел.

Унарні оператори діляться на префіксні і постфіксні, а тернарний оператор всього один.

За іншою класифікацією операторів: вони діляться на арифметичні, бітові, оператори відношення і логічні.

Їх детальний опис можна знайти в довільному довіднику.

 

Використання класу Xterm

Методи clear и setPosition цього класу були описані попередньо, тому зупинимося на методі print.

У класі Xterm є три методи з цим ім’ям але із рзною кількістю аргументів (1,2,3). Перший аргумент – рядок виведення; якщо присутній 2 – це визначення кольору символів, а третій (якщо він є) – колір фона.

Другий і третій аргументи приймають значення цілих чисел, яким для зручності користування прсвоєні символьні імена:

 

public static final int Black = 0;

public static final int Red = 1;

public static final int Green = 2;

public static final int Yellow = 3;

public static final int Blue = 4;

public static final int Magenta = 5;

public static final int Cyan = 6;

public static final int White = 7;

Клас Xterm дає можливість виводити тільки рядки (стрічки), але Java

Дозволяє легко перетворювати дані всіх простих типів в рядкове представлення. Найпростішим способом є використання оператора + із першим операндом – рядком. Оператор + є поліморфним і виконується по різному для чисел і рядків:

 

2 + 2 // 4

"i = " + "c" // "i = c"

"i = " + 2 // "i = 2"

"x = " + (3./2.) // "x = 1.5"

"" + (3./2.) // "1.5"

2 + "i = " // Помилка!

Використання цього оператору і методу print Класа Xterm, може забезпечити виведення значення змінних любого із простих типів. Корисно знати, що "" позначає пустий рядок, а друк "\n" приводить до переміщення курсору терминала на початок наступного рядка. Останнє миожна зробити за допомогою методів println, дія яких у всьому іншому співпадає із роботою методів print.

Інші методик ласу Xterm призначені для вводу цілих і дійсних чисел типу int, long, float і double. Їх імена повністю природні:

inputInt, inputLong, inputFloat і inputDouble відповідно. Всі вони повертають в якості результату введее число, якщо тільки в процесі введення не трапилася якась помилка. За замовченням домовилися, що за один раз може бути введено тільки одне число і введення закінчується натисканням на клавішу Enter.

Аналогічно працює і метод inputChars, який відповідає за введення рядка символів, розміщуючи її в масиві символів.

Особлива ситуація виникає у випадку, наприклад, введення букви або символів керування а також пустого рядка.Обробку цих ситуацій розглянемо пізніше, а поки що запам’ятайте, що у випадку введення чисел рядок

public static void main(String[] args)

потрібно замінити на

public static void main(String[] args) throws Exception.

Усі чотири методи введення чисел і метод введення рядка символів в класі Xterm, є перегруженими (overload). Перегрузка методів – це своєрідна проява поліморфізму, коли два або більше різних методів мають одне ім’я і розрізняються лише кількістю або типами аргументів.

Методи введення Xterm дозволяюь вказувати в якості аргумента і рядок, який є рядком підказки. Ця зручність дозволяє явно побачити під час виконання програми, що ж саме потрібно ввести.

Розглянемо приклад використання.

 

Задача 6.2. Напишіть програму, яка вводить два цілих числа a і b,

потім роздруковує їх, переприсвоює значення цих змінних з подальшим друком результату переприсвоєння.

 

Текст програми.

public class Change {

public static void main(String[] args) throws Exception {

int a = Xterm.inputInt("Введіть перше число -> ");

int b = Xterm.inputInt("Введіть друге число -> ");

Xterm.println("До обміну: a = " + a + "; b = " + b);

int c = a;

a = b;

b = c;

Xterm.println("Після обміну: a = " + a + "; b = " + b);

}

}

 

Ця програма використовує проміжну змінну c для переприсвоєння. Спробуйте придумати варіант алгоритму без використання допоміжної змінної.

 

Повна релізація класу Xterm

Для довідки про цей клас тут приводиться його повна реалізація.

import java.io.*;

// Клас, що виводить рядок тексту

// позиціювання і використання кольрів, а також введення чисел

// цілих типів int і long та дійсних float і double.

public class Xterm {

private static final DataInputStream in =

new DataInputStream(System.in);

private static final int MAXLEN = 255;

private static String inputString() throws IOException {

byte buf[] = new byte[MAXLEN];

int i = in.read(buf);

return new String(buf,0,i-1);

}

 

// Імена кольорів символів і фону

public static final int Black = 0;

public static final int Red = 1;

public static final int Green = 2;

public static final int Yellow = 3;

public static final int Blue = 4;

public static final int Magenta = 5;

public static final int Cyan = 6;

public static final int White = 7;

 

// Метод очистки екрану

public static void clear() {

System.out.print("\033[2J");

}

// Метод позиціонування курсору

public static void setPosition(int x, int y) {

System.out.print("\033[" + (y+1) + ";" + (x+1) + "H");

}

// Методи виведення рядка

public static void print(String txt) {

System.out.print("\033[0m\033[30;1m"+txt+"\033[0m\033[30m");

}

public static void print(String txt, int fg) {

System.out.print("\033[0m\033[" + (30+fg)

+";1m" + txt + "\033[0m\033[30m");

}

public static void print(String txt, int fg, int bg) {

System.out.print("\033[0m\033["+(bg==7?"":""+(40+bg)+";")+

(30+fg)+";1m" + txt + "\033[0m\033[30m");

}

public static void println(String txt) {

print(txt + "\n");

}

public static void println(String txt, int fg) {

print(txt + "\n");

}

public static void println(String txt, int fg, int bg) {

print(txt + "\n");

}

// Методи введення чисел типів int, long, float, double

public static int inputInt() throws IOException,

NumberFormatException {

return Integer.valueOf(inputString()).intValue();

}

public static int inputInt(String prompt) throws IOException,

NumberFormatException {

print(prompt); return inputInt();

}

public static long inputLong() throws IOException,

NumberFormatException {

return Long.valueOf(inputString()).longValue();

}

public static long inputLong(String prompt) throws IOException,

NumberFormatException {

print(prompt); return inputLong();

}

public static float inputFloat() throws IOException,

NumberFormatException {

return Float.valueOf(inputString()).floatValue();

}

public static float inputFloat(String prompt) throws IOException,

NumberFormatException {

print(prompt); return inputFloat();

}

public static double inputDouble() throws IOException,

NumberFormatException {

return Double.valueOf(inputString()).doubleValue();

}

public static double inputDouble(String prompt)

throws IOException, NumberFormatException {

print(prompt); return inputDouble();

}

// Методи введення рядка, що розглядається як масив символів.

public static char[] inputChars() throws IOException {

return (inputString()).toCharArray();

}

public static char[] inputChars(String prompt)

throws IOException {

print(prompt);

return (inputString()).toCharArray();

}

}__

 

Логічні та умовні оператори

Усі попередні програми були лінійними, тобто усі дії в них виконувалися послідовно згідно порядку запису дії в програмі. Насправді, в дійсності нам порібно мати типи керування для задання розгалуджень і повторень однотипних дій. У Java ці типи керування реалізуються умовними операторами, операторами циклів і обробки виключних ситуацій.

Найпростішими конструкціями зміни порядку виконання операторів є оператори if, if-else і switch. Використаня умовних операторів зумовлює використання логічних виразів і логічних операторів.

Любі об’єкти одного і того ж типу можна порівнювать на рівність (==) і нерівність (!=). У випадку застосування цих операторів до указникових типів, буде перевірятися факт рівності (або нерівності) указників, а не вміст об’єктів. Порівняння на рівність двох екземплярів

повністю одинакових об’єктів, наприклад, дасть результат F.

Об’єкти числовых типів можна порівнювати і за допомогою традиційних арифметичних операторів типу <, <=, >, >=.

Із простих логічних виразів, до яких відносяться логічні зінні і результати порівнянь, можна конструювати і більш складніші логічні вирази за допомогою логічних операторів: унарний оператор заперечення!, бінарні оператори логічного І (And) &, логічного АБО (Or) |, виключного АБО (sl Xor) ^, рівності ==, нерівності!=, умовного І (short circuit And) && і умовного АБО (short circuit Or)||, а також тернарний оператор умови?:.

 

Конструкція if-else в залежності від значення логічного виразу дозволяє виконати різні фрагменти програмного коду:

if (логическое_выражение) блок1; [ else блок2; ]

 

Якщо умова, що задається логічним виразом істинна, тоді буде виконуватися блок1, в іншому випадку блок2. Частина else може бути відсутньою.

Конструкції if і if-else можуть бути вложеними і за допомогою блоку (block) (заключення декількох операторів у фігурні дужки) дозволяє розміщати в кожну із власних двох гілок довільну кількість операторів. Що дозволяє розділити потік виконання програи на довільну кількість гілок. Цю ж задачу можна вирішити і з використанням оператора switch:

switch (вираз) {

case значення1:

блок 1;

break;

case значення2:

блок 2;

break;

...

case значенняN:

блокN;

break;

default:

блок N+1;

}

 

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

(якщо такий існує, він не обов’язковий). Оператор break викликає завершенння оператора switch. За відсутності оператора break управління просто буде передаватися наступному блоку, за щойно виконаним.

Розглянемо приклади.

 

Задача 6.3. Напишіть програму, вщо вводить три цілих числа, і друкує максимальне із них.

 

Текст програми.

public class MaxVal3 {

public static void main(String[] args) throws Exception {

int a = Xterm.inputInt("Введіть перше число -> ");

int b = Xterm.inputInt("Введіть друге число -> ");

int c = Xterm.inputInt("Введіть третє число -> ");

int max;

if (a > b) max = a;

else max = b;

if (c > max) max = c;

Xterm.println("Максимальне число = "+max);

}

}

 

 

Задача 6.5. Напишіть програму, що вводить три цілих числа, і друкує Yes в том случае, якщо серд введених є однакові та No – в іншому випадку.

 

Текст програми.

public class Equal3v1 {

public static void main(String[] args) throws Exception {

int a = Xterm.inputInt("Введіть перше число -> ");

int b = Xterm.inputInt("Введіть друге число -> ");

int c = Xterm.inputInt("Введіть третє число -> ");

if ((a == b) || (a == c) || (b == c))

Xterm.println("Yes");

else

Xterm.println("No");

}

}

Зверніть увагу, що в програмі використані оператори умовного АБО ||, а не логічного АБО |. Це типово – операторі логічного | і логічного ического & на практиці не іикористовують – замість них використовують умовні оператори || і &&.

Як випливає із визначення, якщо перший операнд дизьюнкції

истиний, тоді незалежно від значення другого операнду результатом буде істинависимо от значения второго операнда результатом будет

истина. Аналогічно у випадку коньюнкції при хибному значенні першого операнду – значення другого операнду на результат вже не впливає– він буде хибним. За виконання операторів || і&& виконуюча система Java не оцінює значення другого операнда логичного виразу, якщо результат зрозумілий із першого операнда. Іноді це просто спрощує обчислення, а іноді дозволяє добитися і більшого, як, наприклад в такому фрагменті програми:

if (a==0 || b/a > 0) x = y;

За a = 0 другий операнд оператора || обчислюватися не буде і ділення на нуль пе відбудеться, як цеб було у випадку використання оператора |.

Розв’язок попередньої задачі можна змінити, замінивши вираз що перевіряється на його заперечення та використаши заміну оператора АБО на І.

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

Напишіть ці спрошення самостійно.

І, накінець. Програма запишеться зовсім коротко, якщо замінити в ній оператор if-else на тернарний умовнийоператор?:, загальна форма запису якого має вигляд:

вираз1? вираз2: вираз3

Якщо результат обчислення першого виразу –істина, тоді виконується

вираз2 (вдругий операнд), а іначе - вираз3 (третій операнд). У випадку використання цієї конструкції два останніх виразу повинні бути однотипними.



Поделиться:


Последнее изменение этой страницы: 2016-09-20; просмотров: 342; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.145.178.240 (0.173 с.)