Препроцессор и его директивы

Препроцессор – это процессор, манипулирующий исходным текстом Си программы на первой стадии ее компиляции.

Управление работой препроцессора производится посредством директив препроцессора. Обработанный препроцессором исходный текст поступает компилятору и он уже не содержит директив препроцессора. Директивы препроцессора отмечаются специальным маркером – знаком номера (#). Между знаком номера и первой буквой директивы могут находиться пробелы.

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

Директива # define

Эта директива имеет два формата:

  1. #define идентификатор текст_подстановки
  2. #define идентификатор(список параметров) текст_подстановки

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

Текст подстановки может быть опущен. В этом случае удаляются все вхождения идентификатора из текста исходной программы.

Пример:

#define PI 3.1415926

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

Пример:

#define MIN(x,y) ((x)<y?(x):(y)) /* минимум из x и y */

Замечание:

· параметры макроопределения заключают в круглые скобки;

· макроопределение не заканчивается точкой с запятой.

Пример:

#define КУБ(x) (x*x*x)

КУБ(a+3) /* (a+3*a+3*a+3), а должно быть (a+3)*(a+3)*(a+3) */

Директива # include

Эта директива имеет формат:

  1. #include<спецификатор маршрута>
  2. #include “спецификатор маршрута”

Спецификатор маршрута – это имя файла с предшествующей спецификацией каталога.

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

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

Директивы условной компиляции

Это директивы #if, #elif, #else, #endif

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

#if константное выражение_1

[текст]

[#elif константное выражение_2

текст]

[#elif константное выражение_3

текст]

[#else

текст]

#endif

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

Директива #else, если она есть, должна быть последней директивой перед директивой #endif.

Препроцессор выбирает одно из вхождений текста, на основе вычисления константного выражения. Выбирается то, где будет найдено выражение со значением истина (не ноль). Если все выражения ложны или отсутствует директива #elif, то текст берется после директивы #else. Если эта директива отсутствует, то никакой текст не выбирается.

Константное выражение – это выражение из различных констант, исключая константы типа enum (перечисление).


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: