Урок #2

Базові типи даних, константи, літерали та арифметичні оператори

Типи даних

На минулому уроці ми вивчили тип int, діапазон якого від -2 147 483 648 до 2 147 483 647. Але що робити, якщо типу даних не вистачає? Наприклад, треба обчислити результат складання двох чисел з 15-ма розрядами. Ці цифри не помістяться в базовий тип int. Для цього існує більш великий (довший) тип long long, діапазон якого вже від -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807. Але що робити, якщо число перевищує це величезне значення всього лише на одну тисячу! Не хвилюйтеся, Вам не доведеться багато чого писати, можна написати перед нашим типом даних слово unsigned, що означає «беззнаковий». Тоді діапазон значень відразу стає від 0 до подвоєної кількості верхньої межі типу без слова unsigned.

Давайте напишемо програму, яка виведе досить велике значення в різних типах.

-1981284352
-8446744073709551616
10000000000000000000
Для продовження натисніть будь-яку клавішу…

Як ми бачимо, в перших двох випадках значення начебто «перескочили» через максимально можливий елемент і перейшли до мінімально можливого. Це можна порівняти з числовою прямою, на якій розташовані всі можливі числа з діапазону типу. Давайте уявимо, що існує стандартний тип supershort (такий тип ми обов’язково потім навчимося створювати), діапазон якого від -10 до 9. Розподілимо всі значення від -10 до 9 на числовій прямій, а потім з’єднаємо кінці відрізка нашого діапазону. Вийде, що наступне число після 9 – це -10, а не 10, адже числа 10 у нас немає в діапазоні. Якщо брати числа 11, 12 і 13, ми отримаємо числа -9, -8 і -7 відповідно. Саме за цим принципом побудовані всі стандартні типи даних в C++.

Також в цьому прикладі я використав кілька цікавих речей. Давайте поглянемо на імена змінних. Перед ім’ям кожної змінної стоять літери i, ll і ull. Легко здогадатися, що це скорочення від імен типів цих змінних. Це робиться для того, що б вказати який тип у змінної. Це використовують дуже рідко. Але в деяких випадках це необхідно. Я написав ці скорочення тільки заради прикладу і більше не буду їх вживати в кодах програм. Використовувати скорочення чи ні – це повністю Ваше рішення.

Так само вам, швидше за все, сподобалася конструкція i_first = ll_second = ull_third. Як не дивно, але всі змінні присвоюють значення виразу або змінної, яка стоїть праворуч після останнього оператора присвоєння. Але чому ця команда працює саме так? Відповідь криється в її реалізації. Справа в тому, що всі операції присвоєння виконуються справа наліво.

Дійсні типи даних

Крім цілочисельних типів в C++ є так само і дійсні, тобто дробові. Всього дійсних типів даних два: float і double. double має в два рази більше діапазон значень, ніж float, тому найчастіше використовують саме його. Так само є ще одне подання дробного числа – long float, що є якоюсь копією double і нічим не відрізняється від нього. Давайте розглянемо програму, яка виводить добуток введених двох чисел.

1.17
26.123
30.5639
Для продовження натисніть будь-яку клавішу…

Цікаво: якщо число типу double або float буде дорівнювати числу дуже наближеним до одиниці, то це число при виведенні стане одиницею. Якщо ж прирівняти це число будь-якого цілочисельному типу, то воно стане дорівнює 0. Спробуйте запустити цю програму:

1 0
Для продовження натисніть будь-яку клавішу…

Константи і літерали

Бувають програми, в яких необхідно використовувати якесь число кілька разів і яке не може, як в реальному світі, так і в програмі змінитися. Це число пі, всілякі фізичні константи, число днів у січні та інші подібні числа. Тобто константа – це комірка пам’яті, де записано якесь значення, яке не може змінюватися в програмі. Оголошення константи досить просте.

31 30
Для продовження натисніть будь-яку клавішу…

Як ми бачимо, досить написати в оголошенні константи слово const. Не має значення де буде стояти це слово. Після типу константи, або перед – компілятору все одно, але я рекомендую писати саме const int, тому що так буде легше знайти константи в програмі.

До речі, так само як і константам, звичайним змінним можна присвоювати початкові значення відразу в оголошенні змінної. Наприклад, конструкція int a = 1 не є помилковою.

Літерали – це будь-які символи або рядки які не записані в змінній. Ми їх використовували в програмі щоб ставити пропуски між числами при виведенні в консоль. " " – Це символьний літерал. Зазвичай символи беруться в одинарні лапки ' ', а рядки, тобто послідовність символів – в подвійні " ". Але чому, коли ми ставили пробіл, то використовували подвійні лапки? Це робиться для того, щоб не заплутатися в рядках, коли ми захочемо додати якісь слова перед або після нього. Припустимо, ми хочемо красиво оформити програму, яку ми тільки що писали, зробивши у висновку в консоль назву місяців.

In January are 31 days. In April are 30 days.
Для продовження натисніть будь-яку клавішу…

Тут літераломи є "In January are ", " days. In April are" та " days.".

Арифметичні оператори

На минулому уроці ми вивчали додавання, множення і віднімання двох чисел. Ці операції є бінарними, тобто використовуються тільки з двома змінними, або значеннями. Тепер треба частково розглянути ділення. Все що ми зараз можемо знайти – це цілу частину від ділення одного числа на друге. Оператор ділення / «відтинає» дробову частину від відповіді. Давайте розглянемо результат виконання цієї програми:

2
Для продовження натисніть будь-яку клавішу…

У відповіді повинно було вийде 3, адже 2.5 округляється в більшу сторону, але програма виведе 2, тому що, як я вже писав, дрібна частина в буквальному сенсі зникає. Спробуйте самі поділити числа 7 і 3, 100 і 7.

З числами типу float і double все набагато легше: вони мають звичний для нас вигляд, тобто складаються з цілої і дробової частини. Це означає, що, записавши результат ділення числа 5 на 2 в змінну дійсного типу, ми отримаємо цілком пристойний відповідь – 2.5. Якщо ж рішення має досить низький степень, порядку 10 ^ (- 5), то відповідь буде виводитися в такому вигляді: 1e-05, що означає “1 помножити на 10 в степені -5”.

Але що ж робити, якщо ми не хочемо, щоб пропадала інформація про ділення числа 5 на 2. Для цього треба якось обчислити залишок при діленні. Звичайно, можна було його обчислити і так: r (тобто залишок) = 5 – (5/2) * 2. Але це досить великий вираз, тому для полегшення роботи з мовою, був придуманий оператор залишку %. Він так само є бінарним.

5 = 2 * 2 + 1 Для продовження натисніть будь-яку клавішу…

Унарні оператори

Крім бінарних (+, -, *, / і %) існують так же унарні, які вимагають наявності тільки однієї змінної. Це інкремент, іншими словами – збільшення числа на одиницю, і декремент, або зменшення цифри не одиницю. Оператор інкременту ++ і декременту -- є візитною карткою мови C++. Навіть в назві це використовується.

Ці оператори можна ставити перед змінною і після, в залежності від того, якого результату ви хочете добитися. Давайте розглянемо наступний код програми:

1 2 2 3
Для продовження натисніть будь-яку клавішу…

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

Вираз і докладніше про присвоєння

Дізнавшись про майже всіх арифметичних і унарних операторів, ми повинні визнати, що таке вислів. Вираз – послідовність констант, литералов, функцій, які повертають значення, звичайних змінних і всіляких арифметичних операторів. Вираз повинен повертати значення. Наприклад, вираз 2 + 3 повертає 5, а 2 * 2 + 2 повертає 6. Відмінно, ми розібралися з визначенням вирази і з’ясували, що воно повертає значення. Але куди саме? Насправді місць, де можуть використовуватись вирази, досить багато. Але зараз ми почнемо з найпростішого. Ми вже знаємо, що робить оператор присвоєння. Він «він записує результат виконання дії що знаходиться праворуч від знаку в те, що знаходиться зліва від знаку. . Це насправді так і є. Але дане визначення не дуже грамотне, тому перефразовуємо його з використанням нового слова – вираз. Оператор присвоєння обчислює значення виразу і записує його значення в змінну. Дивно, але цей оператор теж повертає значення. Тобто можна писати так (як було відмічено раніше): a = b = 5. Дана конструкція буде виконуватися з права на ліво. Спочатку в змінну b запишеться значення виразу, тобто 5, а потім змінна a придбає значення b, що так само дорівнює 5.

Можливі питання за темою:

«Чи можна писати ++num++?» – не можна, це буде помилкою, так само як і num++++. Тому краще писати num = num + 2, чи num += 2. Ця конструкція += додає до змінної num значення виразу праворуч від неї. У нашому випадку це 2. Так само можно робити і з іншими операторами:

Вираз Еквівалент
num += 2 num = num + 2
num -= 2 num = num – 2
num *= 2 num = num * 2
num /= 2 num = num / 2
num %= 2 num = num % 2

«Мені набридло кожний раз писати std::! Як цього позбутися?» – Все дуже просто. У нас поки було дуже мало викликів функцій з простору імен std, тому ми писали перед кожною функцією ім’я простору імен. Для того що б підключити відразу всі функції з простору імен std, нам треба відразу після підключення бібліотек написати using namespace std.

Додавайте свої питання в коментарі. Кращі потраплять до статті 🙂


Урок #1 Урок #3