Препроцессор и макросы
Подтемы:
Что такое препроцессор?
Препроцессор в C++ — это инструмент, который выполняет предварительную обработку исходного кода перед его компиляцией. Препроцессор обрабатывает директивы, начинающиеся с символа #, такие как #include для включения файлов, #define для определения макросов, #ifdef и #ifndef для условной компиляции. Препроцессор занимается раскрытием макросов, включением кода и удалением комментариев, тем самым подготавливая код к следующим этапам компиляции.
Ссылки для изучения
Как работает препроцессор?
Препроцессор в C++ обрабатывает исходный код до его компиляции. Он выполняет следующие задачи:
-
Обработка директив: Распознает и выполняет инструкции, начинающиеся с символа
#, такие как#includeдля включения содержимого других файлов,#defineдля создания макросов, и директивы условной компиляции (#if,#ifdef,#ifndef). -
Раскрытие макросов: Заменяет макросы их значениями в коде.
-
Удаление комментариев: Удаляет комментарии из кода, чтобы они не мешали компиляции.
-
Вставка кода: Вставляет содержимое файлов, указанных в
#include, непосредственно в место включения.
Эти действия выполняются ещё до того, как компилятор начинает анализировать и трансформировать код в машинный язык.
Ссылки для изучения
Какие директивы вы знаете?
Основные директивы препроцессора:
-
#include- включает содержимое одного файла в другой в момент компиляции. -
#define- определяет макросы, которые заменяются значениями или блоками кода. -
#undef- отменяет определение макроса. -
#if,#elif,#else,#endif- используются для условной компиляции кода. -
#ifdef- проверяет, определен ли макрос перед компиляцией кода в блоке. -
#ifndef- проверяет, не определен ли макрос, и выполняет код в блоке, если это так. -
#error- выводит сообщение об ошибке и останавливает компиляцию, если встречается в коде. -
#pragma- используется для указания специфических инструкций компилятору, зависящих от платформы или компилятора.
Ссылки для изучения
Как работает директива include?
Директива #include в C++ используется для включения содержимого одного файла в другой файл во время компиляции. Она берёт все содержимое указанного файла и вставляет его в место, где стоит директива #include. Это обычно используется для включения заголовочных файлов, которые содержат объявления классов, функций, макросов и других элементов, чтобы они были доступны в нескольких файлах исходного кода.
Существует два способа использования #include:
-
С угловыми скобками (
#include <filename>): Используется для включения стандартных библиотечных файлов или файлов, которые не находятся в текущей директории исходного кода. Компилятор ищет эти файлы в стандартных системных директориях. -
С двойными кавычками (
#include "filename"): Используется для включения файлов, которые находятся в той же директории, что и файл исходного кода, или в пути поиска, указанном компилятору. Это предпочтительный способ для пользовательских заголовочных файлов.
Директива #include просто вставляет содержимое файла в точку включения, поэтому она не добавляет какого-либо дополнительного функционала, кроме объединения текста файлов во время компиляции.
Ссылки для изучения
Как работает директива define?
Директива #define в C++ используется препроцессором для определения макросов. Макросы — это фрагменты кода, которые могут быть вставлены в другие части программы. Основное применение #define — это создание констант и макросов функций.
Вот как она работает:
-
Определение константы:
#defineможет использоваться для определения символьных констант, что позволяет заменять идентификаторы на определённые значения во время компиляции. Например:#define PI 3.14159Здесь, всякий раз, когда
PIвстречается в коде, препроцессор заменяет его на3.14159. -
Макрос функции:
#defineтакже может определять макросы, которые ведут себя подобно функциям, но без накладных расходов на вызов функции. Например:#define SQUARE(x) ((x) * (x))Этот макрос берет один параметр
xи заменяет его использование на выражение(x * x).
#define просто текстовая замена, и она происходит перед
компиляцией кода. Это значит, что она не влияет на время выполнения программы и
не проводит проверок типов или вычислений до того, как код будет скомпилирован.
Ссылки для изучения
Как работают макросы?
Макросы в программировании, особенно в C и C++, работают как инструменты для текстовой замены в исходном коде перед его компиляцией. Макросы определяются с помощью директивы препроцессора #define, и вот как они работают:
-
Определение макроса: Используя
#define, вы определяете макрос, который может быть как простым текстом, так и параметризированной функцией. Например:#define PI 3.14159 #define MAX(a, b) ((a) > (b) ? (a) : (b)) -
Замена: Во время препроцессинга, каждое вхождение имени макроса в коде заменяется его определением. Препроцессор просто заменяет текст без учета контекста или типов данных.
-
Компиляция: После замены макросов исходный код компилируется. Замененный текст обрабатывается как обычный код программы.
Макросы полезны для:
-
Создания констант.
-
Реализации небольших функций без накладных расходов вызова функций.
-
Условной компиляции кода.
Макросы могут приводить к повторному вычислению аргументов. Например, MAX(a++, b) может увеличить a больше одного раза. Для вычислений предпочтительны функции и шаблоны, а для констант constexpr; они проверяют типы и соблюдают правила области видимости.
Ссылки для изучения







