Невозможно отобразить презентацию
Category: programmingprogramming

Препроцессорные средства

Тема № 10.

Препроцессорные средства 10.1.

Стадии и основные команды препроцессорной обработки Препроцессор языка Си (Си++) представляет собой программу (подпрограмму), которая используется для обработки исходного файла на нулевой фазе компиляции.

Чаще всего препроцессор не отдельная программа, а входит в состав компилятора.

Директивы препроцессора представляют инструкции, записанные в исходном тексте программы.

Они обычно используются для того, чтобы облегчить модификацию исходных программ и сделать их более независимыми от особенностей различных реализаций компилятора языка Си, разных компьютеров и операционных сред.

Стадии препроцессорной обработки 1.Все системно-зависимые обозначения (например, системно-зависимый индикатор конца строки) перекодируются в стандартные коды.

2.Каждая пара символов «\» и «конец строки» убираются, и тем самым следующая строка присоединяется к исходной.

3.В тексте распознаются директивы препроцессора, а каждый комментарий заменяется пробелом.

4.Выполняются директивы препроцессора и выполняются макроподстановки.

5.ESC-последовательности в строках (символах) заменяются на их эквиваленты (числовые коды).

6.Смежные символьные строки объединяются в одну строку.

С помощью директив препроцессора можно выполнять следующие действия

• заменять идентификаторы заранее подготовленными последовательностями символов;

• включать тексты из файлов;

• исключать из текста программы отдельные его части (условная компиляция);

• заменять обозначения параметризованным текстом (макроподстановки).

Определены следующие препроцессорные директивы: #define #include #undef #if #ifdef #else #endif #elif #line #error # ## Указание компилятору: #pragma 10.2.

Замены в тексте Формат: #define <идентификатор> [<текст>] Директива может располагаться в любом месте обрабатываемого текста, ее действие от точки размещения до конца текста.

Директива определяет идентификатор как препроцессорный (это условие можно далее использовать для условной компиляции).

В результате обработки вхождения идентификатора заменяются текстом, окончание которого признак конца строки.

Символы пробела в начале и конце текста в подстановке не участвуют.

Если текст слишком длинный его можно продолжить на другой строке, использую символ «\».

Идентификатор можно переопределять с помощью другого использования #define или отменить его действие с помощью директивы #undef <идентификатор> 10.3.

Макроподстановки Макрос – это средство замены одной последовательности символов другой (замена в тексте простейшая форма макроса).

Большими возможностями обладают макроопределения с параметрами.

Формат: #define <идентификатор>(<список_параметров>) <текст> Примеры: #define max(a, b) a<b?b:a Вхождение в программу max(x, 10) заменяется на x<10? 10:x #define abs(x) x>=0?x:-x Вхождение в программу abs(a) заменяется на a>=0?a:-a Отличие макросов от функций 1.Функции имеют код (за исключением inline- функций) в одном экземпляре, а коды макроса вставляются в программу столько раз сколько используется макрос, причем подстановка для макроса осуществляется всегда.

2.Функции работают с определенными типами параметров, макрос пригоден для обработки параметров любого типа, допустимых в выражении строки замещения.

Механизм перегрузки и шаблоны функций в Си++ позволяют решать те же задачи.

10.4.

Включение текстов из файлов Формат: #include “путь_к_файлу” #include <путь_к_файлу> Включает текст файла в текущий компилируемый файл, когда используются “” файл в первую очередь ищется в текущем каталоге, а затем в системных, а когда <>, то файл ищется в первую очередь в системных каталогах, а затем в текущем.

10.5.

Условная компиляция 1-ая форма: #if <конст_выражение1> [<текст>] [#elif <конст_выражение2> <текст>] [#elif <конст_выражение3> <текст>] …..

[#else <текст>] #endif 2-ая форма #ifdef <идентификатор> [<текст>] [#elif <конст_выражение2> <текст>] [#elif <конст_выражение3> <текст>] …..

[#else <текст>] #endif 3 форма #ifndef <идентификатор> [<текст>] [#elif <конст_выражение2> <текст>] [#elif <конст_выражение3> <текст>] …..

[#else <текст>] #endif Вместо директив #ifdef и #ifndef можно использовать более старые формы: #if defined(<идентификатор>) #if !defined(<идентификатор>) defined(<идентификатор>) – может использоваться в качестве ограниченного константного выражения, например, после #elif Директивы условной компиляции могут использоваться для отладочных печатей, для защиты заголовочных файлов от повторного включения, а также для повышения переносимости программ.

10.6.

Директива нумерации строк #line <константа> [“имя_файла”] Директива сообщает компилятору об изменении имени файла и порядка нумерации строк (следующая строка имеет номер константа+1).

Влияет на диагностические сообщения компилятора.

10.7.

Директива обработки ошибок Формат: #error <текст> Происходит печать текста, как правило, используется совместно с директивами условной компиляции.

Препроцессор прерывает компиляцию и выдает сообщение.

10.8.

Директивы # и ## Для повышения читабельности программ может использоваться пустая директива, состоящая из строки с символом #.

Кроме того, символ # может помещаться перед аргументом в строке текста макроопределения и указывает на необходимость его преобразования с символьную строку (помещается в “ “).

Директива ## используется в строке замещения в макроопределениях для склейки лексем.

10.9.

Заранее определенные препроцессорные идентификаторы __TIME__ __DATE__ __FILE__ __LINE__ _WIN32 _M_IX86 // Определяет используемый процессор __cplusplus _DLL UNICODE и др.

10.10.

Указания компилятору #pragma <последовательность_символов> Определяет зависящие от реализации указания компилятору (прагмы).

Компилятор Visual C++ поддерживает следующие прагмы: alloc text, comment, optimize, auto_inline, component, inline_depth, pack, bss seg, data_seg, function, intrinsic, setlocale, code_seg, hdrstop, message, const seg, once, warning, inline recursion, check_stack, include_alias Например,директива #pragma warning(disable: 4305) предписывает компилятору не выдавать предупреждения при несовпадении типов данных #pragma inline
English     Русский Rules