Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
+ООП_Навч_посібник.doc
Скачиваний:
8
Добавлен:
01.07.2025
Размер:
6.58 Mб
Скачать

23.2.2. Директиви #ifdef і #ifndef

Директиви #ifdef і #ifndef пропонують ще два варіанти умовного компілювання, які можна виразити як "якщо визначено" і "якщо не визначено" відповідно. Загальний формат використання директиви #ifdef такий.

#ifdef макроім'я

послідовність настанов

#endif

Якщо макроім'я попереднє визначено за допомогою якої-небудь директиви #define, то послідовність настанов, розташована між директивами #ifdef і #endif, буде скомпільована.

Загальний формат використання директиви #ifndef такий.

#ifndef макроім'я

послідовність настанов

#endif

Якщо макроім'я не визначене за допомогою якої-небудь директиви #define, то послідовність настанов, розташована між директивами #ifdef і #endif, буде скомпільована.

Як директива #ifdef, так і директива #ifndef може мати директиву #else або #elif. Розглянемо такий приклад.

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

#define TOM

int main()

{

#ifdef TOM

cout << "Програміст Том.\n";

#else

cout << "Програміст невідомий.\n";

#endif

#ifndef RALPH

cout << "Ім'я RALPH не визначене.\n";

#endif

getch(); return 0;

}

У процесі виконання ця програма відображає наступне.

Програміст Тому.

Ім'я RALPH не визначене.

Але якби ідентифікатор ТОМУ був не визначено, то результат виконання цієї програми виглядав би так.

Програміст невідомий. Ім'я RALPH не визначене.

Необхідно пам'ятати! Директиви #ifdef і #ifndef можна вкладати так само, як і директиви #if.

23.2.3. Директива #undef

Директива #undef використовують для видалення попереднього визначення деякого макроімені. Її загальний формат такий.

#undef макроім'я

Розглянемо такий приклад:

#define TIMEOUT 100 Sdefine WAIT 0

//...

#undef TIMEOUT

#undef WAIT

У цих записах імена TIMEOUT і WAIT визначені доти, доки не виконається директива #undef.

Основне призначення директиви #undef дати змогу локалізацію макроімен для тих частин коду програми, в яких вони потрібні.

23.2.4. Використання оператора defined

Крім директиви #ifdef існує ще один спосіб з'ясувати, чи визначене у програмі деяке макроім'я. Для цього можна використовувати директиву #if у поєднанні з оператором часу компілювання defined. Наприклад, щоб дізнатися, чи визначено макроім'я MYFILE, можна використовувати одну з наступних команд препроцесорного оброблення.

#ifdefined MYFILE АБО

#ifdef MYFILE

У разі потреби, щоб реверсувати умову перевірки, можна передувати оператору defined символом "!". Наприклад, такий фрагмент коду програми скомпілюється тільки у тому випадку, якщо макроім'я DEBUG не визначене:

#if !defined DEBUG

cout << "Остаточна версія!\n";

#endif

23.2.5. Про значення препроцесора

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

На даному етапі препроцесор вже частково надмірний. Наприклад, дві найбільш споживані властивості директиви #define були замінені настановами C++. Зокрема, її здатність створювати константне значення і визначати макровизначення, що діє подібно до функцій, зараз абсолютно надмірна. У мові програмування C++ є ефективніші засоби для виконання цих завдань. Для створення константи достатньо визначити const-змінну. А із створенням вбудовуваної (що підставляється) функції цілком справляється специфікатор inline. Обидва ці засоби краще працюють, ніж відповідні механізми директиви #define.

Наведемо ще один приклад заміни елементів препроцесора елементами мови. Він пов'язаний з використанням однорядкового коментарю. Одна з причин його створення дати змогу "перетворення" коду програми у коментар. Як уже зазначалося вище, коментар, що використовує /*.*/-стиль, не може бути вкладеним. Це означає, що фрагменти коду програми, що містять /*.*/-коментарі, одним махом "перетворити на коментар" не можна. Але це можна зробити з //-коментарями, оточивши їх /*.*/-символами коментарю. Можливість "перетворення" коду програми у коментар робить використання таких директив умовного компілювання, як #ifdef, частково надмірним.