Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ответы на программирование.doc
Скачиваний:
29
Добавлен:
17.04.2019
Размер:
393.22 Кб
Скачать

2.16. Директивы препроцессора и указания компилятору языка с

Директивы препроцессора. Указания компилятору.

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

Именованные константы. Макроопределения

Идентификаторы, представляющие собой последовательность действий, заданной операторами и выражениями, называют макроопределениями. Обращение к макроопределениям называют макровызовом.

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

#define идентификатор_константы замещающий текст

После появления этой строки в файле все встретившиеся далее в тексте программы имена, совпавшие с элементом директивы: дентификатор_константы, будут автоматически заменены на указанный в директиве замещающий_текст прежде, чем начнется компиляция программы. Символические константы дают возможность программисту присвоить константе имя и использовать его далее в программе. Если возникнет необходимость изменить значение константы во всей программе, для этого достаточно будет внести только одно изменение в директиву препроцессора #define и перекомпилировать программу; значение константы будет изменено по всей программе автоматически. (#define Pi 3.14)

Операция # преобразует подставляемую лексему в строку символов, взятую в кавычки

Операция ## выполняет конкатенацию (сцепление, склеивание) двух лексем. Рассмотрим следующее макроопределение:

#define TOKENCONCAT(х, у) х ## у

Когда в программе встречается макрос TOKENCONCAT, его аргументы склеиваются и полученное выражение используется для замещения идентификатора макроса. Например, TOKENCONCAT (О, К) будет замещаться в тексте программы на ОК. Операция ## должна иметь два операнда.

Директива #undef

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

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

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

Условная компиляция: директивы #if, #endif, #ifdef, #ifndef, #else, #elif

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

Условная директива препроцессора #if во многом похожа на оператор if. Ее синтаксис имеет вид: #if условие фрагмент кода #endif

В этой записи условие является целочисленным выражением. Если это выражение возвращает не нуль (истинно), то фрагмент кода, заключенный между директивой #if и директивой #endif, компилируется. Если же выражение возвращает нуль (ложно), то этот фрагмент игнорируется и препроцессором, и компилятором. В условиях, помимо обычных выражений, можно использовать конструкцию: defined. Идентификатор defined возвращает 1, если указанный идентификатор ранее был определен директивой #define, и возвращает 0 в противном случае. Конструкция #if defined может быть заменена эквивалентной ей директивой #ifdef, а конструкция #if !defined — директивой #ifndef.

Можно использовать более сложные конструкции условных директив препроцессора при помощи директив #elif (эквивалент else if в обычной структуре if) и #else (эквивалент else в структуре if). Например, в коде

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

Директива препроцессора #error имеет следующий синтаксис: #error лексемы

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

Указания компилятору

Помимо директив препроцессора на ход компиляции оказывают влияние указания компилятору. К ним могут быть отнесены выражения, влияющие на размер стековой памяти. На эту константу влияет STK_LEN. Также размер стека может быть определен с помощью соответствующего ключа командной строки. Псевдопеременные

Каждая такая переменная начинается и заканчивается двойными символами подчеркивания и записывается заглавными буквами.

__LINE__содержит номер текущей строки

__FILE__имя компилируемого исходного файла

__DATE__дата начала компиляции

__TIME__время начала компиляции