![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Директивы препроцессора
Препроцессором называется первая фаза компилятора. Инструкции препроцессора называются директивами. Они должны начинаться с символа #, перед которым в строке могут находиться только пробельные символы. Директива #include Директива #include < имя_файла> вставляет содержимое указанного файла в ту точку исходного файла, где она записана. Включаемый файл также может содержать директивы #include. Поиск файла, если не указан полный путь, ведется в стандартных каталогах включаемых файлов. Вместо угловых скобок могут использоваться кавычки (" ") — в этом случае поиск файла ведется в каталоге, содержащем исходный файл, а затем уже в стандартных каталогах. Директива #include является простейшим средством обеспечения согласованности объявлений в различных файлах, она включает в них информацию об интерфейсе из заголовочных файлов. Заголовочные файлы обычно имеют расширение.h и могут содержать: § определения типов, констант, встроенных функций, шаблонов, перечислений; § объявления функций, данных, имен, шаблонов; § пространства имен; § директивы препроцессора; § комментарии. В заголовочном файле не должно быть определений функций и данных. Эти правила не являются требованием языка, а отражают разумный способ использования директивы. При указании заголовочных файлов стандартной библиотеки расширение.h можно опускать. Это сделано для того, чтобы не ограничивать способы их хранения. Для каждого файла библиотеки С с именем < name.h> имеется соответствующий файл библиотеки C++ < cname>, в котором те же средства описываются в пространстве имен std. Например, директива #include < cstdio> обеспечивает те же возможности, что и #include < stdio.h>, но при обращении к стандартным функциям требуется указывать имя пространства имен std (см. раздел «Поименованные области». Директива #define Директива #define определяет подстановку в тексте программы. Она используется для определения: § символических констант: #define имя текст_подстановки (все вхождения имени заменяются на текст подстановки); § макросов, которые выглядят как функции, но реализуются подстановкой их текста в текст программы: #define имя(параметры) текст_подстановки § символов, управляющих условной компиляцией. Они используются вместе с директивами #ifdef и #ifndef. Формат: #define имя Примеры: #define VERSION 1 #define VASIA " Василий Иванович" #define MAX(x, y) ((x)> (y)? (x): (y)) #define MUX Имена рекомендуется записывать прописными буквами, чтобы зрительно отличать их от имен переменных и функций. Параметры макроса используются при макроподстановке, например, если в тексте программы используется вызов макроса у = MAX(suml, sum2);, он будет заменен на у = ((suml)> (sum2)? (suml): (sum2)); Отсутствие круглых скобок может привести к неправильному порядку вычисления, поскольку препроцессор не оценивает вставляемый текст с точки зрения синтаксиса. Например, если к макросу #define sqr(x) (x*x) обратиться как sqr(y+l), в результате подстановки получится выражение (у+1*у+1). Макросы и символические константы унаследованы из языка С, при написании программ на C++ их следует избегать. Вместо символических констант предпочтительнее использовать const или enum, а вместо макросов — встроенные функции или шаблоны. Директивы условной компиляции Директивы условной компиляции #if, #ifdef и #ifndef применяются для того, чтобы исключить компиляцию отдельных частей программы. Это бывает полезно при отладке или, например, при поддержке нескольких версий программы для различных платформ. Формат директивы #if: … #if константное_выражение [ #elif константное выражение
…] [ #elif константное_выражение …] [ #else …] #endif Количество директив #elif — произвольное. Исключаемые блоки кода могут содержать как описания, так и исполняемые операторы. Пример условного включения различных версий заголовочного файла: #if VERSION == 1 #define INCFILE " versl.h" #elif VERSION == 2 #define INCFILE " vers2.h" /* и так далее */ #else #define INCFILE " versN.h" #endif #include INCFILE В константных выражениях может использоваться проверка, определена ли константа, с помощью defined(имя_константы), например: #if defined(_BORLANDC_) & & _BORLANDC_ — 0x530 // BC5.3: typedef istream_iterator< int, char, char_traits< char>, ptrdiff_t> istreamjter; #elif difined(_BORLAND_) // BC5.2: typedef istream_iterator< int, ptrdiff_t> istream iter; #else // VC5.0: typedef istream_iterator< int> istream_iter; #endif Другое назначение директивы — временно закомментировать фрагменты кода, например: #if 0 int i, j; double x, у; #endif Поскольку допускается вложенность директив, такой способ весьма удобен. Наиболее часто в программах используются директивы #ifdef и #ifndef, позволяющие управлять компиляцией в зависимости от того, определен ли с помощью директивы #define указанный в них символ (хотя бы как пустая строка, например, #define 32_BIT_SUPP0RT): #ifdef символ // Расположенный ниже код компилируется, если символ определен #ifndef символ // Расположенный ниже код компилируется, если символ не определен Действие этих директив распространяется до первого #elif, #else или #endif. Директива #ifndef часто применяется для того, чтобы обеспечить включение заголовочного файла только один раз: #ifndef HEADER_INCLUDED #include " myheader.h" #define HEADERJNCLUDED #endif Директива #undef Директива #undef имя удаляет определение символа. Используется редко, например, для отключения какой-либо опции компилятора.
|