Тема: мова програмування C# і середовище програмування мовою C#.
Мета:
Обладнання: ПК зі встановленою ОС і стійким сполученням до мережі Інтернет для роботи з онлайн-середовищем програмування, (дана) інструкція.
Структура уроку
Хід уроку
1. Організаційний момент
Привітання з учнями. Перевірка присутності і готовності учнів до уроку. Перевірка виконання домашнього завдання. Оголошення теми й мети уроку.
2. Актуалізація опорних знань
Дати означення понять, назви яких виділеноі жирним шрифтом. Порівняти з очікуваним.
Алгоритм — це запис скінченої послідовності вказівок, виконання яких призводить до розв'язання певної задачі.
Вказівка (алгоритму) — це спонукальне речення, що вказує, яку дію має виконати виконавець алгоритму.
Виконавець (алгоритму) — це жива істота (людина або тварина)
або автоматичний пристрій (робот, електронна обчислювальна машина тощо),
спроможна діяти відповідно з алгоритмом.
Система вказівок виконавця — це множина (сукупність) всіх вказівок, які може виконувати даний виконавець.
Середовище виконання алгоритму — об'єкти, з якими працює виконавець у процесі виконання алгоритму.
Властивості алгоритму: дискретність, визначеність, виконуваність, скінченність, результативність, масовість, ефективність.
Дискретність (латинською discretus — розділений, розривний) алгоритму означає, що виконання
алгоритму зводиться до виконання окремих дій (кроків) у певній
послідовності. Причому, кожну вказівку алгоритму виконують за скінченний
проміжок часу.
Визначеність (однозначність) означає, що алгоритм однозначно визначає порядок дій виконавця, результат цих дій і не потребує додаткового тлумачення..
Виконуваність означає, що алгоритм, призначений для певного виконавця, може містити лише вказівки, які входять до системи вказівок цього виконавця.
Скінченність означає, що виконання алгоритму закінчиться після
скінченної (можливо, досить великої) кількості кроків і за скінченний
час для довільних вхідних даних.
Результативність алгоритму означає, що після закінчення виконання алгоритму обов’язково:
Масовість алгоритму означає, що алгоритм можна застосувати до цілого класу однотипних задач, для яких спільними є умова та хід розв’язування та які відрізняються лише початковими (вхідними) даними. Наприклад, алгоритмом дій, складеним для одного касира, можуть успішно
скористатися всі касири супермаркету. А програмою пошуку коду й підрахунку суми вартостей товарів, придбаних покупцем, — усі комп'ютери супермаркету
Ефективність алгоритму описує час виконання і об'єм ресурсів, необхідних для виконання алгоритму: чим менше часу (часова ефективність) і ресурсів (просторова ефективність), тим ефективність вища.
3. Вивчення нового матеріалу
Робота комп'ютера полягає у виконанні програми — запису певних вказівок у певному порядку. Програма є алгоритмом дій комп’ютера, записаним зрозумілою для нього мовою.
Щоб задати комп'ютеру послідовність дій, потрібно задати послідовність двійкових кодів відповідних вказівок. Писати такі програми — дуже складна й марудна справа.
Простіше писати програму деякою мовою, наближеною до природної людської мови, а переклад у машинні коди доручити комп'ютеру. Так з'явилися мови, призначені спеціально для написання програм — мови програмування, що на відміну від розмовної мови не допускають двозначностей чи вільного тлумачення.
Мова програмування (англійською programming language) — це система позначень для опису алгоритмів та структур даних.
C# (вимовляти Сі-шарп) — об'єктно-орієнтована мова програмування з безпечною системою типізації для платформи .NET.
C# є дуже близьким родичем мови програмування Java. Мову Java було створено компанією Sun Microsystems, коли глобальний розвиток інтернету поставив задачу роззосереджених обчислень. Взявши за основу популярну мову C++, Java виключила з неї потенційно небезпечні речі. Для роззосереджених обчислень була створено концепцію віртуальної машини та машинно-незалежного байт-коду, свого роду посередника між вихідним текстом програм і апаратними інструкціями комп'ютера чи іншого інтелектуального пристрою. Java набула чималої популярності, і була ліцензована також і компанією Microsoft. Але з плином часу Sun почала винуватити Microsoft, що та при створенні свого клону Java робить її сумісною виключно з платформою Windows, чим суперечить самій концепції машинно-незалежного середовища виконання і порушує ліцензійну угоду. Microsoft відмовилася піти назустріч вимогам Sun, і тому з'ясування стосунків набуло статусу судового процесу. Суд визнав позицію Sun справедливою, і зобов'язав Microsoft відмовитися від позаліцензійного використання Java. У цій ситуації в Microsoft вирішили, користуючись своєю вагою на ринку, створити свій власний аналог Java — мову, в якій корпорація стане повновладним господарем. Ця новостворена мова отримала назву C#. Вона успадкувала від Java концепції віртуальної машини (середовище .NET), байт-коду (MSIL) і для більшої безпеки вихідного коду програм врахувала досвід використання програм на Java.
Нововведення C# — можливість легшої взаємодії, порівняно з мовами-попередниками, з кодами програм, написаних іншими мовами, що є важливим при створенні великих проектів.
Символ # (октоторп) у назві мови можна інтерпретувати і як дві пари плюсів ++, що натякають на новий крок у розвитку мови порівняно з C++, і як музичний символ дієз, разом з буквою C, що становить в англійській мові назву ноти до-дієз.
Мову С# розробив Андерс Гейлсберг — данський програміст, який прославився роботою над комерційно успішними мовами програмування та інструментарієм для розробки програмного забезпечення: Turbo Pascal, Delphi, J++, C#, TypeScript та інше.
Будь-яка мова програмування має такі 3 основні складові: абетку, синтаксис (правила написання) і семантику (правила тлумачення й виконання).
Алфавіт мови C# містить:
Програма мовою С# складається з синтаксичних конструкцій, які називають вказівками (операторами, командами), які будують з лексем — неподільних елементів мови. Розрізняють 5 типів лексем:
Майже всі типи лексем (крім ключових слів і ідентифікаторів) мають власні правила словотворення, включаючи власні підмножини алфавіту. Лексеми відокремлюють роздільниками. Цій самій меті служать пробіл, табуляція, ознака кінця рядка і коментар.
Ідентифікатор — це назва, яку користувач надає об’єкту (змінній, сталій, функції).
Ідентифікатор записують літерами латиниці, цифрами і знаком підкреслення. Розпочинають ідентифікатори з літер та знаку
підкреслення:
Test, х, у2, MaxLoad, up, _top, my_var, sample23 — правильно записані ідентифікатори;
1max, max-znach, max znach, a..b — хибно записані ідентифікатори.
Ідентифікатор не може розпочинатися з цифри! При написаннні ідентифікатора мовою С# враховують регіср: myvar і MyVar — два різні ідентифікатори. Довжину ідентифікатора не обмежено. Пропуски усередині ідентифікатора не припустимі.
Ключові слова — це попередньо визначені зарезервовані ідентифікатори, які мають спеціальні значення для компілятора: abstract, as, base, bool, break, byte, case, catch, char, checked, class, constcontinue, decimal, default, delegate, do, double, else, enum, event, explicit, extern,
false, finally, fixed, float, for, forea, ch, goto, if, implicit, in, int, interface, internal, is, lock, long, namespace, new, null, object, operator, out, out, override, params, private, protected, publ, readonly, ref, return, sbyte, sealed, short, sizeof, stackalloc, static, string, struct, switch, this, throw, true, try, typeof, uint, ulong, unchecked, unsafe, ushort, using, using, static, virtual, void, volatile, while.
Контекстні ключові слова використовують для надання коду конкретного значення, але вони не є зарезервованими словами в C#: add, alias,ascending, async, await,descending, dynamic, from, getglobal, group, into, join, let, nameo, forderby, partial (тип), partial(метод),remove, select,
set,value, var, when, where, yield.
Перепроцесор — це програма, яка опрацьовує директиви — вказівки компілятора, які записують на початку програми.
Директива перепроцесора визначає порядок інтерпретації тексту програми перед її перетворенням у машинний код. Даний термін використавують в описі мов С та C++. В С# не має окремого кроку перепроцесора, тому директиви С# є складовою частиною процесу лексичного аналізу компілятора.
Директиви мовою С# (так само як і мовою C++) розпочинають символом #:
#define ідентифікатор — визначає послідовність символів, яку називають ідентифікатором (наприклад, #define EXP);
#if, #elif, #else, #endif — директиви, які дозволяють компілювати чи не компілювати частину коду залежно від істиності певного виразу;
#undef ідентифікатор — директива, яка видаляє визначений раніше ідентифікатор;
#error повідомлення — виводить текстове повідомлення про помилку;
#warning попередження — директива, яка виводить текстове попередження;
#line № назва_файлу — директива задає номер рядка та назву файлу;
#region, #endregion — директиви, які використовують при структуруванні вихідного коду програми.
Коментар — частина коду програми, яку компілятор ігнорує. Коментарі у програмі мовою C# записують таким чином:
// Коментар до кінця рядка, починаючи з двох похилих рисок /* Коментар (можливо) на кілька рядків */
Структура програми мовою С#
Програма мовою С# складається з функцій, які відповідають підпрограмам (процедурам) в інших мовах програмування.
Головна функція, яка має бути в кожній програмі, — це функція такого вигляду:
static void Main() { тіло функції; }
Найпростіша програма мовою С# має такий загальний вигляд:
using System.IO; using System; class Program { static void Main() { Console.WriteLine("Hello, World!"); } }
Вказівка виведення даних у консоль має такий вигляд:
Console.WriteLine(s); — для рядка тексту s з переходом на новий рядок;
Console.Write(s); — для рядка тексту s без переходу на новий рядок;
Console.Write("{0} {1}",a,b); — для чисел a,b, розділених пропуском.
Зазвичай програми мають такі об'єкти: величини (змінні та сталі), функції (стандартні та створені користувачем) тощо. Всі дані, які використовують у програмі, необхідно зазделегідь описати для розподілу оперативної пам'яті згідно з описами.
Для зручності роботи користувача створено інтерактивне інтегроване середовище програмування, у якому об'єднано можливості:
текстового редактора — для набирання текстів програм;
компілятора — для виявлення помилок у програмі та створення машинного коду;
налагоджувача — для покровного виконання програм і виявлення алгоритмічних помилок
і в якому передбачено можливість запуску програми на виконання в разі успішної компіляції. Інтерактивним середовище називають тому, що воно працює в режимі постійного спілкування з користувачем, а інтегрованим тому, що об'єднує в собі одночасно всі згадані вище можливості. При першому знайомстві з мовою програмування (особливо ще до того, як прийнято рішення щодо доцільності занурення у конкретну мову програмування) зручно скористатися online-середовищем програмування. Наприклад, Coding Ground, інтерфейс якого має такий вигляд.
Роботу усіх поданих нижче програм чи навіть лише частин програм бажано перевірити у цьому чи іншому (наприклад, rextester.com) середовищі програмування. Особливо зручно використовувати online середовища програмування, які не вимагають встановлення програмного забезпечення.
Для використання всіх можливостей мови пограмування використовують середовище програмування не online, а встановлене на ПК. Для С# такими є:
В MonoDevelop вбудовано дизайнер Stetic для наочного програмування за допомогою технології Gtk#.
Visual Studio для платформ Mac OS X та Microsoft Windows з можливістю наочного програмування;
Для опанування навчального матеріалу усіх розробок потрібно встановити:
MonoDevelop — інтегроване середовище програмування;
Cairo — бібліотека для створення зображень;
Gtk# 3.0 — бібліотека для створення і використання елементів керування — Gtk-sharp3 у менеджері програм Ubuntu / Linux Mint.
Компіляція коду вказівкою терміналу при встановленому MonoDevelop можлива такою вказівкою:
mcs *.cs
Тут замість зірорчки * потрібно вказати назву (шлях до) файлу. Після назви файлу вказують (при потребі) параметри — див. опис анґлійською або українською. Наприклад, наступним чином.
mcs *.cs -pkg:gtk-sharp-2.0 -pkg:mono-cairo
Запуск на виконання створеного файлу *.еxe при ОС Windows не викликає проблем. При ОС Ubuntu / Linux Mint це можна зробити:
Для відображення дії коду у терміналі потрібно вібрати наступний пункт Відкрити у програмі Mono Runtime (Terminal).
Примітка. При спробі використати вказівку:
mcs 0.cs -pkg:gtk-sharp-3.0 -pkg:mono-cairo
для файла, успіщно скомпільованого вказівкою для версії 2.0, можна отримати повідомлення такого вигляду:
0.cs(30,3): error CS0433: The imported type `Cairo.Color' is defined multiple times /usr/lib/pkgconfig/../../lib/cli/cairo-sharp-1.10/cairo-sharp.dll (Location of the symbol related to previous error) /usr/lib/mono/4.5/Mono.Cairo.dll (Location of the symbol related to previous error) 0.cs(130,32): error CS0246: The type or namespace name `ExposeEventArgs' could not be found. Are you missing an assembly reference? Compilation failed: 2 error(s), 0 warnings
— з точністю до номерів рядків і початкових символів послідовностей, що викликають помилки компіляції за рахунок багатократного означення класів у різних бібліотеках dll або некоректного звернення до параметрів.
Успішна компіляця програми мовою C# з використанням бібліотек Cairo і GKT# 3.0 можлива для консольного проєкту з під'єднанням певних пакунків — див. далі.
Створення консольного застосунку у середовищі
MonoDevelop
Або натиснути клавіші Ctrl + Shift + N,
або використати вказівку меню File / New Solution...
У вікні діалогу Новий проект вибрати .NET / Консольний проект і натиснути кнопку Далі
У вікні діалогу Новий проект вказати назву (для поданого далі малюнку s), розташування проекту і натиснути кнопку Створити
Отримати вікно сеедовища програмування з кодом програми, що виводить у консоль рядок: "Hello World!".
Успішна компіляця програми мовою C# з використанням бібліотек Cairo і GKT# 3.0 можлива для консольного проєкту з під'єднанням певних пакунків таким чином:
використати вказівку меню Проект / Редагувати посилання…;
у вікні діалогу Редагувати посилання виставити мітки (прапорці) для тих пакунків, на відсутність під'єднання яких вказує повідомлення компілятора, і натиснути кнопку з написом Гаразд.
На малюнку вище відображено, як це потрібно зробити для MonoDevelop 7.8.4 (build 2) при ОС Linux Mint 20.3 Una станом на січень 2023 року.
Зазвичай вважають, що програмувати складно і не кожен може бути програмістом. Насправді, маючи інтегроване середовище програмування, програмувати легко і просто, порівняно зі складанням алгоритмів. І навчитися цьому нескладно, якщо починати з редагування наявних програм.
Поняття величини є одним з найважливіших понять математики та фізики. Більшість з них є числовими. У програмуванні користуються таким визначенням.
Величина — одиниця даних, якими оперує програма. Вона має такі властивості:
назва (ідентифікатор) — послідовність літер латиниці, цифр і нижнього підкреслювання «_», на початку — обов'язково літера;
тип — визначає обсяг відведеної пам'яті, можливі дії, правила тлумачення бітів пам'яті та множину допустимих значень;
розмірність — проста або складена (структурована);
значення — елемент множини допустимих значень величини.
З кожною величиною (або її складовою для структурованої величини) пов'язана ділянка оперативної пам’яті, куди її під час роботи програми заносять та у якій зберегають. Цю ділянку визначено її адресою. Тут під адресою розуміють адресу першого байту з послідовновних щодо адресації байтів, відведених для збереження величини. Назва змінної слугує назвою цієї послідовності байтів під час виконання програми.
Тип даних характеризує допустимі величини для цих даних і сукупністю операцій над ними.
В мові С# розрізнять прості та складні типи даних. До простих відносять числові, логічні та символьні типи даних.
Числові дані поділяють на цілі та дійсні.
Цілі типи
Назва типу | Обсяг (бітів) | Діапазон значень |
---|---|---|
byte | 8 | 0..255 |
sbyte | 8 | –128..127 |
short | 16 | –32768..32767 |
ushort | 16 | 0..65535 |
int | 32 | –2147483648..2147483647 |
uint | 32 | 0..4294967295 |
long | 64 | –9223372036854775808 ..9223372036854775807 |
ulong | 64 | 0..184467440073709551615 |
Об'єм пам'яті, яка виділяють під величини певного типу, залежать від розрядності операційної системи: 2 байти в 32-х
розрядній і 4 байти в 64-х розрядній системі.
Дійсні типи
Назва типу | Обсяг (бітів) | Діапазон значень |
---|---|---|
decimal | 128 | 1·10–28..7.9·10+28 |
double | 64 | 5·10–324..1.7·10+308 |
float | 32 | 1.5·10–45..3.4·10+38 |
Для дійсних чисел вказано діапазони зміни абсолютнної величини (модуля). Дійсні числа можна записувати у форматі з фіксованою крапкою (2.56, –0.3) або у науковому форматі (з рухомою крапкою: –0.23e3=–230, 1.45e–2=0.0145)
Бінарні арифметичні операції:
+ — додавання;
- — віднімання;
* — множення;
% — залишок від цілочисельного ділення;
/ — ділення.
Якщо обидва операнди ділення є цілими числами, то результатом ділення буде ціле число:
double x = 10/4; // результат 2 double y = 10.0/4.0;// результат 2.5
Унарні арифметичні операції:
++ інкремент (зростання значення на 1):префіксний ++x — спочатку значення змінної x збільшують на 1, а потім її значення повертається в якості результату операції;
постфіксний x++ — спочатку значення змінної x повертається в якості результату операції, а потім його збільшують на 1 — див. приклад
int x1 = 5; int z1 = ++x1; // z1 = 6; x1 = 6 int x2 = 5; int z2 = x2++; // z2 = 5; x2 = 6
префиксний --x — спочатку значення змінної x зменшують на 1, а потім її значення повертається в якості результату операції;
постфіксний x-- — спочатку значення змінної x повертається в якості результату операції, а потім його зменшують на 1 — див. приклад
int x1 = 5; int z1 = --x1; // z1 = 4; x1 = 4 int x2 = 5; int z2 = x2--; // z2 = 5; x2 = 4
Пріоритет операцій (від вищого до нижчого):
Для зміни порядку виконання операцій застосовуються дужки.
Логічний тип bool. Змінні цього типу можуть набувати лише два значення:
Вони займають 1 байт у пам'яті.
Операції з логічним типом величин
Значення операндів (аргументів) | Результат операції | |||||
---|---|---|---|---|---|---|
X | Y | not X | X and Y | X or Y | X xor X | |
0 | 0 | 1 | 0 | 0 | 0 | |
0 | 1 | 1 | 0 | 1 | 1 | |
1 | 0 | 0 | 0 | 1 | 1 | |
1 | 1 | 0 | 1 | 1 | 0 |
В С# немає автоматичного приведення числових типів до логічного типу.
Символьний тип char призначено для роботи із символами Unicode. На зберігання величини такого типу компілятор C# виділяє 16-бітів (2 байти) пам'яті. Сталі цього типу можна записати в одному з таких виглядів (спочатку подано приклад для одного й того самого значення):
Зауважимо: 102 — це десятковий код символу 'f', тому після виконання таких вказівок:
char s='f'; int n=s;
змінна n набуде величини 102.
Оголошення змінної — виділення пам'яті для неї — описують таким чином:
тип назва_змінної;
Можливості використання змінної визначено її типом. Наприклад, змінну типу bool не можна використовувати для зберігання числових значень з рухомою точкою. Крім того, тип змінної не можна змінювати протягом терміну роботи програми. Зокрема, змінну типу int не можна перетворити у змінну типу char.
Всі змінні в С# потрібно оголосити до застосування. Це потрібно для того, щоб повідомити компілятор про тип даних, що зберігають у змінній, перш ніж він спробує правильно скомпілювати будь-який оператор, в якому використано цю змінну. Це дозволяє також здійснювати строгий контроль типів у мові С #.
Задати значення змінної можна, зокрема, за допомогою оператора надання значення =. Крім того, задати початкове значення змінної можна при її оголошенні. Для цього після назви змінної вказують знак рівності (=) і значення змінної.
Ініціалізація змінної — виділення пам'яті для неї і надання їй початкового значення. Її описують таким чином:
тип назва_змінної = значення;
де значення має відповідати вказаному типу змінної — див. приклади ініціалізації змінних:
int i = 10;
char c = 'X';
float f = 1.2;
Якщо кілька змінних одного й того самого типу оголошено списком, члени якого розділено комами, то цим змінним можна надати початкове значення див. приклад, у якому ініціалізовано лише змінні b і с:
int а, b = 8, с = 19, d;
Загальні правила оголошення та ініціалізації змінних в С#:
Динамічна ініціалізація
У поданих вище прикладах при ініціалізації змінних використано лише сталі. Але в С# припустимою динамічна ініціалізація змінних за допомогою будь-якого виразу, обчислюваного момент оголошення змінної — див. приклад програми обчислення гіпотенузи прямокутного трикутника за довжинами його катетів (сторін, протолежих до гострих кутів прямокутного трикутника:
using System; class DynInit { static void Main() { double a = 4.0, b = 5.0, c = Math.Sqrt((a*a)+(b*b)); Console.WriteLine ("Гіпотенуза трикутника з катетами " + a + " і " + b + " дорівнює {0:#.###}.", c); } }
з таким результатом:
Гіпотенуза трикутника з катетами 4 і 5 дорівнює 6.403.
Приклади зведення (перетворення) числового типу до рядкового типу string подамо таким кодом.
string s; int v1 = 100; s = v1.ToString(); // s = "100" float v2 = 12345.678937f; s = v2.ToString(); // s = "12345.679" double v3 = 12345.678937; s = v3.ToString(); // s = "12345.678937" s = v3.ToString("F4"); // s = "12345.6789" s = v3.ToString("E4"); // s = "1.2356E+004"
Приклади зведення (перетворення) рядкового типу string у числовий подамо таким кодом.
float v1 = Convert.ToSingle ("1234"); double v2 = Convert.ToDouble ("1234"); decimal v3 = Convert.ToDecimal("1234"); short v4 = Convert.ToInt16 ("1234"); int v5 = Convert.ToInt32 ("1234"); long v6 = Convert.ToInt64 ("1234"); ushort v7 = Convert.ToUInt16 ("1234"); uint v8 = Convert.ToUInt32 ("1234"); ulong v9 = Convert.ToUInt64 ("1234");
4. Закріплення вивченного матеріалу
5. Підбиття підсумків уроку
Виставлення оцінок.
6. Домашнє завдання
Завдання 1. Вивчити навчальний матеріал уроку.
Завдання 2. Встановити на домашній ПК середовище MonoDevelop.
Завдання 3. Дано натуральне число n. Скласти логічний вираз, який справджується тоді й лише тоді, коли це двозначне число.
Завдання 4. Дано порядковий номер року. Скласти логічний вираз, який справджується тоді й лише тоді, коли цей рік високосний. Врахувати, що серед років, які кратні 4 не всі роки високосні. Високосними не є роки кратні 100 крім тих, що кратні 400.
Завдання 5. Поміняти величини двох змінних цілого типу без використання додаткових змінних і операцій введення-виведення. Скласти алгоритм та написати текст програми мовою С#.
Завдання 6. Вивчити навчальний матеріал уроку. Ознайомитися з наступними структурами мови С# (подано структуру опису), щоб виробити уявлення про можливості мови програмування. У разі потреби використати довідникову літературу або ресурси Інтернету.
Лінійний (одновимірний) масив — це набір однотипних даних, які розташовано у пам'яті послідовно одне за одним. Доступ до елементів масиву здійснюють за індексом (номером) елемента. Масив може містити елементи будь-якого типу даних, можна навіть створювати масив масивів.
Розмір масиву — кількість елементів у масиві.
Оголошення масиву мовою С# має таку структуру:
тип [] назва_масиву = new тип [розмір масиву]
Наприклад:
int[] a = new int[5]; // створено масиву a цілих чисел // оголошення та ініціалізація масиву рядків b string[] b = new string[4] {"зима","весна","літо","осінь"};
Доступ до елементів здійснюють за його номером (індексом). Нумерацію елементів починається з нуля: перший елемент масиву має індекс 0, а останній — (N – 1), де N — кількість елементів масиву.
Двовимірний масив відповідає поняттю прямокутної таблиці елементів. Оголошення двовимірного масиву має такий вигляд:
тип [,] назва_масиву = new тип [кількість рядків; кількість стовпчиків]
Кількістю індексів, які використовуються для доступу до елементів масиву називається розмірність масиву.
int[,] a = new int[2, 2]; // оголошення 2-вимірного масиву int[,,] b = new int[2, 2 ,3]; // оголошення 3-вимірного масиву int[,] c = new int[3, 2]{{6,0},{5,7},{8,9}}; // ініціалізація 2-вимірного масиву
Розгалуження реалізують з допомогою умовних операторів:
if (умова-висловлювання) { Вказівки, які потрібно виконати при cсправдженні умови } else { Вказівки, які потрібно виконати при хибності умови }
switch (значення) { case значення1 : вказівка1; break; case значення2 : вказівка2; break; … case значенняn : вказівкаn; break; default: вказівкаn + 1 };
тернарний оператор «? :» використовують для зменшення обсягу коду шляхом заміни оператора if-else таким чином:
умова-висловлювання? вираз1: вираз2
Наприклад, для перевірки введеного числа на парність:
using System; using System.IO; namespace My { class Program { static void Main (string [] args) { int a =54; Console.WriteLine (a% 2 == 0? "Число парне": "Число непарне"); } } }
Виняток — це виняткова обставина (аварійна ситуація), що виникає під час виконання програми. Наприклад, при спробі поділити на нуль.
Опрацювання винятків C# виконують за допомогою таких службових слів:
try — визначає частину коду, що може породити виняток;
catch — визначає частину коду, якмй буде виконано як результат перехоплення (опрацювання) винятку;
finally — визначає частину коду, який буде виконано незалежно від того, чи створено виняток, чи ні. Наприклад, якщо ви відкриваєте файл, його потрібно закрити незалежно від того, чи виникає виняток, чи ні.
Наприклад, програма
using System; namespace Rextester // для rextester.com { public class Program { public static void Main(string[] args) { int a=1, b=0; try { Console.WriteLine(a/b);} catch (DivideByZeroException e) { Console.WriteLine("Виняток DivideByZeroException");} finally { Console.WriteLine("Фінал");} Console.WriteLine("======="); } } }
виводить таке.
1 Фінал =======
При заміні "b=1" на "b=0" виведення стане таким.
Виняток DivideByZeroException Фінал =======
Тип Exception — базовий для усіх типів винятків з такими властивостями:
Тип Exception є базовим типом для всіх винятків. Тому вираз:
catch (Exception ex)
буде опрацьовувати всі можливі винятки. Але також є спеціалізовані типи винятків, призначені для опрацювання певних видів винятків. Ось найуживаніші з них:
— див. такий приклад коду.
using System; namespace Rextester { public class Program { public static void Main(string[] args) { try { int v = Convert.ToInt32("234"); Console.WriteLine(v); //v=v/0; } catch (FormatException e) { Console.WriteLine("Рядок не є послідовністю цифр.");} catch (OverflowException e) { Console.WriteLine("Число поза діапазоном int.");} catch (Exception e) { Console.WriteLine(e.Message);} } } }Простір назв System.IO містить класи для дій введення / виведення (Input / Output) і для роботи з теками й файлами.
using System.IO;
Для використання кодувань потрібно ще дописати: using System.Text;
Класи Directory та DirectoryInfo простору назв System.IO призначено для роботи з теками.
Методи класу Directory
Клас DirectoryInfo багато в чому схожий на Directory, але не є статичним.
Конструктор класу DirectoryInfo для шляху path (тип string) до теки має такий вигляд.
DirectoryInfo name = new DirectoryInfo (path);
Методи класу DirectoryInfo
Обидва класи Directory або DirectoryInfo надають схожі можливості. Коли і що використовувати? Якщо потрібно здійснити одну-дві операції з однією текою, простіше використовувати клас Directory. Якщо необхідно виконати багато операцій з однією і тією самою текою, краще використати клас DirectoryInfo. Чому? Бо методи класу Directory виконують додаткові перевірки безпеки. А для класу DirectoryInfo такі перевірки не завжди є обов'язковими.
Див. приклад коду виведення у консоль повного шляху до підтек і файлів певної теки.
using System; using System.IO; using System.Threading; class Example { static void Main(string[] args) { string name = @"/home/chief"; // Назва теки try { Console.WriteLine("Підтеки:"); string[] s = Directory.GetDirectories(name); foreach (string t in s) Console.WriteLine(t); Console.WriteLine("\nФайли:"); s = Directory.GetFiles(name); foreach (string t in s) Console.WriteLine(t); } catch (IOException ex) {Console.WriteLine("Отримано виключення: {0}", ex.Message);} finally {Thread.Sleep(9000);} // Затримка на 9 секунд для перегляду консолі } }Методи:
обох класів Directory та DirectoryInfo дозволяють виконувати фільтрацію за допомогою додаткового необов'язкового арґумента типу string шаблона, який може містити:
Наприклад, шаблон ".*" призначено для отримання даних про приховані об'єкти.
Робота з файлами містить такі 2 групи дій:
робота з файлами, як з елементами файлової системи. Наприклад, знайти файл, отримати список файлів теки, дізнатися властивості файлу (дату зміни, розширення), скопіювати або видалити наявний файл, створити новий файл;
робота з вмістом файлу: прочитати дані з файлу або записати їх у нього.
Класи File і FileInfo простору назв System.IO призначено для роботи з файлами, як зі складовими файлової системи. Вони містять кілька методів, які дозволяють працювати з вмістом файлу повністю. У простих випадках (коли розміри файлу невеликі, скажімо, до 1 МБ), файл можна повністю прочитати і зберегти в оперативній пам'яті.
Те, що можна зробити за допомогою класу File, можна зробити і за допомогою класу FileInfo, і навпаки. Чому ж їх два? Методи класу File статичні, а методи класу FileInfo є методами об'єкта:
для представника FileInfo шлях до файлу вказують один раз у конструкторі при створенні об'єкта.
Якщо потрібно виконати разову дію, краще використовувати клас File. При роботі з багатьма файлами краще використовувати FileInfo.
Cтворення об'єкта FileInfo здійснюють вказівкою такого вигляду:
FileInfo назва_об'єкта = new FileInfo(@"шлях_до_файлу");
Методи класу FileInfo:
Метод CopyTo класу FileInfo має необов'язковий другий арґумент, булеве значення якого вказує, чи потрібно при копіюванні перезаписувати файл. Як усталено, значення цього арґумента true. При його значенні false та існуванні файлу програма видасть помилку — буде створено виключення.
Властивості класу FileInfo:
Метод Copy класу File має необов'язковий третій арґумент, булеве значення якого вказує, чи буде файл перезаписано.
Див. приклад коду виведення у консоль назви, дати й часу останньої зміни файлів теки, змінених після певного моменту часу.
using System; using System.IO; using System.Text; using System.Threading; class Example { static void Main(string[] args) { string name = @"/home/chief", // Назва теки date_time = @"23.06.2010 23:53:26"; // Дата й час - для порівнння try { DirectoryInfo d = new DirectoryInfo(name);// Створення сховища даних про теку FileInfo[] files = d.GetFiles(); // Створення масиву рядків files з даними про файли foreach (FileInfo fi in files) // Виведення назви, дати й часу if (fi.LastWriteTime > DateTime.Parse(date_time)) // останньої зміни файлів теки Console.WriteLine("{0} | {1}", fi.Name, fi.LastWriteTime.ToString()); } catch (IOException ex) {Console.WriteLine("Отримано виключення: {0}", ex.Message);} finally {Thread.Sleep(9000);} // Затримка на 9 секунд для перегляду консолі } }
Методи класу File для читання та запису текстових і бінарних файлів покривають практично всі основні сценарії. Залежно від завдання можна застосовувати синхронні методи (їх вказано першими у переліку нижче), так і їх асинхронні аналоги (їх вказано другими у переліку нижче). Для методів, що повертають значення, перед назвою метода вказано тип повернутого значення. Після назв методів у дужках вказано типи відповідних арґументів, де перший арґумент — назва файлу. Об'єкт CancellationToken використовують для переривання дії.
AppendAllLines(string, IEnumerable<String>)
AppendAllLinesAsync(string, IEnumerable<String>, CancellationToken)
—
додають у файл набір рядків. Якщо файл не існує, його буде створено.
AppendAllText(string, string)
AppendAllTextAsync(string, string, CancellationToken)
—
додають у файл рядок. Якщо файл не існує, його буде створено.
byte[] ReadAllBytes (string)
Task
—
зчитують вміст бінарного файлу у масив байтів.
string[] ReadAllLines (string)
Task
—
зчитують вміст текстового файлу у масив рядків.
string ReadAllText (string)
Task
—
зчитують вміст текстового файлу в рядок.
IEnumerable
—
зчитують вміст текстового файлу в колекцію рядків.
void WriteAllBytes (string, byte[])
Task WriteAllBytesAsync (string, byte[], CancellationToken)
—
записують масив байт у бінарний файл. Якщо файл не існує, його буде створено. Якщо існує, то його буде перезаписано.
void WriteAllLines (string, string[])
Task WriteAllLinesAsync (string, IEnumerable
—
записують масив рядків у текстовий файл. Якщо файл не існує, його буде створено. Якщо існує, то його буде перезаписано.
WriteAllText (string, string?)
Task WriteAllTextAsync (string, string?, CancellationToken)
— записують рядок у текстовий файл. Якщо файл не існує, його буде створено. Якщо існує, то його буде перезаписано.
using System; using System.IO; class Example { public static void Main() { string[] n = File.ReadAllText("input.txt").Split(' '); File.WriteAllText ("output.txt", Convert.ToString( Int32.Parse(n[0]) + Int32.Parse(n[1]))); } }
У розгорнутому і, можливо, зрозумілішому вигляді програма має такий вигляд.
using System; using System.IO; class Example { public static void Main() { string s = File.ReadAllText("input.txt");// зчитування рядка string[] n = s.Split(' '); // розбиття за роздільником-пробілом int n0 = Int32.Parse(n[0]); // перетворення рядка у число int n1 = Int32.Parse(n[1]); int m = n0 + n1; // знаходження суми s = Convert.ToString(m); // перетворення числа у рядка File.WriteAllText ("output.txt",s); // запис результату у файл } }
Кодування символів можна вказати за допомогою додаткового необов'язкового арґумента у вигляді об'єкта System.Text.Encoding. Наприклад, із застосуванням вбудованого значення Encoding.Unicode:
File.WriteAllText("/home/chief/output.txt", "ґїє", Encoding.Unicode);
Або явно вказавши назву кодування:
File.WriteAllText("/home/chief/output.txt", "abc", Encoding.GetEncoding("iso-8859-1"));
Класи StreamReader і StreamWriter простору назв System.IO — інші спеціальні класи, передбачені у С# для роботи з символьними даними файлів:
Обидва класи працюють із символами Unicode. StreamReader походить від абстрактного класу TextReader, а StreamWriter походить від TextWriter.
Методи класу StreamWriterДив. код програми, що робить таке:
using System; using System.IO; class Example { static void Main(string[] args) { StreamReader i = File.OpenText("input.txt"); string[] n = i.ReadLine().Split(' '); i.Close(); StreamWriter o = File.CreateText("output.txt"); o.WriteLine(Convert.ToString( Int32.Parse(n[0]) + Int32.Parse(n[1]))); o.Close(); } }
Якщо відомо лише тип, але не кількість величин у файлі, потрібно перед кожним зчитуванням перевіряти, чи досягнуто кінець файлу за допомогою булевої функції F.eof(), де F — назва потоку. Функція повертає true або false залежно від до того, досягнуто кiнця файлу чи ні.
Цикли служать для багаторазового повторення виконання деякої частини коду. У С# є 4 види циклів:
Цикл for використовують тоді, коли наперед відомо, скільки повторень потрібно зробити. Він має такий синтаксис:
for (дія до почату циклу; умова продовження циклу;; дія в кінці кожної ітерації циклу; { вказівка1; вказівка2; … вказівкаn; }
Наприклад, цикл:
for (int i = 0; i <5; i ++) {Console.Write (i + " ");}
виводить на екран 5 (кількість повторень) цілих чисел: 0, 1, 2, 3, 4.
Цикл while використовують для запису повторення, поки справджується деяка умова. Синтаксис має такий вигляд:
В останньому випадку гарантовано щонайменше один прохід циклу.
Цикл foreach слугує для циклічного звернення до елементів колекції (групи об'єктів). У C # визначено кілька видів колекцій, кожна з яких є масивом. Загальна форма запису такого оператора циклу така:
foreach (тип назва_змінної_циклу in назва_колекції) вказівка;
Тут тип змінна циклу отримує значення наступного елемента колекції на кожному кроці виконання циклу. Отже, тип змінної циклу має збігатися з типом елемента масиву. Крім цього, тип можна позначати службовим словом var. В цьому випадку компілятор визначає тип змінної циклу, виходячи з типу елемента масиву. Але зазвичай тип вказують явно.
Приклад використання циклу foreach:
using System; using System.Linq; using System.Text; namespace My { class Program { static void Main(string[] args) { int[] a = new int[5] {3,5,7,9,11}; foreach (int j in a) Console.WriteLine("{0}*{1}={2}",j,j,j*j); } } }
Оператор break використовують для дострокового виходу циклу (як правило, у поєднанні з умовним оператором, інакше цикл буде завершено після першого проходження циклу.
Наприклад, при перевірці того, чи містить масив число, кратне 13, знайшовши таке число, немає сенсу перевіряти наступні інші елементи масиву — див. фрагмент коду:
int [] a = {4, 7, 26, 20, 33, 23, 54}; bool b = false; for (int i = 0; i < a.Length; i ++) { if (a[i] % 13 == 0) { b = true; break; } } Console.WriteLine (b? "У масиві є число кратне 13": "У масиві немає числа кратного 13");
Оператор continue дозволяє перейти до наступної ітерації, не завершивши до кінця поточну.
Припинення виконання програми можна здійснити вказівкою:
Environment.Exit(0);Клас Random використовують для породження (псевдо-) випадкових чисел за допомогою методів, що відповідають різним типам даних:
using System; using System.IO; class Example { public static void Main() { Random r = new Random(); Console.Write(r.NextDouble()); Console.ReadLine(); } }
Текст упорядкувала Войтенко Наталія Анатоліївна, вчитель СЗШ № 214 Оболонського району міста Києва, під час виконання випускної роботи на курсах підвищення кваліфікації з 27.11.2017 по 01.12.2017.