НОУ ІНТУІТ, Лекція, Вирази та операції

Проект до цієї лекції Ви можете завантажититут.

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

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

Пріоритет та порядок виконання операцій

Більшість операцій у мові C#, їхній пріоритет і порядок успадковані з мови C++. Проте є й відмінності: наприклад, немає операції " , " , що дозволяє обчислювати список висловів; додано операції checked і unchecked , що застосовуються до виразів.

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

Таблиця 3.1. Пріоритети операцій мови C#Пріоритет Категорія Операції Порядок
0Первинні(expr), x.y, x->y, f(x), a[x], x++, x--, new, typeof(t), checked(expr), unchecked(expr)Зліва направо
1Унарні+, -, !,

, ++x, --x, (T)x, sizeof(t)

Зліва направо
2Мультиплікативні (множення)*, /, %Зліва направо
3Адитивні (Складання)+, -Зліва направо
4Зрушення>Зліва направо
5Відносини, перевірка типів, =, is, asЗліва направо
6Еквівалентність==, !=Зліва направо
7Логічне І (AND)&Зліва направо
8Логічне виключне АБО (XOR)^Зліва направо
9Логічне АБО (OR)Зліва направо
10Умовне логічне І&&Зліва направо
11Умовне логічне АБОЗліва направо
12Умовний вираз? :Справа наліво
13Привласнення

Склеювання з null

Справа наліво
14Лямбда-оператор=>Справа наліво

Перевантаження операцій та методів

Підперевантаженням операціїрозуміється існування кількох реалізацій однієї і тієї ж операції. Наприклад, операція зі знаком "+" виконується по-різному в залежності від того, чи є її операнди цілими числами, довгими цілими, цілими з фіксованою або плаваючою точкою або рядками тексту.

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

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

Перетворення типів

Кожен об'єкт (змінна), кожен операнд при обчисленні виразу, сам вираз характеризується парою style = display: inline; ">, що задає значення виразу та його тип. У процесі обчислень часто виникає необхідність перетворення типів - необхідність перетворити пару " style="display: inline; "> до пари "style="display: inline; ">. Вихідна пара називається джерелом перетворення, заключна - метою перетворення.

Необхідність у подібних перетвореннях виникає, як зазначалося, у процесі обчислення висловлювання під час приведення операндів до типу, узгодженому з типом операції. Перетвореннятипів необхідно в операторах присвоювання, коли тип виразу правої частини оператора наводиться до типу, заданого лівою частиною цього оператора. Семантика присвоєння має місце і за виклику методів у процесі заміни формальних аргументів методу фактичними параметрами. І тут потрібне перетворення типів.

Перетворення типів можна розділити на безпечні та небезпечні. Безпечне перетворення - це перетворення, для якого гарантується, що:

  • воно можна здійснити для всіх можливих значень джерела ,
  • у процесі перетворення немає втрати точності, тобто точність завдання відповідає точності завдання .

Перетворення, котрій не виконується хоча одне з цих умов, називається небезпечним. Достатня умова існування безпечного перетворення є, наприклад, умова того, що тип є підтипом типу . Справді, у разі будь-яке значення джерела є й допустимим значенням мети. Так, перетворення від типу int до типу double є безпечним. Зворотне перетворення, звісно, ​​буде небезпечним.

Деякі перетворення типів виконуються автоматично. Такі перетворення називаються неявними, і часто зустрічаються при обчисленні виразів. Очевидно, що неявними можуть лише безпечні перетворення. Будь-яке небезпечне перетворення має явно задаватися самим програмістом, який бере на себе всю відповідальність за виконання небезпечного перетворення.

Існують різні способи виконання явних перетворень - операція кастингу (приведення до типу), методи спеціального класу Convert, спеціальні методи ToString, Parse. Всі ці методи будуть розглянуті в даній лекції.

Пояснимо, як виконуються неявні перетворення приобчисленні виразу. Нехай при обчисленні деякого виразу необхідно виконати додавання, де має тип double, а-int. Серед численних реалізацій додавання є операції, що виконують додавання операндів типу int і додавання операндів типу double, так що при виборі будь-якої з цих реалізацій додавання буде потрібно перетворення типу одного з операндів. Оскільки перетворення типу від int до double є безпечним, а в інший бік це перетворення небезпечне, то вибирається безпечне перетворення, яке виконується автоматично, другий операнд неявно перетворюється на тип double, виконується складання операндів цього типу, і результат додавання буде мати тип double .

Організація програмного проекту ConsoleExpressions

Як завжди, всі приклади програмного коду, що з'являються в тексті, є частиною програмного проекту. Опишу структуру консольного проекту, що використовується в цій лекції, названого ConsoleExpressions. Крім створеного за умовчанням класу Program, до проекту додані два класи з іменами TestingExpressions і Scales. Кожен із методів класу TestingExpressions представляє тест, який дозволяє аналізувати особливості операцій, що використовуються при побудові виразів, так що цей клас є збіркою тестів. Клас Scale має змістовний характер, демонструючи роботу зі шкалами, про які йтиметься у цій лекції. Щоб мати змогу викликати методи цих класів, у процедурі Main класу Program оголошуються та створюються об'єкти цих класів. Потім ці об'єкти використовуються як ціль виклику відповідних методів. Загальна схема процедури Main та виклику методів класу така:

Щоразу, коли в тексті лекції потрібно буде навести приклад коду, наводиться або повний текст викликаного методу,наприклад, методу Casting або окремий фрагмент методу.