На цьому уроці ми розглянемо умовний тернарний оператор, оператор Кома і згадаємо оператор sizeof в мові C++.
Оператор sizeof
Ми вже розглядали оператор sizeof на уроці №33.
Оператор | Символ | Приклад | Операція |
sizeof | sizeof | sizeof(тип) sizeof(змінна) |
Повертає розмір типу даних або змінної в байтах |
Тоді ми використовували його для визначення розміру конкретних типів даних. Але оператор sizeof також можна використовувати і зі змінними:
1 2 3 4 5 6 7 |
#include <iostream> int main() { double t = 7.0; std::cout << sizeof(t); // виводимо розмір змінної t в байтах } |
Оператор Кома
Оператор Кома (або “оператор Comma”) дозволяє обчислювати декілька виразів (в той час як допускається тільки один).
Оператор | Символ | Приклад | Операція |
Кома | , | x, y | Обчислюється x, потім обчислюється y, а потім повертається значення y |
Вираз, в якому знаходиться цей оператор, матиме значення правого операнду, наприклад:
1 2 3 |
int x = 0; int y = 2; int z = (++x, ++y); // інкремент x і y |
Змінній z
присвоюється результат обчислення ++у
(правого операнду), що дорівнює 3
.
Майже в кожному випадку, стейтмент, в якому є оператор Comma, краще записувати у вигляді окремих інструкцій. Вищенаведений код коректніше буде записати наступним чином:
1 2 3 4 5 |
int x = 0; int y = 2; ++x; ++y; int z = y; |
Зверніть увагу, оператор Comma має найнижчий пріоритет з усіх операторів (навіть нижче, ніж в оператора присвоювання). Через це, наступні два рядки коду виконують не одне і те ж:
1 2 |
z = (a, b); // спочатку обчислюється вираз (a, b), який дорівнює значенню b, а потім результат присвоюється змінній z z = a, b; // обчислюється як "(z = a), b", тому змінній z присвоюється значення a, а змінна b ігнорується |
Більшість програмістів не використовують оператор Comma взагалі (хіба що тільки в циклах for).
Зверніть увагу, кома, яка використовується у викликах функцій, не є оператором Comma:
1 |
int sum = add(x, y); // ця кома не є оператором Comma |
Аналогічно, при оголошенні декількох змінних в одному рядку, кома використовується як роздільник, а не як оператор:
1 |
int x(3), y(5); // ця кома не є оператором Comma |
Правило: Уникайте використання оператора Comma (винятком є використання в циклах for).
Умовний тернарний оператор
Умовний (тернарний) оператор (?:
) — це єдиний тернарний оператор в мові С++, який працює з трьома операндами. Через це його часто називають просто “тернарний оператор“.
Оператор | Символ | Приклад | Операція |
Умовний | ?: | c ? x : y | Якщо змінна c є ненульовим значенням (true), то обчислюється x, в іншому випадку — обчислюється y |
Оператор ?:
є скороченим способом (альтернативою) розгалуження if/else.
Стейтменти if/else:
if (умова)
вираз;
else
інший_вираз;
можно записати як
(умова) ? вираз : інший_вираз;
Зверніть увагу, операндами умовного оператора повинні бути вирази (а не стейтменти).
Наприклад, розгалуження if/else, яке виглядає наступним чином:
if (умова)
x = значення1
else
x = значення2
можна записати як
x = (умова) ? значення1 : значення2;
Більшість програмістів надає перевагу останньому варіанту, так як він читабельніший.
Ще один приклад. Щоб визначити, яке значення помістити у змінну larger
, ми можемо зробити так:
1 2 3 4 |
if (x > y) larger = x; else larger = y; |
Або ось так:
1 |
larger = (x > y) ? x : y; |
Зазвичай, частину з умовою поміщають всередині дужок, щоб переконатися, що пріоритет операцій збережено і також так зручніше читати.
Пам’ятайте, що оператор ?:
має дуже низький пріоритет, через що його потрібно записувати в круглих дужках.
Наприклад, для виводу х
або у
ми можемо зробити наступне:
1 |
if (x > y) std::cout << x; else std::cout << y; |
Або за допомогою тернарного оператора:
1 |
std::cout << ((x > y) ? x : y); |
Давайте розглянемо, що відбудеться, якщо ми не помістимо в дужки весь умовний оператор у вищенаведеному випадку. Оскільки оператор <<
має більший пріоритет, ніж оператор ?:
, то наступний стейтмент (де ми не помістили весь тернарний оператор в круглі дужки, а лише умову):
1 |
std::cout << (x > y) ? x : y; |
Буде оброблюватися як:
1 |
(std::cout << (x > y)) ? x : y; |
Таким чином, в консольному вікні ми побачимо 1
(true), якщо х > у
, в іншому випадку — виведеться 0
(false).
Порада: Завжи поміщайте в круглі дужки умовну частину тернарного оператора, а краще взагалі весь тернарний оператор.
Умовний тернарний оператор — це зручне спрощення розгалуження if/else, особливо при присвоюванні результату змінної або поверненні певного значення. Але його не слід використовувати замість складних розгалужень if/else, оскільки в таких випадках читабельність коду різко погіршується і ймовірність виникнення помилок тільки зростає.
Правило: Використовуйте умовний тернарний оператор тільки в тривіальних випадках.
Умовний тернарний оператор обчислюється як вираз
Варто відзначити, що умовний оператор обчислюється як вираз, в той час як розгалуження if/else обчислюються як набір стейтментів. Це означає, що тернарний оператор ?:
може використовуватися там, де if/else застосувати неможливо, наприклад, при ініціалізації константи:
1 2 |
bool inBigClassroom = false; const int classSize = inBigClassroom ? 30 : 20; |
Тут не можна застосувати if/else, так як константи повинні бути ініціалізовані при оголошенні, а стейтмент не може бути значенням для ініціалізації.