Препроцессор С++
Препроцессоры — это директивы, которые дают инструкции компилятору для предварительной обработки информации перед началом фактической компиляции.
Все директивы препроцессора начинаются с #, и перед директивой препроцессора в строке могут стоять только пробельные символы. Директивы препроцессора не являются операторами C++, поэтому они не заканчиваются точкой с запятой (;).
Вы уже видели #include директива во всех примерах. Этот макрос используется для включения файла заголовка в исходный файл.
Существует ряд директив препроцессора, поддерживаемых C ++, таких как #include, #define, #if, #else, #line и т. д. Давайте посмотрим на важные директивы —
Препроцессор #define
Директива препроцессора #define создает символические константы. Символическая константа называется макросом. и общая форма директивы —
#define macro-name replacement-text
Когда эта строка появляется в файле, все последующие вхождения макроса в этом файле будут заменены замещающим текстом перед компиляцией программы. Например —
#include <iostream> using namespace std; #define PI 3.14159 int main () { cout << "Value of PI :" << PI << endl; return 0; }
Теперь давайте выполним предварительную обработку этого кода, чтобы увидеть результат, предполагая, что у нас есть файл исходного кода. Итак, давайте скомпилируем его с опцией -E и перенаправим результат в test.p. Теперь, если вы проверите test.p, в нем будет много информации, а внизу вы найдете значение, замененное следующим образом —
$gcc -E test.cpp > test.p ... int main () { cout << "Value of PI :" << 3.14159 << endl; return 0; }
Макросы функционального типа
Вы можете использовать #define для определения макроса, который будет принимать следующие аргументы:—
Живая демонстрация#include <iostream> using namespace std; #define MIN(a,b) (((a)<(b)) ? a : b) int main () { int i, j; i = 100; j = 30; cout <<"The minimum is " << MIN(i, j) << endl; return 0; }
Если мы скомпилируем и запустим приведенный выше код, это даст следующий результат —
The minimum is 30
Условная компиляция
Есть несколько директив, которые можно использовать для компиляции отдельных частей исходного кода вашей программы. Этот процесс называется условной компиляцией.
Условная конструкция препроцессора очень похожа на структуру выбора if. Рассмотрим следующий код препроцессора —
#ifndef NULL #define NULL 0 #endif
Вы можете скомпилировать программу для целей отладки. Вы также можете включить или отключить отладку с помощью одного макроса следующим образом:
#ifdef DEBUG cerr <<"Variable x = " << x << endl; #endif
Это вызывает ошибку cerr оператор для компиляции в программе, если символическая константа DEBUG была определена до директивы #ifdef DEBUG. Вы можете использовать статус #if 0, чтобы закомментировать часть программы следующим образом —
#if 0 code prevented from compiling #endif
Давайте попробуем следующий пример —
Живая демонстрация#include <iostream> using namespace std; #define DEBUG #define MIN(a,b) (((a)<(b)) ? a : b) int main () { int i, j; i = 100; j = 30; #ifdef DEBUG cerr <<"Trace: Inside main function" << endl; #endif #if 0 /* This is commented part */ cout << MKSTR(HELLO C++) << endl; #endif cout <<"The minimum is " << MIN(i, j) << endl; #ifdef DEBUG cerr <<"Trace: Coming out of main function" << endl; #endif return 0; }
Если мы скомпилируем и запустим приведенный выше код, это даст следующий результат —
The minimum is 30 Trace: Inside main function Trace: Coming out of main function
Операторы # и ##
Операторы препроцессора # и ## доступны в C++ и ANSI/ISO C. Оператор # вызывает преобразование маркера замещающего текста в строку, заключенную в кавычки.
Рассмотрим следующее определение макроса —
Живая демонстрация#include <iostream> using namespace std; #define MKSTR( x ) #x int main () { cout << MKSTR(HELLO C++) << endl; return 0; }
Если мы скомпилируем и запустим приведенный выше код, это даст следующий результат —
HELLO C++
Давайте посмотрим, как это сработало. Несложно понять, что препроцессор C++ переворачивает линию —
cout << MKSTR(HELLO C++) << endl;
Строка выше будет преобразована в следующую строку —
cout << "HELLO C++" << endl;
Оператор ## используется для объединения двух токенов. Вот пример —
#define CONCAT( x, y ) x ## y
Когда в программе появляется CONCAT, его аргументы объединяются и используются для замены макроса. Например, CONCAT(HELLO, C++) заменяется на "HELLO C++" в программе следующим образом.
Живая демонстрация#include <iostream> using namespace std; #define concat(a, b) a ## b int main() { int xy = 100; cout << concat(x, y); return 0; }
Если мы скомпилируем и запустим приведенный выше код, это даст следующий результат —
100
Давайте посмотрим, как это сработало. Несложно понять, что препроцессор C++ преобразовывает -
cout << concat(x, y);
Строка выше будет преобразована в следующую строку —
cout << xy;
Предопределенные макросы C++
C++ предоставляет ряд предопределенных макросов, упомянутых ниже —
Старший № | Макрос и описание |
---|---|
1 | <тд>|
2 | <тд>|
3 | <тд>|
4 | <тд>
Давайте посмотрим на пример для всех вышеперечисленных макросов —
Живая демонстрация#include <iostream> using namespace std; int main () { cout << "Value of __LINE__ : " << __LINE__ << endl; cout << "Value of __FILE__ : " << __FILE__ << endl; cout << "Value of __DATE__ : " << __DATE__ << endl; cout << "Value of __TIME__ : " << __TIME__ << endl; return 0; }
Если мы скомпилируем и запустим приведенный выше код, это даст следующий результат —
Value of __LINE__ : 6 Value of __FILE__ : test.cpp Value of __DATE__ : Feb 28 2011 Value of __TIME__ : 18:52:48
Язык C