C/C++ Директивы препроцессора

C/C++ Директивы препроцессора

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

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

Основные директивы препроцессора

#include — вставляет текст из указанного файла
#define — задаёт макроопределение (макрос) или символическую константу
#undef — отменяет предыдущее определение

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

Если файл находится в текущем каталоге проекта (или путь прописан в IDE), он указывается в кавычках “”. Для файла, находящегося в другом каталоге необходимо в кавычках указать полный путь.

 

Директива #define позволяет вводить в текст программы константы и макроопределения.

Общая форма записи: #define Идентификатор Замена

Благодаря директиве #define компилятор,вместо каждого аргумента Идентификатор в исходном файле подставляет выражение, скрытое под именем “замена”. Идентификатор не заменяется, если он находится в комментарии, в строке или как часть более длинного идентификатора.
#define PI 3.14

В зависимости от значения константы компилятор присваивает ей тот или иной тип. С помощью суффиксов можно переопределить тип константы:

U или u представляет целую константу в беззнаковой форме (unsigned);
F (или f) позволяет описать вещественную константу типа float;
L (или l) позволяет выделить целой константе 8 байт (long int);
L (или l) позволяет описать вещественную константу типа long double

#define A 280U   // unsigned int

Создание функций с помощью defines
С помощью дефайнов можно создавать простые функции (зачастую “магические/калибровочные”), синтаксис в общем виде выглядит так:

#define название(аргумент_1, …, агрумент_n) (реализация)

Важно – каждый операнд указывать в скобках, иначе при вычислении
#define Dev_p10(a) ((a)%10)

Dev_p10(19+10) получим результат 19 т.к. 19+10%10=19+0=19

Условная компиляция
#if — осуществляет условную компиляцию при истинности константного выражения
#ifdef — осуществляет условную компиляцию при определённости символической константы
#ifndef — осуществляет условную компиляцию при неопределённости символической константы
#else — ветка условной компиляции при ложности выражения
#elif — ветка условной компиляции, образуемая слиянием else и if
#endif — конец ветки условной компиляции
#line — препроцессор изменяет номер текущей строки и имя компилируемого файла
#error — выдача диагностического сообщения
#pragma — действие, зависящее от конкретной реализации компилятора.

Директивы #if или #ifdef/#ifndef вместе с директивами #elif, #else и #endif управляют компиляцией частей исходного файла.

Если указанное выражение после #if имеет ненулевое значение, в записи преобразования сохраняется группа строк, следующая сразу за директивой #if. Синтаксис условной директивы следующий:

#if/ifdef/ifndef константное выражение
группа операций

#elif константное выражение
группа операций
#else
группа операций

#endif

У каждой директивы #if… в исходном файле должна быть соответствующая закрывающая директива #endif. Между директивами #if и #endif может располагаться любое количество директив #elif, однако допускается не более одной директивы #else. Директива #else, если присутствует, должна быть последней перед директивой #endif.

Условную компиляцию удобно применять в отладочных целях – если задать #define Debug

#define Debug

// то когда будет код
#ifdef Debug
   //code
#endif
//Аналогичное с #if
#if Debug < 4
  //code
#endif

Отменить макроопределение можно с помощью директивы #undef.

Leave a Reply

Your email address will not be published. Required fields are marked *