C++. Умовна компіляція. Директиви #if, #else, #elif, #endif, #ifdef, #ifndef. Оператор defined

Умовна компіляція. Директиви #if, #else, #elif, #endif, #ifdef, #ifndef. Оператор 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

 


Споріднені теми