C++ Препроцессор
Препроцессоры — это директивы, которые указывают компилятору выполнить предварительную обработку, необходимую перед фактической компиляцией.
Все директивы препроцессора начинаются со знака решётки (#). Перед директивой препроцессора могут находиться только пробельные символы. Директивы препроцессора не являются операторами C++, поэтому они не заканчиваются точкой с запятой (;).
Мы видели, что во всех предыдущих примерах,#includeДиректива. Этот макрос используется для включения заголовочного файла в исходный файл.
C++ также поддерживает множество директив препроцессора, таких как #include, #define, #if, #else, #line и т. д. Давайте взглянем на эти важные директивы.
#define Препроцессор
Директива препроцессора #define используется для создания символьных констант. Эта символьная константа часто называетсямакрособщий вид директивы:
#define macro-name replacement-text
Когда эта строка кода появляется в файле, все последующие вхождения макроса в этом файле будут заменены на replacement-text перед компиляцией программы. Например:
Теперь давайте протестируем этот код, чтобы увидеть результат предварительной обработки. Предполагая, что файл исходного кода уже существует, далее используйте опцию -E для компиляции и перенаправьте результат в test.p. Теперь, если вы посмотрите на файл test.p, вы увидите, что он уже содержит большой объём информации, и значение внизу файла было изменено на следующее:
$ gcc -E test.cpp > test.p
...
int main ()
{
cout << "Value of PI :" << 3.14159 << endl;
return 0;
}
Параметризованный макрос
Вы можете использовать #define для определения макроса с параметрами, как показано ниже:
Когда приведенный выше код скомпилирован и выполнен, он выдает следующие результаты:
较小的值为:30
Условная компиляция
Существует несколько директив, которые можно использовать для выборочной компиляции частей исходного кода программы. Этот процесс называется условной компиляцией.
Структура условного препроцессора очень похожа на структуру выбора if. Взгляните на следующий код препроцессора:
#ifdef NULL #define NULL 0 #endif
Можно компилировать только во время отладки. Переключатель отладки можно реализовать с помощью макроса, как показано ниже:
#ifdef DEBUG cerr <<"Variable x = " << x << endl; #endif
Если символьная константа DEBUG была определена до директивы #ifdef DEBUG, то операторы в программеcerrоператоры будут скомпилированы. Вы можете использовать инструкцию #if 0, чтобы закомментировать часть программы, как показано ниже:
#if 0 不进行编译的代码 #endif
Давайте попробуем следующий пример:
Пример
Когда приведенный выше код скомпилирован и выполнен, он выдает следующие результаты:
Trace: Inside main function The minimum is 30 Trace: Coming out of main function
Операторы # и ##
Операторы препроцессора # и ## доступны как в C++, так и в ANSI/ISO C. Оператор # преобразует токен текста замены в строку, заключённую в кавычки.
Рассмотрим следующее определение макроса:
Пример
Когда приведенный выше код скомпилирован и выполнен, он выдает следующие результаты:
HELLO C++
Давайте посмотрим, как это работает. Нетрудно понять, что препроцессор C++ берёт следующую строку:
cout << MKSTR(HELLO C++) << endl;
Преобразуется в:
cout << "HELLO C++" << endl;
Оператор ## используется для конкатенации двух токенов. Вот пример:
#define CONCAT( x, y ) x ## y
Когда CONCAT появляется в программе, его аргументы конкатенируются и используются для замены макроса. Например, CONCAT(HELLO, C++) в программе будет заменено на "HELLO C++", как показано в примере ниже.
Пример
Когда приведенный выше код скомпилирован и выполнен, он выдает следующие результаты:
100
Давайте посмотрим, как это работает. Нетрудно понять, что препроцессор C++ берёт следующую строку:
cout << concat(x, y);
Преобразуется в:
cout << xy;
Предопределённые макросы в C++
C++ предоставляет некоторые предопределённые макросы, показанные в следующей таблице:
| Макрос | Описание |
|---|---|
| __LINE__ | Это будет включать текущий номер строки при компиляции программы. |
| __FILE__ | Это будет включать имя текущего файла при компиляции программы. |
| __DATE__ | Это будет включать строку в формате месяц/день/год, которая представляет дату, когда исходный файл преобразуется в объектный код. |
| __TIME__ | Он будет содержать строку в формате час:минута:секунда, которая представляет время, когда программа была скомпилирована. |
Давайте рассмотрим примеры вышеуказанных макросов:
Пример
Когда приведенный выше код скомпилирован и выполнен, он выдает следующие результаты:
Value of __LINE__ : 6 Value of __FILE__ : test.cpp Value of __DATE__ : Feb 28 2011 Value of __TIME__ : 18:52:48Другие расширения