Вітаю вас! Ще один розділ позаду! Зараз ми коротко повторимо те, чому навчилися в цьому розділі, а потім закріпимо пройдений матеріал на практиці.
Теорія
Завжди використовуйте круглі дужки для усунення можливих проблем з пріоритетами операторів і порядком їх виконання.
Арифметичні оператори в мові C++ працюють так само, як і в звичайній математиці. Оператор % повертає залишок від цілочисельного ділення. Остерігайтеся помилок округлення, коли операнди цілочисельного ділення і залишку від ділення є від’ємними.
Оператори інкременту (++) та декременту (--) використовуються для збільшення або зменшення числа. Остерігайтеся побічних ефектів, особливо коли справа доходить до порядку, в якому будуть оброблятися параметри функції. Не використовуйте змінну з побічним ефектом більше одного разу в одному стейтменті.
Оператори порівняння дозволяють порівнювати числа типу з плаваючою крапкою. Остерігайтеся використання операторів рівності і нерівності з ними.
Логічні оператори дозволяють формувати складні умовні стейтменти. Побітові оператори дозволяють працювати на рівні окремих біт.
Завдання №1
Обчисліть наступні вирази:
(5 > 3 && 4 < 8)
(4 > 6 && true)
(3 >= 3 || false)
(true || false) ? 4 : 5
Відповідь №1
(5 > 3 && 4 < 8) => (true && true). Результат: true.
(4 > 6 && true) => (false && true). Результат: false.
(3 >= 3 || false) => (true || false). Результат: true.
(true || false) ? 4 : 5 => (true ? 4 : 5). Результат: 4.
Завдання №2
Обчисліть наступні вирази:
7 / 4
14 % 5
Відповідь №2
7 / 4 = 1 з залишком 3. Результат: 1.
14 % 5 = 2 з залишком 4. Результат: 4.
Завдання №3
Конвертуйте наступні двійкові числа в десяткову систему числення:
1101
101110
Відповідь №3
1101: ((1 * 8) + (1 * 4) + (0 * 2) + (1 * 1)) = 8 + 4 + 1 = 13
101110: ((1 * 32) + (0 * 16) + (1 * 8) + (1 * 4) + (1 * 2) + (0 * 1)) = 32 + 8 + 4 + 2 = 46
Завдання №4
Конвертуйте наступні десяткові числа у двійкову систему числення:
15
53
Відповідь №4
Десяткове 15:
Використовуючи метод №1:
15 / 2 = 7 r1
7 / 2 = 3 r1
3 / 2 = 1 r1
1 / 2 = 0 r1
Рахуємо залишки (знизу вгору): 1111.
Використовуючи метод №2:
15 >= 8? Так, 8-й біт дорівнює 1. Залишається 7.
7 >= 4? Так, 4-й біт дорівнює 1. Залишається 3.
3 >= 2? Так, 2-й біт дорівнює 1. Залишається 1.
1 >= 1? Так, 1-й біт дорівнює 1.
Результат: 1111.
Десяткове 53:
Використовуючи метод №1:
53 / 2 = 26 r1
26 / 2 = 13 r0
13 / 2 = 6 r1
6 / 2 = 3 r0
3 / 2 = 1 r1
1 / 2 = 0 r1
Рахуємо залишки (знизу вгору): 110101.
Використовуючи метод №2:
53 >= 32? Так, 32-й біт дорівнює 1. Залишається 21.
21 >= 16? Так, 16-й біт дорівнює 1. Залишається 5.
5 >= 8? Ні, 8-й біт дорівнює 0.
5 >= 4? Так, 4-й біт дорівнює 1. Залишається 1.
1 > 2? Ні, 2-й біт дорівнює 0.
1 >=1? Так, 1-й біт дорівнює 1.
Таким чином, десяткове 53 дорівнює двійковому 110101.
Завдання №5
Чому ви ніколи не повинні робити наступне?
int y = foo(++x, x);
int x = 7 / -2; // (до C++11)
int x = -5 % 2; // (до C++11)
float x = 0.1 + 0.1; if (x == 0.2) return true; else return false;
int x = 3 / 0;
Відповідь №5
Оскільки оператор ++ створює побічний ефект аргументу x, то ми не повинні використовувати x двічі в цьому виразі. Параметри функції foo() можуть оброблятися в будь-якому порядку і неможливо визначити, що буде першим (x чи ++x). Оскільки ++x змінює значення x, то незрозуміло, які значення будуть передані в функцію.
До C++11 незрозуміло, чи округлить компілятор це значення до -3 чи до -4.
До C++11 незрозуміло, що буде результатом: 1 чи -1.
Помилки округлення зі значеннями типу з плаваючою крапкою приведуть до результату false, хоча і здається, що повинно бути true.
Ділення на 0 призведе до збою в програмі.
