В препроцессор в C ++ это инструмент, который обрабатывает код перед его компиляцией компилятором. Он выполняет множество задач, таких как включение заголовочных файлов, условная компиляция, подстановка текста, удаление комментариев и т.д. Препроцессор также позволяет разработчикам выбирать, какие части кода следует включать или исключать.
Все директивы препроцессора начинаются с новой строки и символа #, а заканчиваются переходом на следующую строку (а не точкой с запятой, как инструкции).
Директивы препроцессора в C ++
В C++ директивы препроцессора — это специальные команды, которые используются для управления препроцессором. Они начинаются с символа ‘#’ и указывают препроцессору на необходимость изменения исходного кода перед компиляцией. В C++ существуют различные директивы препроцессора для выполнения разных операций.
В приведенной ниже таблице перечислены часто используемые директивы препроцессора:
Директива | Описание |
---|---|
#include | Связывает заголовочный файл с исходным кодом. |
#define | Создает символическую или макроконстанту. |
#undef | Удаляет макрос, который уже был определен. |
#if / #elif / #else / #endif | Компиляция, которая является условной и основана на некотором выражении. |
#ifdef / #ifndef | Компиляция, зависящая от наличия или отсутствия макроса. |
#error | Останавливает процесс компиляции и выдает уведомление об ошибке. |
#warning | Во время компиляции отображается предупреждение. |
#pragma | Предоставьте компилятору конкретные инструкции |
#include
Директива препроцессора #include используется для включения содержимого одного файла в текущий. Используйте директиву #include. Header files часто включаются с помощью этой директивы.
Синтаксис
1 2 |
#include <file_name> #include "file_name" |
Первый синтаксис включает файлы из системного каталога, а второй — файлы из каталога, в котором в данный момент находится исходный файл.
Пример
1 2 3 4 5 6 7 8 |
// Including the standard I/O stream header file #include <iostream> using namespace std; int main() { cout << "GeeksforGeeks"; return 0; } |
1 |
GeeksforGeeks |
#define
Директива препроцессора #define используется для определения макросов. Имена макросов являются символическими и могут использоваться для представления константных значений или коротких фрагментов кода. Использование препроцессора #define делает наш код более читаемым и удобным для сопровождения, поскольку мы можем заменить числа и фрагменты кода осмысленными именами.
Синтаксис
1 |
#define macro_name value |
Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> using namespace std; // Defining macros #define PI 3.14159 #define findSquare(x) (x * x) int main() { double radius = 5.0; // Macro name PI and findSquare will be substituted // by preprocessor double area = PI * findSquare(radius); cout << area; return 0; } |
1 |
78.5397 |
#undef
Директива препроцессора #undef используется для отмены ранее определённого макроса (определённого с помощью #define). В основном она используется в тех случаях, когда мы хотим переопределить существующий макрос или удалить связанное с ним определение макроса из кода.
Синтаксис
1 |
<span class="cp">#undef macro_name</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include <iostream> using namespace std; // Defining a macro #define MAX_VALUE 100 int main() { cout << MAX_VALUE << endl; // using undef to change MAX_VALUE #undef MAX_VALUE #define MAX_VALUE 200 cout << MAX_VALUE; return 0; } |
1 2 |
100 200 |
#if, #elif, #else и #endif (условные директивы)
Директивы #if, #elif, #else, #endif, и #error являются условными директивами препроцессора, которые используются для условной компиляции. Они используются для включения или исключения кода на основе заданных условий.
Синтаксис
1 2 3 4 5 6 7 |
#if constant_expr // Code to be executed if constant_expression is true #elif another_constant_expr // Code to be excuted if another_constant_expression is true #else // Code to be excuted if none of the above conditions are true #endif |
Пример
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> using namespace std; #define PI 3.14159 int main() { // Conditional compilation #if defined(PI) cout << "PI is defined"; #elif defined(SQUARE) cout << "PI is not defined"; #else #error "Neither PI nor SQUARE is defined" #endif return 0; } |
output
1 |
PI is defined |
Объяснение: этот код использует директивы препроцессора для проверки того, определены ли определённые макросы (PI и SQUARE). Поскольку PI определён, программа выводит «PI определён», затем проверяет, определён ли SQUARE, который не определён, поэтому ничего не выводит.
#ifdef и #ifndef
Директивы препроцессора #ifdef и #ifndef используются для условной компиляции. #ifndef проверяет, что макрос не определён, #ifdef проверяет, что макрос определён.
Синтаксис
1 2 3 4 5 |
#ifdef macro_name // Code to be executed if macro_name is defined #ifndef macro_name // Code to be executed if macro_name is not defined #endif |
#ifdef и #ifndef часто используются с директивой #endif для включения или исключения фрагментов кода в зависимости от того, определён ли определённый макрос.
Пример
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#include <iostream> using namespace std; // Definign two macros #define DEBUG #define PI 3.14 int main() { // Check if DEBUG is defined #ifdef DEBUG cout << "Debug mode is ON" << endl; #else cout << "Debug mode is OFF" << endl; #endif // Check if PI is defined #ifndef PI cout << "PI is not defined" << endl; #else cout << "PI is defined" << endl; #endif return 0; } |
output
1 2 |
Debug mode is ON PI is defined |
#error
Директива #error — это директива препроцессора, которая используется для вывода пользовательского сообщения об ошибке компиляции. Если какое-либо условие не выполняется или какое-либо конкретное требование не удовлетворено, мы можем остановить процесс компиляции с помощью #error.
Синтаксис
1 |
#error error_message |
Здесь, error_message это пользовательское сообщение об ошибке, которое вы хотите напечатать, когда #error .
Пример
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include <iostream> using namespace std; // not defining PI here // #define PI 3.14159 int main() { #if defined(PI) cout << "PI is defined" << endl; #else #error "Neither PI nor SQUARE is defined" #endif return 0; } |
output
1 |
#error "Neither PI nor SQUARE is defined" |
#warning
Директива препроцессора #warning используется для создания предупреждающего сообщения во время компиляции. Мы можем писать собственные предупреждающие сообщения, которые обычно используются в информационных или отладочных целях. Компилятор выводит предупреждающее сообщение в консоль, чтобы сообщить о любом необходимом условии или решениях, принятых на этапе предварительной обработки.
Синтаксис
1 |
#warning message |
Здесь сообщение — это любое пользовательское сообщение, которое вы хотите распечатать в виде оповещения.
Пример
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <iostream> using namespace std; // not defining it to trigger the warning //#define PI 3.14 #ifndef PI #warning "PI is not defined!" #endif int main() { cout << "Hey! geek"; return 0; } |
output
1 2 3 4 |
main.cpp:8:2: warning: #warning "PI is not defined!" [-Wcpp] 8 | #warning "PI is not defined!" | ^~~~~~~ Hey! geek |
Примечание: предупреждающее сообщение выводится при компиляции кода на выходе компилятора или в консоли. Оно зависит от компилятора. Следовательно, способ отображения предупреждения зависит от используемого вами компилятора.
#pragma
Директива #pragma — это инструкции для компилятора. Специальные инструкции для компилятора предоставляются с помощью директивы #pragma. Она может использоваться для изменения параметров компилятора, отключения предупреждений и т. д. Поддерживаемые прагмы могут различаться в зависимости от компилятора.
Синтаксис
- #pragma once: используется для включения защиты заголовочных файлов.
- #pragma message: используется для вывода пользовательских сообщений во время компиляции.
- #pragma warning: используется для управления поведением предупреждений (например, для включения или отключения предупреждений).
- #pragma optimize: используется для управления настройками оптимизации (управления уровнем оптимизации).
- #pragma comment: используется для включения дополнительной информации в объектный файл (или указания параметров компоновщика).
Пример
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> using namespace std; #pragma once // Defining PI to trigger a pragma message during // compilation #define PI 3.14 // to set aggressive optimization level #pragma optimize("O3") int main() { #ifdef PI #pragma message("YES! PI is defined.") #endif cout << "In main function!\n"; return 0; } |
output
1 2 3 |
./Solution.cpp: In function 'int main()': ./Solution.cpp:15:38: note: #pragma message: YES! PI is defined. #pragma message("YES! PI is defined.") |