Умовна компіляція. Директиви #if, #else, #elif, #endif, #ifdef, #ifndef. Оператор defined
Зміст
- 1. Директиви #if, #else, #elif, #endif. Умовна компіляція
- 2. Директиви #ifdef, #ifndef. Умовна компіляція
- 3. Оператор defined. Визначення, чи існує в програмі макроім’я
- Споріднені теми
1. Директиви #if, #else, #elif, #endif. Умовна компіляція
1.1. Комбінація директив #if – #endif
З допомогою директив #if, #else, #elif, #endif можна задати ті частини програми, які потрібно відкомпілювати в залежності від значення константного виразу.
Загальна форма директиви #if наступна
#if consant_expression operators_sequence #endif
тут
- constant_expression – константний вираз, який повертає true або false;
- operator_sequence – послідовність операторів, яка виконується якщо constant_expression=true.
Приклад.
#include <iostream> using namespace std; // Номер рішення #define N_SOLUTION 2 // Число Пі #define Pi 3.1415926535 // Якщо рішення рівне 1, то обчислити довжину кола #if N_SOLUTION == 1 #define RESULT(radius) 2*Pi*radius #endif // Якщо рішення 2, то обчислити площу круга #if N_SOLUTION == 2 #define RESULT(radius) Pi*radius*radius #endif void main() { // 1. Радіус double r; // 2. Ввести радіус кола cout << "r = "; cin >> r; // 3. Обчислити площу круга double area = RESULT(r); cout << "area = " << area << endl; }
Результат виконання програми
r = 3 area = 28.2743
⇑
1.2. Комбінація директив #if – #else – #endif
Директиви #if – #else – #endif дозволяють відкомпілювати одну з двох частин програми в залежності від значення умовного виразу. Загальна форма використання даної директиви наступна:
#if consant_expression operators_sequence_1 #else operators_sequence_2 #endif
тут
- constant_expression – вираз, що повертає значення логічного типу (true або false);
- operators_sequence_1 – послідовність операторів, яку потрібно виконати якщо constant_expression=true;
- operators_sequence_2 – послідовність операторів, яку потрібно виконати якщо constant_expression=false.
Приклад.
У прикладі в залежності від значення N_SOLUTION компілюється потрібний фрагмент коду, який визначає довжину кола або площу круга.
#include <iostream> using namespace std; // Номер рішення #define N_SOLUTION 1 // Число Пі #define Pi 3.1415926535 // Якщо рішення рівне 1, то компілюється фрагмент, що обчислює довжину кола, // інакше компілюється фрагмент що обчислює площу круга. #if N_SOLUTION == 1 #define RESULT(radius) 2*Pi*radius #else #define RESULT(radius) Pi*radius*radius #endif void main() { // 1. Радіус double r; // 2. Ввести радіус кола cout << "r = "; cin >> r; // 3. Обчислення double result = RESULT(r); cout << "result = " << result << endl; }
Результат
r = 3 result = 18.8496
⇑
1.3. Комбінація директив #if – #elif – #endif. Ланцюжок if-else-if
Комбінація директив #if-#elif-#endif утворює так званий ланцюжок if-else-if або сходинкову (каскадну) форму директиви #if. Директива #elif розшифровується як else-if. З допомогою цієї форми директив можна виконувати перевірку багатьох умов. Загальний вигляд директиви #if-#elif-#endif наступний
#if expression_1 operators_sequence_1 #elif expression_2 operators_sequence_2 ... #elif expression_N operators_sequence_N #endif
тут
- expression_1, expression_2, expression_N – деякий вираз, який може справджуватись (true) або не справджуватись (false);
- operators_sequence_1, operators_sequence_2, operators_sequence_N – послідовність операторів, які потрібно відкомпілювати у відповідному блоці коду.
Приклад.
У прикладі, в залежності від значення N_SOLUTION обчислюється відповідна
#include <iostream> using namespace std; // Номер рішення #define N_SOLUTION 3 // Число Пі #define Pi 3.1415926535 // Компілюється фрагмент, що відповідає відповідному номеру рішення. #if N_SOLUTION == 1 #define RESULT(radius) 2*Pi*radius // довжина кола #elif N_SOLUTION == 2 #define RESULT(radius) Pi*radius*radius // площа круга #elif N_SOLUTION == 3 #define RESULT(radius) 4.0/3*Pi*radius*radius*radius // об'єм кулі #endif void main() { // 1. Радіус double r; // 2. Ввести радіус кола cout << "r = "; cin >> r; // 3. Обчислення double result = RESULT(r); cout << "result = " << result << endl; }
Результат
r = 3 result = 113.097
⇑
2. Директиви #ifdef, #ifndef. Умовна компіляція
Директиви #ifdef та #ifndef забезпечують ще один вид умовної компіляції. Дослівно значення директив можна визначити так: “if defined” (якщо визначено), “if not defined” (якщо не визначено).
Загальний вигляд директив #ifdef наступний:
#ifdef macros_name operators_sequence #endif
тут
- macros_name – ім’я макросу, яке перевіряється на те, чи воно визначене оператором #define. Якщо ім’я макросу визначене, то виконується послідовність operators_sequence;
- operators_sequence – деяка послідовність.
Загальний вигляд директиви #ifndef наступний:
#ifndef macros_name operators_sequence #endif
тут
- macros_name – ім’я макросу, яке може бути визначеним або не визначеним. Якщо ім’я макросу визначене директивою #define, послідовність operator_sequence не виконується;
- operators_sequence – послідовність операторів.
Приклад.
#include <iostream> using namespace std; #define Is_Calc_Length // Чи потрібно визначати макрос Length? // Якщо потрібно визначити макрос, що обчислює відстань // між двома точками, то визначити його #ifdef Is_Calc_Length #define Length(x1, y1, x2, y2) sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) #endif // Якщо не потрібно визначати макрос Length, то повернути 0 #ifndef Is_Calc_Length #define Length(x1, y1, x2, y2) 0 #endif void main() { double x1, y1, x2, y2; cout << "x1 = "; cin >> x1; cout << "y1 = "; cin >> y1; cout << "x2 = "; cin >> x2; cout << "y2 = "; cin >> y2; double len = Length(x1, y1, x2, y2); cout << "len = " << len << endl; }
Результат
x1 = 1 y1 = 2 x2 = 3 y2 = 5 len = 3.60555
⇑
3. Оператор defined. Визначення, чи існує в програмі макроім’я
Оператор defined використовується в поєднанні з директивою #if. Поєднання цих двох елементів замінює директиву #ifdef.
Загальна форма використання оператора defined має вигляд
defined macros_name
тут
- macros_name – ім’я макроса, яке перевіряється на наявність.
Приклад.
У прикладі демонструється оригінальний спосіб розв’язків обчислення квадратного рівняння на основі наперед визначених формул.
#include <iostream> using namespace std; // Оператор defined. // Формули обчислення квадратного рівняння. #define D(a, b, c) (b*b - 4*a*c) #define X1(a, b, c) ((-b - sqrt(D(a,b,c))) / (2*a)) #define X2(a, b, c) ((-b + sqrt(D(a,b,c))) / (2*a)) void main() { // Обчислення квадратного рівняння. // Перевірка, чи є наявними формули обчислення квадратного рівняння. #if defined D #if defined X1 #if defined X2 // 1. Оголосити змінні double a, b, c; // 2. Ввести коефіцієнти cout << "a = "; cin >> a; cout << "b = "; cin >> b; cout << "c = "; cin >> c; // 3.Перевірка, чи існує рівняння if (a == 0) { cout << "Incorrect value of a (a==0)." << endl; return; } // 4. Якщо дискримінант більше або рівне 0, то провести обчислення if (D(a, b, c) >= 0) { cout << "x1 = " << X1(a, b, c) << endl; cout << "x2 = " << X2(a, b, c) << endl; } else cout << "The equation has no roots." << endl; #endif #endif #endif }
Результат
a = -3 b = -4 c = 5 x1 = 0.7863 x2 = -2.11963
⇑
Споріднені теми
- Препроцесор. Загальні відомості. Директиви препроцесора. Огляд. Директиви #define, #error, #include, #undef, #import, #using, #pragma, #line
- Макроси. Директива #define. Приклади
⇑