Лабораторна робота 2

Типи даних та операції

1 Завдання на лабораторну роботу

Для виконання всіх завдань слід використовувати операції та твердження-вирази. Не слід використовувати тверджень if, switch, goto та циклів.

1.1 Символ з визначеним кодом

Ввести з клавіатури ціле число (від 33 до 255) і вивести символ з відповідним кодом.

1.2 Перевірка приналежності числа визначеним діапазонам

Ввести з клавіатури значення x типу double. Вивести 1, якщо 0 ≤ x ≤ 2 або 7 < x < 11. Вивести 0 в протилежному випадку. Реалізувати обчислення одним твердженням, в якому застосувати присвоєння, умовну операцію, логічні операції та операції порівняння.

1.3 Обмін місцями бітів цілого числа

Розробити програму, в якій користувач уводить з клавіатури ціле k > 0, а також невід'ємні цілі значення m < 32 і n < 32. Обміняти у двійковому поданні значення бітів з номерами m і n. Біти рахувати з нуля справа. Вивести отримане число.

1.4 Степінь числа 8

Увести значення n (від 0 до 10) і вивести значення 8n. Реалізувати підхід з використанням побітових операцій.

1.5 Обчислення суми

Розробити програму, яка читає додатне ціле значення k, обчислює та виводить значення y:

y = 1/k + 1/k2 + 1/k3

1.6 Індивідуальне завдання

Розробити програму, в якій користувач уводить значення аргументу x, після чого здійснюється обчислення y відповідно до формул, наведених в таблиці.

Конкретні формули визначаються відповідно до номеру в списку студентів у групах (номер варіанту).

Номер варіанту
(номер студента у списку)
y Діапазон Номер варіанту
(номер студента у списку)
y Діапазон
1, 17
x + x2 x < 0
9, 25
xx2 x < 0
1/xx 0 ≤ x ≤ 1 x/(x + 1) 0 ≤ x ≤ 1
(x – 1)2 x > 1 1 + 1/x + 1/x2 x > 1
2, 18
x/(x + 1) x < 0
10, 26
xx2 x < 0
xx2 0 ≤ x ≤ 2 (x + 1)2 0 ≤ x ≤ 2
1 + 1/x + 1/x3 x > 2 x/(x – 1) x > 2
3, 19
x/(x – 1) x < –1
11, 27
x2x x < –1
x + x3 –1 ≤ x ≤ 0 (x + 4)(x2 - 1) –1 ≤ x ≤ 0
4 + 1/x31/x4 x > 0 1 + 1/x3 + 1/x4 x > 0
4, 20
(x – 4)2 x < 0
12, 28
4 + 1/x31/x4 x < –1
xx2 0 ≤ x ≤ 1 (x + 3)(x2 + 5) –1 ≤ x ≤ 0
1/x1/x3 x > 1 xx3 x > 0
5, 21
(x + 5)2 x < –1
13, 29
1/x + 1/x2 x < 0
(x + 3)2 –1 ≤ x ≤ 0 x3x2 0 ≤ x ≤ 1
1/x + 1/x3 x > 0 1/x1/x3 x > 1
6, 22
1/x + 1/x4 x < 0
14, 30
x2x x < –1
xx3 0 ≤ x ≤ 1 (x + 10)2 –1 ≤ x ≤ 0
(x + 3)(x2 + 4) x > 1 x/(x + 1) x > 0
7, 23
x/(x – 1) x < –1
15, 31
(x + 3)(x2 + 2) x < –1
x + x4 –1 ≤ x ≤ 0 (x + 4)2 –1 ≤ x ≤ 0
(x + 1)2 x > 0 x/(x – 1) x > 0
8, 24
4 + 1/x41/x2 x < 0
16, 32
(x + 1)2 x < 0
(x + 4)(x2 - 1) 0 ≤ x ≤ 1 (x + 4)(x2 + 5) 0 ≤ x ≤ 1
x + x3 x > 1 4 + 1/x31/x4 x > 1

Для обчислення значень y використовувати вкладені умовні операції. Не використовувати тверджень if. Не вживати стандартних математичних функцій (наприклад, pow()).

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

2 Методичні вказівки

2.1 Основні характеристики мови програмування C++

2.1.1 Історія створення C++

Мова програмування C++ була створена в 1983 році данським дослідником Б'ярном Страуструпом.

Базовою мовою для C++ було обрано С – багатоцільову, лаконічну і відносно низькорівневу мову програмування. Мова C зберігається як підмножина. Основними особливостями C++ у порівнянні з С є такі:

  • строга типізація;
  • підтримка об'єктно-орієнтованого програмування;
  • підтримка шаблонів і узагальненого програмування;
  • розширені можливості процедурного програмування.

Мова C++ поєднує в собі можливості представлення складних структур даних і написання ефективних низькорівневих програм. На базі синтаксису C++ згодом були створені нові об'єктно-орієнтовані мови. Насамперед, це Java і C#.

У серпні 1998 року був ратифікований стандарт мови C++. Стандарт C++ – це документ, який повністю описує синтаксис мови і його можливе використання. Крім базових засобів мови програмування C++, в стандарт увійшла так звана Стандартна бібліотека (Standard C++ Library). Всі останні версії компіляторів на C++ зобов'язані підтримувати стандарт мови. Деякі компанії пропонують спеціальні пакети, які перевіряють "стандартність" реалізації C++. Стандарт оновлювався у 2003, 2011 і 2014 роках. Останнє оновлення – у 2020 році.

2.1.2 Етапи розробки програми мовою C++

Є кілька типових кроків розробки програми мовою C++:

  • сирцевий код готується та зберігається за допомогою будь-якого текстового редактора;
  • здійснюється препроцесування (preprocessing) сирцевого коду і створюється одиниця трансляції; в більшості випадків препроцесування об'єднане з компіляцією;
  • здійснюється компіляція створеної одиниці трансляції; якщо компіляція неможлива через наявність помилок компіляції (compiler errors) , виводиться список цих помилок; якщо синтаксичних помилок немає, створюється так званий об'єктний модуль – файл з машинним кодом, який містить посилання на функції, відсутні в цьому модулі; найчастіше об'єктний модуль – це файл з розширенням .obj.
  • здійснюється редагування невирішених зв'язків за допомогою так званого лінкера (linker, компонувач, редактор зв'язків) – спеціальної підпрограми, яка зв'язує декілька об'єктних модулів, а також додає скомпільовані функції зі стандартних бібліотек – файлів з розширенням lib; крім того, з коду видаляються функції, на які немає посилань; результат роботи лінкера – файл, готовий до виконання (*.exe) або бібліотека.

Під час роботи виникають помилки часу виконання (runtime errors), які відображаються в окремих діалогових вікнах, а також логічні помилки (logical errors, програма виконує неочікувані дії і ми не отримуємо результату). Виправлення цих помилок вимагає повторного редагування коду, компіляції, компонування та завантаження скорегованої програми на виконання.

2.2 Середовище програмування Visual Studio

2.2.1 Інсталяція програми і створення нового проєкту

Visual Studio – це комплект (suіte) засобів розробки, що включає розробку багатьма мовами, зокрема, Visual Basic .NET, C, C++, F++, C#, а також підтримку Web-програмування. Мови розробки використовують загальне інтегроване середовище розробки (Integrated Development Environment, IDE). Інтегроване середовище розробки дозволяє програмісту створювати проєкти, здійснювати доступ до файлів допомоги, редагувати й компілювати код, виправити помилки компіляції та компонування.

Завантажити IDE можна зі сторінки https://visualstudio.microsoft.com/downloads. Обираємо варіант Community і натискаемо на кнопку Free download. Завантажується програма встановлення Visual Studio Installer. Натиснувши на кнопку Continue, починаємо процес інсталяції. У вікні "Installer - Visual Studio Community" серед різних можливостей обираємо Desktop development with C++ і натискаємо Install. На наступній сторінці можна все залишити без змін.

Після встановлення нам пропонують увійти в систему або зареєструватися. Можна прибрати відповідну опцію і натиснути на посилання Not now, maybe later. На наступній сторінці можна вибрати бажану тему – Blue, Blue (Extra Contrast), Dark або Light і натиснути Start Visual Studio.

Після першого завантаження ІDE з'являється стартова сторінка, на якій, зокрема, можна знайти кнопки "Відкрити проєкт або рішення " (Open project or solution) і "Створити новий проєкт" (Create a new Project). Можна здійснити створення нового проєкту.

Примітка: якщо рішення вже створене, новий проєкт може бути створений з використанням головного меню File | New | Project... або клавішною комбінацією Ctrl+Shif+N.

Проєкт (project) є ключовим поняттям розробки програми у Visual Studio. Проєкт – це набір взаємозалежних вихідних файлів, компіляція і компонування яких дозволяє створити програму або DLL (Dynamic link library). Файли проєкту зазвичай зберігаються в окремій теці. Всередині проєкту можна створювати декілька конфігурацій – узгодженого набору налаштувань, зв'язаних з певною метою діяльності. Кожен проєкт містить щонайменше дві конфігурації – конфігурацію зневадження (debug configuration) і конфігурацію релізу (release configuration).

У майстрі нового проєкту слід виконати такі дії:

  • серед встановлених типів проєктів обираємо Empty Project;
  • уводимо ім'я проєкту в полі Name; усталене місце розташування для нового проєкту (Location) визначається автоматично, але в більшості випадків слід змінити диск і теку;
  • обираємо ім'я рішення, яке для простих проєктів збігається з ім'ям проєкту; для простих проєктів також доцільно вибрати опцію Place solution and project in the same directory;
  • натискаємо ОК і порожній проєкт створений.

Примітка: можна також скористатися шаблоном Console App, але потім треба буде вручну видаляти зайві коментарі та твердження на кшталт виведення повідомлення "Hello World!".

Щоб створити новий файл з сирцевим кодом, слід виконати такі дії:

  • в меню Project обираємо функцію Add New Item... (або Add | New Item... в контекстному меню пункту провідника рішень проєкту);
  • обираємо тип файлу: C++ File. Рекомендується ввести ім'я файлу в полі Name; в іншому випадку ім'я буде встановлено в Source.cpp;
  • натискаємо OK, після чого в панелі редактора відкривається порожній файл.

Тепер можна ввести та зберегти текст програми. Для виконання програми можна використовувати клавішну комбінацію Ctrl-F5 (Start Without Debugging).

2.2.2 Зневадження програми

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

Крім автоматичного виконання програми з метою зневадження передбачений покроковий режим. До тексту програми необхідно додати принаймні одну точку переривання (breakpoint). Це можна зробити за допомогою клавіші F9, коли курсор знаходиться в необхідному рядку. Коли програма виконується в режимі зневадження, точка переривання обумовлює тимчасову зупинку програми. Далі можна зняти програму з використання, або виконувати звичайне чи покрокове виконання.

Після встановлення точок переривання можна завантажити програму в режимі зневадження (Debug | Start Debugging або F5). Після зупинки в точці переривання можна здійснювати покрокове виконання або продовжити виконання далі (до кінця або до наступної точки переривання). Для продовження в звичайному (не покроковому) режимі використовують F5. Покрокове виконання програми може відбуватися з заходженням у підпрограми (Debug | Step Into, функціональна клавіша F11) і з пропуском (не покроковим виконанням) підпрограм (Debug | Step Over, функціональна клавіша F10).

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

Підвікно Find Symbol Results містить такі закладки:

  • закладка Autos відображає інформацію про змінні, які вживані в поточному та попередньому твердженнях;
  • закладка Locals відображає інформацію про змінні, які є локальними всередині поточної функції;
  • закладка Watch 1 дозволяє дивитися і редагувати значення, які зберігаються в змінних.

Якщо у вікні Locals відображається масив, об'єкт класу або структура, поруч з ім'ям змінної з'являється кнопка. Натиснувши на кнопку, можна розширити або звузити перегляд змінної. Кнопка відображається зі знаком плюс (+), якщо змінна відображається в скороченому вигляді, і зі знаком мінус (-), коли вона відображається в розгорнутому вигляді.

Достроково припинити виконання можна за допомогою функції DEBUG | Stop Debugging (Shift-F5). Можна також зупинити програму з одночасним завантаженням і виконанням з початку (Debug | Restart або Ctrl-Shif-F5).

2.3 Перша програма мовою C++

Вивчення мови програмування традиційно починають зі створення програми "Hello, World!". Для створення такої програми мовою C++ нам необхідно підготувати новий порожній проєкт у Visual Studio. Нехай цей проєкт матиме назву Hello. Додаємо порожній файл Source.cpp для сирцевого коду. В цьому файлі ми розташуємо нашу програму в найпростішому варіанті:

#include <iostream>

void main()
{
    std::cout << "Hello, World!";
}

Перший рядок коду – директива препроцесора, яка обумовлює підключення у відповідному місці тексту стандартного заголовного файлу iostream. Цей файл містить оголошення необхідних об'єктів, зокрема об'єкту std::cout, який використовують для виведення результату в консольне вікно. Далі розташовано заголовок функції main(), з якої починається виконання програми. Далі у фігурних дужках міститься тіло функції з одним твердженням. Здійснюється виведення рядка вітання у стандартний потік виведення.

Для того, щоб після виведення тексту "Hello, World!" здійснювався перехід курсора на новий рядок, слід змінити рядок, у якому здійснюється виведення, в такий спосіб:

std::cout << "Hello, World!" << std::endl;

Додавання маніпулятору std::endl в потік забезпечує перехід на новий рядок. Для того, щоб не вживати двічі префікс std (ім'я простору імен), до програми можна додати директиву підключення простору імен (після директиви препроцесора #include <iostream>):

using namespace std;

Тепер рядок, в якому здійснюється виведення результатів буде таким:

cout << "Hello, World!" << endl;

Для того, щоб компілятор не генерував попередження (warning) "return type of 'main' should be 'int' instead of 'void'" слід змінити тип результату функції main(). Якщо замість void використати int, можна буде здійснювати аналіз успішності виконання програми на рівні операційної системи. Тепер наша програма виглядатиме так:

#include <iostream>

using namespace std;

int main()
{
    cout << "Hello, World!" << endl;
    return 0;
}

Після завантаження програми на виконання (Debug | Start Without Debugging) текст вітання з'явиться у спеціально створеному консольному вікні

2.4 Основні елементи мови програмування C++

2.4.1 Загальна структура програми

Програма мовою C++ складається з оголошень і визначень глобальних імен – типів, констант, змінних, функцій. Для того, щоб запобігти конфліктам імен, глобальну область видимості ділять на простори імен.

У глобальній області видимості визначають функцію main(), з якої починається виконання програми. Увесь програмний код (крім оголошень і визначень) повинен міститись всередині функцій.

Окрім безпосередньо тексту мовою C++, сирцевий код зазвичай також містить директиви препроцесора. Ці директиви починаються з символу # і їх обробляє спеціальна програма – препроцесор. Мінімально необхідна директива – #include. Вона обумовлює включення в поточний файл тексту іншого файлу – так званого заголовного файлу. Заголовний файл містить оголошення і визначення, необхідні для компіляції початкового коду. Ім'я заголовного файлу вказано у кутових дужках (для стандартних файлів) або у лапках (для користувацьких файлів, які знаходяться у поточній теці). Фізично копіювання тексту в файл не здійснюється, але у пам'яті створюється так звана одиниця трансляції – сирцевий код, оброблений препроцесором.

2.4.2 Ідентифікатори. Ключові слова. Коментарі

На відміну від мов Pascal і BASIC, у мові C++ відрізняються великі та маленькі літери.

Сирцевий код програми складається з лексем. Лексема (token) – це послідовність символів, що мають певне сукупне значення. Проміж окремими лексемами розташовують розділювачі - пропуск, табуляція, новий рядок тощо.

Лексеми поділяються на такі групи:

  • ключові (зарезервовані) слова;
  • ідентифікатори;
  • літерали (константи);
  • знаки операцій.

Ключове слово – це лексема, яка має єдиний наперед визначений сенс в програмному коді. Набір ключових слів обмежений. Усі ключові слова є зарезервованими. Зарезервовані слова не можна використовувати як ідентифікатори. У стандартному С++ є 63 ключових слова. Ще 11 слів зарезервовано для альтернативного представлення операцій. Нижче наводиться список ключових слів:

asm auto bool break case
catch char class const const_cast
continue default delete do double
dynamic_cast else enum explicit export
extern false float for friend
goto if inline int long
mutable namespace new operator private
protected public register reinterpret_cast return
short signed sizeof static static_cast
struct switch template this throw
true try typedef typeid typename
union unsigned using virtual void
volatile wchar_t while    

Ідентифікатори використовуються для іменування змінних, функцій та інших програмних об'єктів. Першим символом повинна бути літера чи символ підкреслення ("_", underscore character). Далі можуть використовуватися також цифри. Використання символу підкреслення на початку імені не є бажаним, оскільки такі імена дуже часто використовуються як системні у стандартних бібліотеках.

Доцільно використовувати змістовні імена, які показують природу об'єкта або функції. Не можна використовувати пропуски всередині ідентифікатора. Тому, якщо необхідно створити ідентифікатор з кількох слів, можна використовувати один з двох підходів:

  • стиль C: між словами замість пропуску вживають символ підкреслення ("_");
  • стиль C++: слова пишуть злито, починаючи друге, третє та інші слова з великої літери (camel notation).

Наприклад, можна створити такі імена змінних:

this_is_my_variable
thisIsMyVariable

Стиль C++ є більш бажаним.

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

Коментарі – це текст всередині сирцевого коду, який не обробляє компілятор. Коментар призначений для інформування читача (програміста) про сенс типів, об'єктів і дій у сирцевому коді програми. Мова C++ підтримує два види коментарів:

  • у стилі C++ – починаючи з символів // компілятор проігнорує весь текст до кінця поточного рядка;
  • у стилі C – починаючи з символів /* до символів */ у цьому або в наступних рядках весь текст буде проігноровано компілятором; всередині тексту коментаря не можуть зустрічатися пари /* та */.

Як правило, велика програма повинна мати коментарі на початку, де роз'яснюється призначення програми. Кожна велика функція повинна також мати коментарі, які пояснюють, що робить ця функція і які значення вона повертає.

2.5 Фундаментальні типи даних

Фундаментальні типи даних у C++, як і в усіх мовах програмування, можна об'єднати у дві групи:

  • дані цілого типу;
  • дані з рухомою комою (дійсні).

До групи цілих типів належать такі типи: int, long, short, char та bool. Усі цілі типи, крім bool, можуть бути звичайними цілими зі знаком (signed) і цілими без знаку (unsigned). Цілі числа без модифікатора unsigned вважаються зі знаком. Цілі числа зі знаком є або від’ємними, або додатними. Беззнакові цілі числа завжди додатні. Символьні дані (char) розглядаються як малі цілі числа.

За числом розрядів, які використовуються для представлення даних (діапазону значень) розрізняють звичайні цілі (int), короткі цілі (short int) та довгі цілі (long int).

Змінні з рухомою крапкою (комою) мають значення, які можна виразити дробом. Іншими словами, вони є дійсними числами. Представлення даних у форматі з рухомою крапкою, або рухомою комою (floating point numbers) дозволяє зберігати дробові значення у формі мантиса*2порядок. Така форма дозволяє зберігати дані дуже широкого діапазону. Група типів з рухомою крапкою містить такі стандартні типи: float, double і long double. Представлення double і long double ідентичні.

У таблиці наведені розміри в байтах і діапазон значень фундаментальних типів:

Категорія Ім'я типу Розгорнуте ім'я Розмір у байтах Діапазон значень
Цілі типи int signed int 4 від -2 147 483 648 до 2 147 483 647
unsigned unsigned int 4 від 0 до 4 294 967 295
char signed char 1 від -128 до 127
unsigned char   1 від 0 до 255
short short int, signed short int 2 від -32 768 до 32 767
unsigned short unsigned short int 2 від 0 до 65 535
long long int, signed long int 4 збігається з int
unsigned long unsigned long int 4 збігається з unsigned int
bool   1 false або true (0 або 1)
Типи з рухомою крапкою float   4 3.4E +/- 38 (7 цифр)
double   8 1.7E +/- 308 (15 цифр)
long double   8 збігається з double

Дані символьного типу (char) мають подвійну природу, а саме: можуть розглядатися як цілі (коди символів) і бути зі знаком і без знака, а також як символи, наприклад '#' . Символьна змінна в одному байті дозволяє зберігати код символу ASCII-таблиці. ASCII означає American Standard Code for Information Interchange (американський стандартний код для обміну інформацією).

Для визначення констант логічного типу (bool) використовують ключові слова true і false. Можна також використовувати 1 і 0 замість true і false.

2.6 Константні значення

Константне значення (неіменована константа) – це лексема, яка представляє певне числове або символьне значення, а також рядок символів.

Константи цілого типу записуються як послідовності цифр. Тип константи залежить від числа цифр у записі константи і може бути уточнений додаванням наприкінці константи букв L чи l (тип long), U або u (тип unsigned) або у сполученні. Цілі константи можуть записуватися у вісімковій системі числення, у цьому випадку першою цифрою повинна бути цифра 0, число може містити тільки цифри 0...7. Цілі константи можна записувати й у шістнадцятковій системі числення. У цьому випадку запис константи починається із символів 0x чи 0X. Для позначення цифр понад 9 використовуються латинські букви a, b, c, d, e та f (великі або маленькі).

Константи символьного типу char беруть в одиночні лапки (апострофи), значення константи визначається знаком з поточного набору символів або цілою константою, якій передує зворотна коса риска (символ із заданим кодом). Є ряд спеціальних символів, що можуть використовуватись як значення константи типу char (такі подвійні символи називаються послідовностями керування, або escape-послідовностями):

Послідовність керування Що представляє
  \a звуковий сигнал
  \b повернення (backspace)
  \f нова сторінка
  \n новий рядок
  \r перехід на початок рядку
  \t горизонтальна табуляція
  \v вертикальна табуляція
  \' одиночні лапки (апостроф)
  \" подвійні лапки
  \\ зворотна коса риска (backslash)
  \ooo ASCII-символ у вісімковій нотації
  \xhh ASCII-символ у шістнадцятковій нотації

Константи дійсних типів можуть записуватись у формі з рухомою крапкою або в експонентному форматі та усталено мають тип double (число з рухомою крапкою подвійної точності). За необхідності тип константи можна уточнити, записавши наприкінці суфікс f чи F для типу float, суфікс l чи L для типу long double. Можна також явно використовувати суфікси d і D для double. Наприклад:

1.5f    // 1.5 типу float
2.5E-2d // 0.25 типу double

Константа-рядок (літерал, string literal) складається із символів, які беруть у подвійні лапки (" "). Наприклад:

"Це рядок"

Константа-рядок може включати escape-послідовності. Якщо між двома константами нічого немає, окрім пропусків та переходів на новий рядок, компілятор поєднує їх в одну. Константа-рядок подається масивом символів, що містить, крім символів рядка, завершальний символ з кодом 0 ('\0'). Такі рядки називаються рядками, які закінчуються нульовим закінченням (null-terminated strings).

2.7 Визначення змінних та іменованих констант

Змінна – це іменована область пам'яті, до якої є доступ у програмі. Кожна змінна має певний тип. Зі змінною пов'язується її значення, яке зберігається в певному місці пам'яті (rvalue – праве значення, у присвоєнні стоїть праворуч), і її місце розташування, тобто адреса в пам'яті, за якою зберігається її значення (lvalue – ліве значення).

Змінна може бути оголошена і повинна бути визначена. Синтаксис оголошення змінних буде розглянуто нижче у контексті створення заголовних файлів.

Визначення змінної викликає виділення пам'яті. Визначення задає ім'я змінної та її тип і закінчується крапкою з комою:

ім'я_типу ім'я_змінної;

Доцільно вживати змістовні імена змінних. Змінні з короткими іменами (з однієї літери) повинні мати обмежену видимість.

Якщо необхідно визначити кілька змінних однакового типу, їхні ідентифікатори записуються через кому:

int x, y; // Дві цілих змінних з невизначеними значеннями 

Оголошення і визначення спільно називаються описами. Слід зауважити, що коли в описах відсутнє ім'я типу але присутні інші модифікатори (long, short, signed, unsigned), припускається, що змінна має тип int. Наприклад,

short s;    // коротке ціле
unsigned s; // беззнакове ціле 

Певне значення змінній можна присвоїти за допомогою оператора присвоєння (=). В такий спосіб можна присвоїти значення 5 змінній width, написавши

unsigned short width;
width = 5;

Визначення часто об'єднують з ініціалізацією:

unsigned short width = 5;

Ініціалізація дуже схожа на присвоєння. Істотна різниця в тому, що ініціалізація відбувається в момент створення змінної.

Повинно бути одне і тільки одне визначення змінної в програмі. Змінна не може використовуватись до її визначення. Ініціалізувати змінну можна також константою в дужках:

int a = 10; // Змінна цілого типу з початковим значенням 10
int b(10);  // Те ж саме 

Можна ініціалізувати більше однієї змінної під час створення. Наприклад:

long width = 5, length = 7; 

Можна об'єднувати визначення та ініціалізацію в різних комбінаціях:

int myAge = 39, yourAge, hisAge = 40;

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

У C ++ ми можемо присвоювати цілі значення змінним з рухомою крапкою і навпаки. Наприклад:

double x = 10; 
int n = 10.5;  // отримали цілу частину, n = 10

Для подання константних величин можуть використовуватися так звані іменовані константи (symbolic constants). Значення іменованої константи не можна змінювати в програмі. Приклад опису константи:

const int yearOfBirth = 1901; 

Тут yearOfBirth – це константа типу int. Її значення не може бути змінене.

Якщо під час опису ім'я типу було пропущене, константа вважається цілою. Наприклад:

const n = 2; // те саме, що const int n = 2;

Слід запобігати подібному стилю опису констант.

У версії C++ 2011 року (C++11) до синтаксису мови додано механізм автоматичного визначення типів, який дозволяє компілятору створювати локальні змінні, тип яких залежить від контексту. Для опису таких змінних застосовують ключове слово auto. Такі змінні обов'язково повинні бути ініціалізовані. Тип змінної компілятор визначає відповідно до типу виразу, яким ця змінна ініціалізується. Наприклад:

auto i = 10;   // ціла змінна
auto x = 10.5; // змінна типу double

Попри те, що тип не вказано явно, компілятор створює змінну певного типу. Після того, як змінна створена, не можна змінювати її тип. Такий підхід є виправданим лише для складних типів. Ця та інші можливості нових версій C++ будуть розглянуті пізніше.

2.8 Вирази та операції

2.8.1 Вирази, операції та операнди

Вираз – це конструкція мови, яка складається з однієї або декількох операцій і може приводити до отримання певного результату під час виконання програми.

Операція – це атомарний (неподільний) вираз. Об'єктами операцій є операнди. Залежно від кількості операндів виділяють унарні операції (один операнд), бінарні операції (два операнди) і тернарні операції (три операнди).

Знак операції (operator) – це символ (або декілька символів), який визначає дію над операндами.

Належна практика кодування вимагає розташування пропусків між першим операндом, оператором і другим операндом. Унарна операція не відокремлюється від операнда пропуском.

2.8.2 Присвоєння

Оператор присвоєння (=) обумовлює зміну значення лівого операнда на значення виразу, який знаходиться праворуч. Вираз

x = a + b;

присвоює операнду x значення, яке є результатом додавання a до b.

Результатом операції присвоєння є значення того виразу, що присвоюється лівому операнду. Це значення може бути використане у виразі. Наприклад:

a = (b = (c = (d = 0))); // Ми присвоюємо 0 всім змінним

Дужки не потрібні, оскільки оператор присвоєння виконується справа наліво:

a = b = c = d = 0; 

2.8.3 Математичні операції

Існує п'ять математичних операцій: додавання (+), віднімання (-), множення (*), ділення (/) і залишок від ділення (%). Крім того, перед числами можна використовувати унарні операції + і -.

Математичні операції (окрім залишку від ділення) можна застосовувати як до цілих операндів, так і для операндів з рухомою крапкою. Якщо один з операндів має тип з рухомою крапкою, значення іншого операнда також перетворюється на цей тип і здійснюється виконання операції з рухомою крапкою. Якщо обидва операнди мають цілий тип, операція виконується для цілих. Час виконання операцій для цілих операндів зазвичай значно менше, ніж для операндів з рухомою крапкою.

Математичні операції можна використовувати у виразах для ініціалізації нових змінних. У виразах можна використовувати попередньо обчислені значення:

double x = 2.4 / 2; // 1.2
double y = x + 10;  // 11.2

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

Є два способи ділення: ділення з рухомою крапкою (комою) і ціле ділення. Перший варіант працює, як можна було б очікувати:

double a = 10;
double b = 4;
double c = a / b; // c = 2.5

Операція ділення двох цілих чисел повертає цілу частину результату:

int a = 10;
int b = 4;
int c = a / b;    // c = 2
double d = a / b; // d = 2.0

Примітка: результат залежить від типів операндів. Компілятор ігнорує тип змінної, яка отримує результат.

Типовою помилкою, пов'язаною з цілим діленням є спроба отримати половину, третину тощо в такий спосіб:

double x = 1 / 2;
double y = 1 / 3;

Обидві змінні будуть дорівнювати нулю, оскільки здійснюється ціле ділення. Можна написати, наприклад, так:

double x = 1.0 / 2;
double y = 1.0 / 3;

Оскільки принаймні один операнд є константою з рухомою крапкою, здійснюватиметься ділення з рухомою крапкою.

Оператор отримання залишку від ділення можна застосовувати тільки до цілих операндів:

int a = 10;
int b = 3;
int c = a % b;    // c = 1

Обидва операнди повинні бути цілими числами.

Операцію отримання залишку від ділення дуже часто застосовують для перевірки, чи є певне ціле число парним (або непарним). Якщо результат знаходження залишку від ділення цілого числа n

n % 2

дорівнює нулю, це означає, що число n парне.

У C++ немає операції обчислення степенів числа, зокрема, другого степеня. Для обчислювання степенів існує функція pow(), але її використання для обчислення другого степеня неефективне. Доцільно застосовувати множення значення на себе. Так само доцільно обчислювати третій і четвертий степінь.

Операції дуже часто об'єднують у вирази, аналогічно математичним виразам. У кожної операції є свій пріоритет. Множення має більш високий пріоритет, ніж складання. Для зміни порядку виконання операцій можна використовувати дужки.

Наприклад, результат обчислення виразу буде 16:

double y = 1 + 3 * 5; // 16

Однак, якщо додати дужки,

y = (1 + 3) * 5; // 20

результат буде іншим.

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

2.8.4 Складене присвоєння

Складене присвоєння можна представити в загальному вигляді в такий спосіб:

a op= b 

У нашому випадку op – арифметична чи побітова операція: + - * / % | & ^ << >>. Кожна складена операція еквівалентна такому присвоєнню:

a = (a) op (b);

Наприклад,

x += 5;

еквівалентно виразу

x = x + 5;

Операція складеного присвоєння також повертає результат – нове значення змінної. Наприклад:

x = 2;
y = (x += 5); // x = 7, y = 7

2.8.5 Операції інкременту та декременту

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

k = 1;
// Інкремент:
++k; // тепер k = 2, еквівалентно k += 1
// Декремент:
--k; // тепер знову k = 1, еквівалентно k -= 1

Операції інкременту та декременту мають дві форми: префіксну і постфіксну. Префіксна форма забезпечує збільшення або зменшення змінної до того, як значення операції буде використано, а постфіксна – після. Наприклад:

k = 1;
// Префіксна форма:
n = ++k; // k = 2, n = 2
k = 1;
// Постфіксна форма:
n = k++; // k = 2, n = 1

Аналогічний приклад можна навести для декременту.

Операції інкременту і декременту можуть бути причинами помилок, пов'язаних з неправильним розумінням послідовності дій. Наприклад, префіксна операція дає очікуваний результат:

int i = 1;
i = ++i + ++i; // i = 6

Результат постфіксної операції не такий очікуваний:

int i = 1;
i = i++ + i++; // i = 2

Фактично результат обох постфіксних операцій не був використаний.

Бажано уникати подібних конструкцій.

2.8.6 Операції відношення

Операції відношення (relational operators) використовують для порівняння значень операндів. Результатом операції відношення може бути 1 (true) або 0 (false). Наведена нижче таблиця містить операції відношення:

Назва Оператор Приклад Результат
дорівнює == 100 == 50; false
50 == 50; true
не дорівнює    != 100 != 50; true
50 != 50; false
більше > 100 > 50; true
50 > 50; false
більше або дорівнює >= 100 >= 50; true
50 >= 50; true
менше < 100 < 50; false
50 < 50; false
менше або дорівнює <= 100 <= 50; false
50 <= 50; true

Слід відрізняти операцію присвоєння (=) від операції порівняння (==). Неправильне вживання присвоєння замість порівняння може призвести до дуже неприємних помилок.

Замість значень false і true результат можна інтерпретувати як ціле – 0 або 1. У C++ будь-яке значення, яке не дорівнює нулю, інтерпретується як true. Тільки значення 0 (будь-якого типу) інтерпретується як false. Тому в коді, де потрібно перевіряти на ненульове значення змінну a, замість a != 0 можна записати просто a.

Операції відношення можна комбінувати з арифметичними:

int a = 1;
int b = 2;
int c = (a < b) + 2 * (b == 2); // c = 3

Примітка: пріоритет арифметичних операцій вище, ніж операцій порівняння, тому дужки тут обов'язкові.

Такий стиль програмування призводить до виникнення коду, який погано читається. Окрім того, такі можливості відсутні в мовах, які використовують синтаксис C++ як базовий, наприклад, C# і Java.

2.8.7 Логічні операції

Логічні операції (logical operators) використовуються для об'єднання декількох умов. У наведеній нижче таблиці наведено логічні операції:

Операція Оператор Приклад
І && вираз1 && вираз2
АБО || вираз1 || вираз2
НЕ ! !вираз

Логічна операція І оцінює два вирази, і якщо обидва вирази істинні, результат логічного І також "істина" (true). В інших випадках результат буде хибним. Логічна операція АБО оцінює два вирази, і якщо обидва вирази хибні, то результат операції АБО також хибний. В інших випадках результат істинний. Логічна операція НЕ дає результат true, якщо вираз хибний, і навпаки.

Примітка: якщо замість пар символів && і || вживати & і | , замість логічних ми отримаємо так звані побітові операції (bitwise operators), які будуть розглянуті нижче.

Якщо застосувати операцію "НЕ" до цілого ненульового значення, ми отримаємо 0, до нульового – одиницю. Наприклад, !7 дорівнює нулю, !!7 дорівнює одиниці.

Операції відношення та логічні операції часто комбінують для отримання більш складного результату. Наприклад:

int a = 1;
int b = 2;
bool c = a < b &&  b == 2; // c = true

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

2.8.8 Побітові операції

C++ надає можливість використання так званих побітових операцій, які працюють з окремими бітами цілих чисел. Операнди повинні бути цілими числами (переважно цілі без знака). Наприклад:

unsigned char c1 = 168;     // 10101000
unsigned char c2 =  26;     // 00011010

Операція ТА (&, один амперсанд, на відміну від логічної операції), якщо її застосувати до двох бітів, повертає 1, якщо обидва біти мають значення 1, та 0, якщо один або обидва біти дорівнюють 0:

unsigned char c3 = c1 & c2; // 00001000, або 8 

Операція АБО (|, одна вертикальна риска, на відміну від логічного АБО), якщо її застосувати до двох бітів, повертає 0, якщо обидва біти мають значення 0, та 1, якщо один або обидва біти дорівнюють 1:

unsigned char c4 = c1 | c2; // 10111010, або 186

Операція ВИКЛЮЧНЕ АБО (^) для двох однакових бітів встановлює результат в одиницю, якщо біти різні та нуль, якщо вони однакові:

unsigned char c5 = c1 ^ c2; // 10110010, або 178

Операція побітового заперечення, або доповнення (~) встановлює нулі в одиниці, а одиниці в нулі. Наприклад:

unsigned char c6 = ~c1;     // 01010111, або 87 

Оператор << переміщує біти ліворуч. Ця операція відкидає крайній лівий біт і присвоює 0 крайньому правому біту. Наприклад:

unsigned char c7 = c1 << 1;  // 01010000, або 80

Оператор >> переміщує біти праворуч. Ця операція відкидає крайній правий біт і присвоює 0 крайньому лівому біту. Наприклад:

unsigned char c8 = c1 >> 2; // 00101010, або 42

Можна використовувати складене присвоєння: &=, |=, ^=, <<= і >>=.

Побітові операції можна використовувати для швидкого множення цілих чисел або цілого ділення на степені числа 2:

int k = 6;
int m = k << 3; // m = k * 8 = 48
m >>= 2;        // m = m / 4 = 12

Такі операції виконуються найбільш швидко.

Робота з окремими бітами часто використовують для визначення і читання окремих ознак, які можуть бути або присутні, або не присутні. Змінні (або окремі біти), які містять тільки 0 або 1, в програмуванні іменують прапорцями (flags). Встановлення окремих бітів у цілому числі використовують замість роботи з різними змінними для більшої автоматизації, збереження пам'яті та підвищення ефективності. Припустимо, є беззнакова ціла state, окремі біти якої визначають окремі ознаки (елементи стану). За допомогою побітових операцій можна встановлювати або перевіряти окремі біти:

unsigned char state = 0;
unsigned char flag = 0b00000100; // встановлено один біт, який нас цікавить
state |= flag;  // 00000100
bool flagSet = state & flag; // true
state &= ~flag; // 00000000
flagSet = state & flag; // false

Пізніше цей підхід ми застосуємо для визначення стану великої програми.

2.8.9 Операція "кома"

Операція "кома" дозволяє замість одного виразу записувати кілька виразів, розділених комами. Ці вирази обчислюються зліва направо. Типом і значенням результату є тип і значення правого (останнього) виразу. Наприклад, вираз

x = (i = 0, j = i + 4, k = j); 

еквівалентний виразу

i = 0; j = i + 4; k = j; x = k; 

Дужки в цьому прикладі є обов'язковими.

2.8.10 Умовна операція

Умовна операція (?:) – це єдина тернарна операція C++ (операція, яка приймає три операнди).

вираз1 ? вираз2 : вираз3

Цей рядок слід читати так "Якщо вираз1 істинний, повертаємо значення вираз2, в іншому випадку повертаємо значення вираз3". Зазвичай це значення буде присвоєно змінній. Наприклад:

min = a < b ? a : b;

У наведеному рядку мінімальне значення з a і b присвоюється змінній min.

Синтаксично можна використовувати умовну операцію для реалізації розгалуження, не пов'язаного з присвоенням різних значень одній змінній:

a < b ? a = x : b = x;

В таких випадках більш доцільно використовувати твердження if, яке буде розглянуто пізніше.

2.8.11 Операція sizeof

Унарна операція sizeof повертає розмір операнда у байтах. Операнд операції sizeof може бути одним з таких:

  • ім'я типу; щоб використовувати sizeof з ім'ям типу, ім'я має бути взяте в круглі дужки;
  • вираз; у цьому випадку операнд може бути вказаний з або без дужок; вираз не обчислюється.

Приклад 3.1 демонструє використання операції sizeof.

2.8.12 Використання операцій для введення і виведення даних

У мові C++ немає окремих операцій для введення і виведення. Стандартна бібліотека C надає функції scanf() і printf(), які забезпечують відповідно консольне введення і виведення. Використання цих функцій буде розглянуто пізніше.

Замість функцій scanf() і printf(), які не забезпечують належного контролю типів, мова C++ пропонує більш надійний і зручний спосіб для введення і виведення даних. Цей спосіб побудовано на використанні потоків введення-виведення. Мова C++ дозволяє перевизначати операції для об'єктів стандартних і нестандартних класів. Для класу, який представляє потік введення, визначена операція зсуву праворуч (>>). Ця операція здійснює читання з потоку окремих лексем і перетворення їх у дані, які відповідають типам змінних – операндів, які розташовані ліворуч від об'єкта-потоку. Аналогічно, для потоку виведення визначена операція зсуву ліворуч (<<) для виведення даних. Формат виведення визначається типами змінних. Можна також виводити константи, зокрема, літерали. Для переведення курсора на новий рядок у потік виведення заносять маніпулятор endl.

У наведеному нижче прикладі зі стандартного потоку читання (з клавіатури) зчитується одне ціле, одне дійсне значення і один символ. Зчитані значення виводяться у стандартне консольне вікно:

int k;
double x;
char c;
cin >> k >> x >> c;
cout << k << " " << x << " " << c << endl;
// без символів пропусків дані будуть зшиті в одну лексему

Існують додаткові можливості форматування даних під час виведення. Наприклад, додавання в потік setw(n) обумовлює відведення n позицій для виведення поточних даних.

Для роботи зі стандартними потоками до сирцевого коду слід додати підключення заголовного файлу iostream. Засоби для роботи з потоками визначені в просторі імен std.

2.9 Твердження-вираз

2.9.1 Поняття твердження

У мові C++ твердження (інструкція, statement, іноді оператор) є мінімальною одиницею програмного коду. Вирази та операції входять в твердження. Послідовність тверджень реалізує певний алгоритм.

Можна навести таку класифікацію тверджень:

  • твердження опису
  • порожнє твердження
  • твердження-вираз
  • складене твердження
  • твердження вибору
  • твердження циклу
  • твердження переходу
  • твердження перехоплення й обробки винятків.

Твердження опису – єдині, які можуть бути розташовані як всередині функцій, так і поза ними. Твердження опису були розглянуті раніше.

2.9.2 Твердження-вирази

Усі вирази, які завершуються крапкою з комою, є твердженнями-виразами (expression statements). Одним з найбільш вживаних тверджень є твердження з виразом присвоєння:

a = x + 1;

Мова C++ дозволяє створювати твердження з операцій, які не містять присвоєння:

x + 1;
a;

Здебільшого такі твердження не мають сенсу, оскільки результат операції ніде не зберігається. Але саме так здійснюється виклик функцій з результатом void, наприклад:

system("pause");

Подібні твердження також використовують для введення та виведення даних:

cin >> x;
cout << x;

Наведена нижче програма обчислює суму двох цілих значень, введених користувачем:

#include <iostream>

using namespace std;

int main()
{
    setlocale(LC_ALL,"UKRAINIAN");
    int a, b, c;
    cout << "Уведіть a та b: ";
    cin >> a >> b;
    c = a + b;
    cout << "Сума: " << c << endl;
    return 0;
}

Для забезпечення коректного виведення тексту українською мовою нам необхідно викликати стандартну функцію setlocale(LC_ALL,"UKRAINIAN"), яка вказує на використання відповідної кодової таблиці. На жаль літера і все одно виводиться некоректно. Тому в рядках її доцільно замінити на літеру i англійського алфавіту.

Цю програму можна модифікувати. Створення та обчислення c можна об’єднати:

    ...
    int a, b;
    cout << "Уведіть a та b: ";
    cin >> a >> b;
    int c = a + b;
    ...

Програму можна спростити. Створення змінної c не має сенсу. Ми можемо розрахувати суму безпосередньо перед її виведенням. Тож остаточна версія буде такою:

#include <iostream>

using namespace std;

int main()
{
    setlocale(LC_ALL,"UKRAINIAN");
    int a, b;
    cout << "Уведiть a та b: ";
    cin >> a >> b;
    cout << Сума: " << (a + b) << endl;
    return 0;
}

Тепер компілятор не створює зайву комірку в пам'яті. Зайве копіювання також не виконується.

3 Приклади програм

3.1 Кількість байтів пам'яті для зберігання даних різних типів

Програма дозволяє отримати кількість байтів пам'яті для зберігання даних різних типів:

#include <iostream>

using namespace std;

int main()
{
    setlocale(LC_ALL,"UKRAINIAN");
    cout << "Розмiр int дорiвнює:\t\t"     << sizeof(int)    << " bytes.\n";
    cout << "Розмiр short int дорiвнює:\t" << sizeof(short)  << " bytes.\n";
    cout << "Розмiр long int дорiвнює:\t"  << sizeof(long)   << " bytes.\n";
    cout << "Розмiр char дорiвнює:\t\t"    << sizeof(char)   << " bytes.\n";
    cout << "Розмiр float дорiвнює:\t\t"   << sizeof(float)  << " bytes.\n";
    cout << "Розмiр double дорiвнює:\t"    << sizeof(double) << " bytes.\n";
    return 0;
}

3.2 Коди символів

Ця програма дозволяє друкувати коди символів, уведених з клавіатури:

#include <iostream>

using namespace std;

int main()
{
    char c;
    cin >> c;     // уводимо символ 
    int i = c;    // перетворюємо символ у ціле число
    cout << i << '\n'; // виводимо код
    return 0;
}

3.3 Шістнадцяткові числа

Наведена нижче програма друкує шістнадцяткове представлення чисел:

#include <iostream>

using namespace std;

int main()
{
    int i;
    cin >> i;   // уводимо ціле
    cout << dec << i << ' ' << hex << i << '\n';
    return 0;
}

З наведеного прикладу видно, що стан об'єктів-потоків можна змінити за допомогою так званих маніпуляторів. Можна встановити основу системи числення за допомогою dec (десятковий), oct (вісімковий), або hex (шістнадцятковий).

3.4 Ціла частина значення

У наведеній нижче програмі виводиться ціла частина числа з рухомою крапкою:

#include <iostream>

using namespace std;

int main()
{
    double d;
    int i;
    cin >> d; // уводимо значення з рухомою крапкою
    i = d;    // перетворюємо double на int
    cout << d << ' ' << i << '\n';
    return 0;
}

3.5 Отримання степенів числа 2

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

#include <iostream>

using namespace std;

int main()
{
    unsigned int k;
    cout << "Enter exponent (0 to 31): ";
    cin >> k; // уводимо показник степеня
    unsigned int result = 1 << k; // отримуємо степінь двох,
                                  // нульова степінь - це одиниця
    cout << result << '\n';
    return 0;
}

3.6 Копіювання бітів

Припустимо, необхідно ввести беззнакове ціле число, скопіювати його молодший біт (який розташований праворуч) в позицію 6 (рахуючи від 0 справа наліво) і вивести величину, яку ми отримали. Програма може бути такою:

#include <iostream>

using namespace std;

int main()
{
    unsigned int k;
    cin >> k;
    unsigned int bit = 1 & k; // отримуємо значення молодшого біта
    bit <<= 6;                // зсуваємо на 6 позицій
    k &= ~(1 << 6);           // очищуємо шосту позицію 
    k |= bit;                 // записуємо біт у відповідну позицію
    cout << k << '\n';
    return 0;
}

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

3.7 Умовна операція

Припустимо, необхідно створити програму, в якій здійснюється читання x та обчислення y відповідно до таблиці:

x y
менше, ніж -8 100
від -8 до 1 200
більше, ніж 1 300

Скористаємось умовною операцією:

#include <iostream>

using namespace std;

int main()
{
    double x;
    cin >> x;
    double y = x < -8 ? 100 : (x <= 1 ? 200 : 300);
    cout << y;
    return 0;
}

4 Вправи для контролю

Завдання 1

Розробити програму, в якій здійснюється читання символу і виведення його шістнадцяткового коду.

Завдання 2

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

Завдання 3

Розробити програму, в якій здійснюється читання дійсного x та обчислення y (математична функція signum) з використанням умовної операції:

x y
менше 0 -1
0 0
більше 0 1

5 Контрольні запитання

  1. Які є етапи розробки програми мовою C++?
  2. У чому різниця між компілятором і лінкером?
  3. Що таке інтегроване середовище розробки?
  4. Які мови програмування підтримує Visual Studio?
  5. Що таке зневадження?
  6. Як створити новий проєкт у Visual Studio?
  7. Як зневаджувати програми в Visual Studio?
  8. У чому різниця між коментарями стилю C і стилю C++?
  9. Що таке препроцесор?
  10. У чому різниця між знаковими і беззнаковими цілими?
  11. Що таке константа?
  12. Як визначити шістнадцяткову константу?
  13. Що таке escape-послідовність?
  14. Що таке літерал?
  15. Що таке змінна?
  16. Як визначити змінну?
  17. Що таке іменована константа?
  18. Для чого використовують операцію sizeof?
  19. Що таке вираз?
  20. Що таке операція?
  21. У чому різниця між операціями присвоєння та складеного присвоєння?
  22. У чому різниця між префіксними і постфіксними операціями інкременту і декременту?
  23. Який тип операції відношення?
  24. Які є логічні операції?
  25. Що таке операція "кома"?
  26. Що таке умовна операція?
  27. Що таке твердження-вираз?

 

up