Лекция № 30. Другие директивы препроцессора.
Содержание лекции.
-
Директивы препроцессора.
-
Условная компиляция.
2. Условная компиляция.
1. Директива условной компиляции-проверка существования определенного имени
В предшествующих советах представлялись символы констант и макрокоманд, определенные в самом Си-компиляторе. Там же рассматривались вопросы определения в программе собственных констант и макрокоманд. При написании программы могут быть случаи, когда требуется, чтобы препроцессор проверял, определен ли заданный символ, и выполнял определенный набор операций, если символ действительно определен. Для обеспечения программы средствами такой условной трансляции компилятор языка Си поддерживает директиву условной компиляции #ifdef, которая имеет следующий формат:
#ifdef symbol
// операторы
#endif
Встречая директиву #ifdef, препроцессор выполняет проверку, был ли определен заданный символ. Если да, то препроцессор обрабатывает последующие операторы программы вплоть до директивы #endif. Аналогичным образом, иногда оказывается удобнее, чтобы препроцессор обрабатывал заданную группу операторов, когда указанный символ не определен. В таких случаях может использоваться директива #ifndef. В следующих операторах директива #ifndef используется для определения макрокоманды _toupper, если одноименная макрокоманда еще не определена:
#ifndef _toupper
#define _toupper(c) ((((с)>='а')&&((с)<='z')) ? (с) - 'а' + 'А': с)
#endif
2 Условная компиляция If-Else
Из С 149 стало известно, как использовать директивы условной компиляции #ifdef, #ifndef и #еndif для задания набора операторов, которые должны быть выполнены препроцессором, если символ определен (#ifdef) или неопределен (#ifndef). Возможны случаи, когда требуется включить еще один шаг обработки, чтобы препроцессором выполнялся один набор операторов при значении "истина" проверяемого условия и другой набор операторов, если значение "ложь". Для выполнения такой обработки может быть использована директива #else следующим образом:
#ifdef symbol
// Операторы
#else
// Другие операторы
#endif
4. Дополнительные возможности условной компиляции
Известно, как директивы #ifdef и #ifndef могут быть использованы для проверки, определен ли зданный символ, и обработки определенной группы операторов в зависимости от положительного или отрицательного результата проверки. В некоторых случаях бывает необходимо выполнить такую проверку для нескольких символов или их комбинаций. В следующих директивах сначала проверяется, определен ли символ MY_LIBRARY. Если символ определен, то проверяется, не является ли неопределенным символ MY_ROUTINES. Если MY_ROUTINES не был определен, то препроцессор должен включить заголовочный файл my_code.h:
#ifdef MY_LIBRARY
#ifndef MY_ROUTINES
#include "my_code.h"
#endif
#endif
Хотя представленная последовательность директив и делает то, что нужно, исходный код труден для понимания. В качестве альтернативы для проверки, определен ли символ, может использоваться директива #if с оператором defined следующим образом:
#if defined (symbol)
// Операторы
#endif
Преимущество использования директивы #if заключается в том, что можно задавать комбинированное условие для проверки. Например, следующая директива выполняет те же проверки, что и представленные выше:
#if defined (MY_LIBRARY) && !defined (MY_ROUTINES)
#include "my_code.h"
#endif
С помощью #if defined можно конструировать условия, в которых используются логические операторы (&&, || и !).