Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЯП - ПОИТ (Бахтизин) часть 1 редакт.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
1.76 Mб
Скачать

11. Директивы препроцессора

11.1. Основные понятия

Препроцессор (макропроцессор) – это программный модуль, обрабатывающий исходный текст программы до того, как он пройдёт через компилятор. Языка программирования Си предполагает, что любой транслятор с этого языка содержит препроцессор.

Препроцессорная обработка (макрообработка) — это преобразование текста путем замены препроцессорных переменных их значениями и выполнения препроцессорных операторов (директив препроцессора).

Директива препроцессора – это любая строка, начинающаяся с символа # (до символа # в строке могут содержаться только пробелы). Синтаксис этих строк не связан с остальным языком: они могут появляться в любом месте и их влияние распространяется (независимо от области действия) до конца исходного программного файла.

Макрообработка состоит в последовательном просмотре (сканировании) исходного текста и выделении в нем лексем (макроопределении). Если выделенная лексема является препроцессорной переменной, она заменяется на свое значение – это называется макрорасширением. Если встречается препроцессорная директива, то она выполняется. Лексемы, не являющиеся препроцессорными переменными или директивами, переносятся в выходной текст без изменения. Результатом такой обработки является текст, не содержащий препроцессорных директив и препроцессорных переменных. После макрообработки должен быть получен синтаксически правильный текст на Си.

Препроцессор позволяет выполнить следующие действия:

  1. включить в компилируемый файл другие файлы;

  2. определить символические константы и макросы;

  3. задать режим условной компиляции программного кода и условного выполнения директив препроцессора;

  4. задавать номера строк;

  5. выводить сообщения об ошибках;

  6. использовать дополнительные команды при помощи директивы #pragma. Количество и функции команд зависят от установленного пакета Си.

Фактически препроцессор расширяет возможности языка Си, реализуя такие функции, которые в других языках входят в состав самого языка.

Директивы препроцессора можно условно разделить на следующие группы:

  1. Включение файлов (#include);

  2. Определения символических констант и макросов (#define, #undef);

  3. Условная компиляция (#if, #endif, #ifdef, #ifndef, #else, #elif);

  4. Прочие директивы (#error, #line, #pragma);

  5. Операции препроцессора # и ##.

11.2. Директива #include

Директива #include применяется для включения копии указанного в директиве файла в том месте, где находится эта директива.

Существует 3 формы директивы #include:

  1. #include <имя_файла>

  2. #include "имя_файла"

  3. #include идентификатор_макроса

Последняя форма предполагает, что макрос, идентификатор которого используется в этой форме директивы, предварительно определен и использует одну из первых двух форм директивы #include.

Различие между первыми двумя формами директивы заключается в методе поиска препроцессором включаемого файла. Если имя файла заключено в угловые скобки (< >), как это делается для включения заголовочных файлов стандартной библиотеки, то последовательность поиска препроцессором заданного файла в каталогах определяется заданными каталогами включения (include directories. В Borland C++ 3.1 установить данную директорию можно через меню: Options->Directories).

Если же имя файла заключено в кавычки, препроцессор ищет файл в директории, указанной (для Borland C++ 3.1) через меню: File->Change dir. Если же указан полный путь к файлу, то поиск производится по указанному адресу.

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

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

Рассмотрим примеры директив.

Следующая директива включает файл stdio.h, который ищется в стандартном каталоге включаемых файлов:

#include <stdio.h>

Следующая директива включает пользовательскую библиотеку MyBibl.h, расположенную в каталоге, указанном через меню File->Change dir:

#include "MyBibl.h"

Следующие директивы включают файл C:\Test\my.h, который ищется в каталоге C:\Test:

#define myincl "C:\Test\my.h"

#include myincl

Замечание: Включения с помощью #include могут быть вложенными.