Условная компиляция. Директивы #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 constant_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. Примеры
⇑