Сегодня предстоит изучить директивы препроцессора, которые встречаются в СИ-семействе (C, C#, C++). Отдельное внимание будет уделено записям типа the if else endif, а также условной компиляции. Все это крайне важно для формирования исходного программного кода. Информация пригодятся как новичкам, так и более опытным разработчикам.

Что такое препроцессор

Изучая в the C if else endif и другие директивы, сначала необходимо выяснить, что собой представляет препроцессор. В C++ он выступает в качестве части компилятора, отвечающей за управление формированием исходного кода в объектный.

The preprocessor в C++ перешел в язык из своего «предшественника» – C. Он имеет некоторый набор команд, которые называются директивами. С их помощью удается управлять корректировками в трансляциях исходного кода в объектный.

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

Синтаксис директив

Директива – это командная строка препроцессора. Она в исходном коде имеет определенный формат:

# ключевое_слово заданные_параметры.

При помощи директив можно выполнять различные операции при «сборке» проекта для компиляции. Формируются они по следующим принципам:

  • символ решетки;
  • ноль или более символов пробелов/табуляции после;
  • одно из предопределенных языком СИ ключевых слов;
  • параметры, которые зависят непосредственно от ключевого слова.

Стоит обратить внимание на то, что, если ключевое слово не указано, the directive будет игнорироваться. При написании несуществующего «зарезервированного системой слова» на экране появится сообщение об ошибке. Компиляция будет прервана. В некоторых компиляторах компиляция продолжится, но с предварительным выводом предупреждения, сигнализирующего о сбое.

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

Существуют различные виды the directive в СИ семействе. Каждая из них отвечает за определенный спектр операций. Среди основных можно выделить такие варианты как:

  • # define – с ее помощью можно задать макроопределение (макрос) или символическую константу;
  • #undef – отмена предыдущего определения;
  • Include – вставка текста из указанного файла.

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

Прочие виды

Указанные ранее элементы – это основные директивы препроцессора. Они не являются исключающими. В СИ семействе (в C++) можно встретить такие варианты как:

  • if;
  • endif;
  • error;
  • ifdef;
  • else;
  • line;
  • pragma;
  • using;
  • ifndef;
  • line;
  • NULL.

Далее каждый компонент будет рассмотрен более подробно. Особое внимание будет уделено the if else endif и другим the directives условной компиляции.

Define

The definition (или the directive #define) определяет идентификатор и последовательность символов, которые будут заменять соответствующий идентификатор в приложении. Она позволяет вводить в текст проекта константы и макроопределения.

Форма записи:

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

За счет этого компонента компилятор, вместо каждого аргумента Идентификатор в исходном файле подставляет выражение, скрытое под названием «Замена».

Error

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

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

Error_message – это сообщение об ошибке. Текст, который должен выводиться в консоль при формировании объектного кода.

Undef

Используется для того, чтобы удалить макрос, который ранее был определен через #define. После его применения имя удаляемого макроса становится неопределенным. Запись:

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

Здесь macros_name – это имя макроса, от которого необходимо избавиться.

Import

Компонент #import позволяет включать сведения из библиотеки типов (TBL – type library). В этом случае под библиотекой понимается иерархическое хранилище данных о возможностях Active-X сервера. Она сохраняется как файл с расширениями .tlb или .olb.

Синтаксическая запись #import:

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

Тут:

  1. Filename – имя файла, которое содержит библиотеку типов. В качестве соответствующего компонента могут выступать документы с расширениями .tlb, .olb, .dll или .exe. Другие форматы, распознаваемые функцией API LoadTypeLib тоже допускаются.
  2. Attributes – директивные атрибуты. Они указывают на то, что компилятор будет менять содержимое заголовка библиотеки типов.

Больше подробностей об атрибутах #import рекомендуется изучить в официальной документации C++ на сайте Microsoft. Новичкам углубляться в соответствующую сферу нет необходимости.

Using

The #using – это не the of else end if, но тоже достаточно важный компонент для компиляции. С его помощью получится импортировать метаданные в приложение, которые были скомпилированы с параметром /clr. Это значит, что использование директивы допускается только в режиме C++/CLI.  Записывается так:

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

Тут filename – это имя файла с расширением .dll, .exe, .net module или .obj. Позволяет подключать различные библиотеки и использовать именные пространства.

Pragma

Используется для задания компилятору функций выполнения. Использование команд зависит от операционной системы и устройства, который называется хостом. Характеристики функций компилятора будут определяться при установке компилятора C/C++ на компьютер.

Через #pragma можно предложить компилятору различные команды для их обработки с обеспечением полноценной совместимости с Си-семейством. Обладает соответствующий компонент разнообразными нюансами применения и несколькими реализациями. Общая синтаксическая форма представления:

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

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

Условная компиляция

Для условной компиляции используются the if else endif и другие the directives. Они помогают управлять упомянутым процессом. Каждое «выражение» имеет собственное предназначение.

If, else, endif и elif используются для того, чтобы задать части программы, которые нужно откомпилировать в зависимости от значения константного выражения.

The if проверяет, является ли препроцессорное выражение истинным или нет. Имеет следующую форму записи:

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

Здесь:

  1. Constant_expression (definitions) – это константное выражение. Оно может принимать только два варианта значений – true и false.
  2. Operator_sequence – последовательность операторов, которая выполняется при if defined (expression) = true.

А вот наглядный пример использования связки if endif:

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

При обработке соответствующего фрагмента кода в консоли появится такой результат:

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

Это первый пример работы с if the defined. Есть и другие комбинации. Они будут рассмотрены далее.

If else

Следующая комбинация, которая используется в C – if elif else. Она помогает откомпилировать одну из двух частей приложений в зависимости от значения условного выражения. Общая синтаксическая форма записи:

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

Тут:

  1. Constant_expression – выражение, которое возвращает значение логического типа. Оно может быть true или false.
  2. Operators_sequence_1 – операторы, которые выполняются при значении выражения true.
  3. Operators_sequence_2 – последовательность функций, реализующихся, если в блоке if the defined выражение будет false.

Ниже наглядный пример работы с соответствующей последовательностью. Тут, в зависимости от значения N_SOLUTION, будет формироваться тот или иной фрагмент кода. Он определит длину окружности или площадь заданного круга:

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

Выше можно увидеть не только фрагмент кода, но и результат его непосредственной обработки.

If-else-if

При изучении the ifdef else в C и других директив условной компиляции, стоит обратить внимание на цепочку if-else-if. Она называется ступенчатой (или каскадной). Директива the elif – это else-if. С ее помощью удается проверять разнообразные условия.

Синтаксическая общая форма соответствующей записи:

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

В заданном фрагменте if the define:

  • expression_1, expression_2, expression_N – некоторые выражения, которые могут быть истиной и ложью;
  • operators_sequence_1, operators_sequence_2, operators_sequence_N – операторы, которые будут компилироваться в заданном кодовом фрагменте.

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

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

Выше результат обработки the if c endif с использованием elif. 

Ifdef

The ifdef и ifndef отвечают за обеспечение еще одного вида условной компиляции. Дословно соответствующие комбинации определяются как «если определено» (if the defined) и «если не определено».

Синтаксическая форма соответствующего выражения:

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

Тут:

  • macros_name – название макроса, которое будет проведено на факт определение define;
  • operators_sequence – последовательность, заданная для реализации в коде.

Ifndef выглядит так:

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

Здесь, если имя макроса определено, заданная последовательность operator_sequence не будет выполняться.

P. S. Интересует разработка? Обратите внимание на курс «Программист C». Также в Otus доступно множество других современных курсов. Ниже – один из них:

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