Вітаю вас! Ще один розділ позаду! Зараз ми коротко повторимо те, чому навчилися в цьому розділі, а потім закріпимо пройдений матеріал на практиці.
Теорія
Завжди використовуйте круглі дужки для усунення можливих проблем з пріоритетами операторів і порядком їх виконання.
Арифметичні оператори в мові 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
призведе до збою в програмі.