У цьому уроці ми поговоримо про арифметичні оператори в С++.
- Унарні арифметичні оператори
- Бінарні арифметичні оператори
- Ділення цілих чисел і чисел типу з плаваючою крапкою
- Використання static_cast в операціях ділення
- Ділення з остачею
- Від’ємні числа в операціях ділення до C++11
- Арифметичні оператори присвоювання
- Де оператор піднесення значення до степеню?
- Тест
Унарні арифметичні оператори
Існують два унарних арифметичних оператора: плюс (+
) і мінус (-
). Унарні оператори — це ті, які застосовуються тільки до одного операнду.
Оператор | Символ | Приклад | Операція |
Унарний плюс | + | +x | Значення x |
Унарний мінус | − | −x | Від’ємне значення x |
Унарний оператор плюс повертає значення операнда. Іншими словами, +5 = 5
, +х = х
. Унарний плюс вам, швидше за все, не доведеться використовувати. Його здебільшого додали в якості симетрії з унарним оператором мінус. Унарний оператор мінус повертає операнд, помножений на -1
. Наприклад, якщо х = 5
, то −х = −5
.
Обидва цих оператора потрібно розміщувати безпосередньо перед самим операндом, без пробілу (−x
, а не − x
).
Не слід плутати унарний оператор мінус з бінарним оператором віднімання, хоч вони і використовують один і той же символ. Наприклад, у виразі х = 5 − −3;
, перший мінус — це оператор віднімання, а другий — це унарний мінус.
Бінарні арифметичні оператори
Їх є 5. Бінарні оператори — це ті, які застосовуються до двох операндів (зліва і справа).
Оператор | Символ | Приклад | Операція |
Додавання | + | x + y | x плюс y |
Віднімання | − | x − y | x мінус y |
Множення | * | x * y | x помножити на y |
Ділення | / | x / y | x поділити на y |
Ділення з остачею | % | x % y | Остача від ділення x на y |
Оператори додавання, віднімання і множення працюють так само, як і в звичайній математиці. А ось ділення і ділення з остачею розглянемо детальніше.
Ділення цілих чисел і чисел типу з плаваючою крапкою
Оператор ділення має два режими. Якщо обидва операнди є цілими числами, то оператор виконує цілочисельне ділення, тобто будь-який дріб (більше/менше) відкидається і повертається ціле значення без округлення, наприклад, 7 / 4 = 1
.
Якщо один або обидва операнди типу з плаваючою крапкою, то тоді буде виконуватися ділення типу з плаваючою крапкою. Тут вже дріб присутній. Наприклад, 7.0 / 3 = 2.333
, 7 / 3.0 = 2.333
чи 7.0 / 3.0 = 2.333
генерують один і той же результат.
Спроби виконати ділення на 0 (або на 0.0) стануть причиною збою в вашій програмі, це правило не слід забувати!
Використання static_cast в операціях ділення
В уроці про символьний тип даних char ми вже використовували оператор static_cast для виведення символів ASCII в вигляді цілих чисел.
Аналогічно, ми можемо використовувати static_cast для конвертації цілого числа в число типу з плаваючою крапкою. Таким чином, замість цілочисельного ділення виконається ділення типу з плаваючою крапкою, наприклад:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <iostream> int main() { int x = 7; int y = 4; std::cout << "int / int = " << x / y << "\n"; std::cout << "double / int = " << static_cast<double>(x) / y << "\n"; std::cout << "int / double = " << x / static_cast<double>(y) << "\n"; std::cout << "double / double = " << static_cast<double>(x) / static_cast<double>(y) << "\n"; return 0; } |
Результат виконання програми:
int / int = 1
double / int = 1.75
int / double = 1.75
double / double = 1.75
Ділення з остачею
Оператор ділення з остачею (%
) працює тільки з цілочисельними операндами і повертає залишок після цілочисельного ділення, наприклад:
Приклад №1: 7 / 4 = 1
з остачею 3
, таким чином, 7 % 4 = 3
.
Приклад №2: 25 / 7 = 3
з остачею 4, таким чином, 25 % 7 = 4
. Залишок становить не дріб, а ціле число.
Приклад №3: 36 % 5 = 1
, в числі 36 тільки 35 ділиться на 5 без залишку, тоді 36 − 35 = 1
, 1
— остача/залишок і результат.
Даний оператор найчастіше використовують для перевірки ділення без остачі одних чисел на інші: якщо х % у == 0
, то х
ділиться без остачі на у
.
Наприклад, ми хочемо написати програму, яка виводить числа від 1 до 100 по 20 значень в кожному рядку. Ми можемо використати оператор ділення з остачею для створення розриву рядків. Хоч ми ще й не розглядали оператор циклу while, в наступній програмі все максимально просто і зрозуміло:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <iostream> int main() { // Змінна count зберігає поточне число для виведення int count = 1; // починаємо з 1 // Повторення операції (цикл) до тих пір, поки count не буде дорівнювати 100 while (count <= 100) { std::cout << count << " "; // виведення поточного числа // Якщо count ділиться без остачі на 20, то вставляємо розрив рядка і продовжуємо з нового if (count % 20 == 0) std::cout << "\n"; count = count + 1; // переходимо до наступного числа } // Кінець while return 0; } // Кінець main() |
Результат виконання програми:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Про while ми ще поговоримо у відповідному уроці.
Від’ємні числа в операціях ділення до C++11
До C++11, якщо будь-який з операндів цілочисельного ділення є від’ємним, то компілятор округлює результат самостійно! Наприклад, результатом −5 / 2
може бути або −3
, або −2
. Однак, більшість сучасних компіляторів округлюють числа в бік нуля (наприклад, в −5 / 2
результатом буде −2
). У специфікації C++11 визначили, що компілятор повинен завжди округляти до нуля (або, простіше кажучи, просто відкидати дріб).
Також до C++11, якщо один з операндів оператора ділення з остачею є від’ємним, то результати можуть бути як додатними, так і від’ємними! Наприклад, результатом −5 % 2
може бути як 1
, так і −1
. У специфікації C++11 вирішили зробити так, щоб результат операції a % b
був того ж знаку, що і значення а
.
Арифметичні оператори присвоювання
Оператор | Символ | Приклад | Операція |
Присвоювання | = | x = y | Присвоюємо значення y змінній x |
Додавання з присвоюванням | += | x += y | Додаємо y до x |
Віднімання з присвоюванням | −= | x −= y | Віднімаємо y від x |
Множення з присвоюванням | *= | x *= y | Множимо x на y |
Ділення з присвоюванням | /= | x /= y | Ділимо x на y |
Ділення з остачею і з присвоюванням | %= | x %= y | Присвоюємо остачу від ділення x на y змінній x |
До цього моменту, коли нам потрібно було додати число 5
до певної змінної, ми робили наступне:
1 |
x = x + 5; |
Це працює, але потрібно два оператора для виконання.
Так як стейтменти, типу х = х + 5
є дуже поширеними, то C++ надає 5 арифметичних операторів присвоювання для нашої зручності. Замість х = х + 5
, ми можемо записати:
1 |
x += 5; |
Замість:
1 |
x = x * y; |
Ми можемо написати:
1 |
x *= y; |
Де оператор піднесення значення до степеню?
У C++ замість оператора піднесення до степеню є функція pow(), яка знаходиться в заголовку <cmath>. pow(base, exponent)
еквівалентно baseexponent
. Варто відзначити, що параметри pow() є типу double, тому ви можете використовувати не тільки цілі числа, а й дробові, наприклад:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> #include <cmath> // підключаємо pow() int main() { std::cout << "Enter the base: "; double base; std::cin >> base; std::cout << "Enter the exponent: "; double exp; std::cin >> exp; std::cout << base << "^" << exp << " = " << pow(base, exp) << "\n"; return 0; } |
Тест
Завдання №1
Обчисліть результат наступного виразу: 6 + 5 * 4 % 3
.
Відповідь №1
Оскільки оператори *
і %
мають більш високий пріоритет, ніж оператор +
, то оператор +
виконуватиметься останнім. Ми можемо переписати наш вираз наступним чином: 6 + (5 * 4 % 3)
. Оператори *
і %
мають однаковий пріоритет, але їх асоціативність є зліва направо, тому лівий оператор буде виконуватися першим. Виходить: 6 + ((5 * 4) % 3)
.
6 + ((5 * 4) % 3) = 6 + (20 % 3) = 6 + 2 = 8
Відповідь: 8.
Завдання №2
Напишіть програму, яка просить користувача ввести ціле число, а потім повідомляє, чи є його число парним чи непарним. Напишіть функцію isEven(), яка повертає true
, якщо ціле число парне. Використовуйте оператор ділення з остачею, щоб визначити парність числа.
Підказка: Використовуйте розгалуження if і оператор рівності (==
).
Відповідь №2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <iostream> bool isEven(int x) { // Якщо x % 2 == 0, то x - парне число return (x % 2) == 0; } int main() { std::cout << "Enter an integer: "; int x; std::cin >> x; if (isEven(x)) std::cout << x << " is even\n"; else std::cout << x << " is odd\n"; return 0; } |
Примітка: Можливо, ви хотіли написати або написали функцію isEven() наступним чином:
1 2 3 4 5 6 7 |
bool isEven(int x) { if ((x % 2) == 0) return true; else return false; } |
Хоч цей спосіб теж робочий, але він складніший. Подивимося, як його можна спростити. По-перше, давайте витягнемо умову if і присвоїмо її окремій змінній типу bool:
1 2 3 4 5 6 7 8 |
bool isEven(int x) { bool isEven = (x % 2) == 0; if (isEven) // isEven - true return true; else // isEven - false return false; } |
У коді вище, якщо isEven
є true
, то повертаємо true
, в іншому випадку (якщо isEven
є false
) повертаємо false
. Ми ж можемо відразу повертати isEven
:
1 2 3 4 5 |
bool isEven(int x) { bool isEven = (x % 2) == 0; return isEven; } |
Так як змінна isEven
використовується тільки один раз, то ми можемо взагалі її видалити:
1 2 3 4 |
bool isEven(int x) { return (x % 2) == 0; } |