Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Tema_2._Direktivi_preprocesora.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
64 Кб
Скачать

Умовна компіляція

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

Конструкції умови препроцесора в цілому подібні на оператор умови if. Розглянемо наступний код препроцесора:

 #if  !defined(NULL)

#define  NULL  0

#endif.

 Ці директиви встановлюють, чи визначений символ NULL. Вираз defined(NULL) має значення 1, якщо NULL визначений, і 0 в протилежному випадку. Якщо результат – 0, !defined(NULL) приймає значення 1 і виконується визначення NULL. В протилежному випадку директива #define пропускається. Кожна конструкція #if закінчується #endif. Директиви #ifdef i #ifndef – це скорочення для #if defined(ім’я) і #if !defined(ім’я). Умовні конструкції препроцесора, що перевіряють декілька варіантів, реалізуються за допомогою директив #elif (еквіваленту else if структури if) і #else (еквіваленту else структури if).

При розробці програм програмісти, що уникнути компіляції великих частин програми, часто перетворюють їх в тимчасові коментарії. Якщо сам код програми містить коментарії, то /* і */ символи для цього не підходять. В даному випадку можна використовувати наступну конструкцію препроцесора:

 #if  0

Код, компіляцію якого не потрібно здійснювати

#endif

 Щоб дозволити знову компілювати фрагмент коду, потрібно замість аргументу 0 вставити 1 при операторі #if.

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

 #ifdef DEBUG

printf ("Variable x = %d\n", x);

#endif

приведе до того, що оператор printf буде компілюватися в програмі, якщо перед директивою #ifdef DEBUG була визначена (#define DEBUG) символічна константа DEBUG. Коли відладка завершена, директива #define видаляється із вихідного файла і оператори printf, вставлені для мети відладки, будуть при компіляції ігноруватися. В великих програмах бажано визначити декілька символічних констант, щоб мати можливість контролювати умови компіляції окремих частин вихідного файла.

Директиви #error I #pragma

 Директива #error

#error  лексеми виводить на друк залежне від реалізації повідомлення, включаючи лексеми, визначені в директиві. Лексеми – це послідовності символів, розділені пробілами. Так директива

#error 1 – Out of range error

містить шість лексем-ресурсів. Коли виконується директива #error, лексеми в ній відображаються як повідомлення про помилку (що залежить від системи); потім препроцесор зупиняється і програма не компілюється.

Директива #pragma

#pragma  лексеми вказує дію, залежну від реалізації.

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

 Операції #  i  ## в мові С

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

#define HELLO(x) printf ("Hello, " #x "\n");

Коли в файлі програми з’являється вираз Hello(John), він поширюється в printf ("Hello, " "John" "\n");

Лінійка "John" перетворюється в текст заміни замість #x. Препроцесор здійснює конкатенацію лінійок, що розділені тільки символами пробілу, а тому, попередній оператор еквівалентний:

printf ("Hello,  John \n");

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

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

#define TOKENCONCAT(x,y)  x  ##  y.

Коли TOKENCONCAT з’являється в тексті програми, проходить конкатенація його аргументів, після чого вони заміняють макровизначення. Наприклад, TOKENCONCAT(О,К) заміщується в програмі на ОК. Операція ## повинна мати два операнди.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]