Урок3. Директивы препроцессора C++

12:18 16 окт. 2015

Директивы препроцессора C++ В этой статье мы продолжим постигать искусство программирования на языке С++. На этом этапе обучения пора познакомится с такими вещами, как директивы препроцессора. Забегая наперед скажу, что в предыдущих уроках мы уже использовали директиву #include, которая служит для подключения заголовочных файлов.

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

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

Как видно перед самой компиляцией исходный текст программы обрабатывает препроцессор, давайте познакомимся с его инструкциями поближе.

Начнем с директивы #include, которая заменяется препроцессором на содержимое следующего за ней файла. Пример использования #include:

#include <header1.h>

#include «header2.h»

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

#ifndef CUCUMBLER_H

#define CUCUMBLER_H

/* содержимое файла cucumbler.h */

#endif

Директива #ifndef выполняет проверку не была ли определена константа CUCUMBLER_H ранее, и если ответ отрицательный, то выполняется определение данной константы, и прочего кода, который следует до директивы #endif. Как не сложно догадаться директива #define определяет константу CUCUMBLER_H. В данном случае подобный кусок кода помогает избежать многократного включения одного и того же кода, так как после первого включения проинициализируется константа CUCUMBLER_H и последующие проверки #ifndef CUCUMBLER_H будут возвращать FALSE.

Директива #define широко применяется и при отладке программы.

#include <iostream>

#include <string>

#include <vector>

using namespace std;

int main()

{

#ifdef IN_DEBUG

cout << "Начало функции main()\n";

#endif

string text;

vector<string> text_array;

while ( cin >> text )

{

#ifdef IN_DEBUG

cout << "Прочитан текст: " << text << "\n";

#endif

text_array.push_back(text);

}

return 0;

}

Если константа IN_DEBUG не задана, то препроцессор сгенерирует следующий исходник:

#include <iostream>

#include <string>

#include <vector>

using namespace std;

int main()

{

string text;

vector<string> text_array;

while ( cin >> text )

{

text_array.push_back(text);

}

return 0;

}

Но если определить IN_DEBUG, то текст программы кардинальным образом поменяется

#include <iostream>

#include <string>

#include <vector>

using namespace std;

int main()

{

cout << "Начало функции main()\n";

string text;

vector<string> text_array;

while ( cin >> text )

{

cout << "Прочитан текст: " << text << "\n";

text_array.push_back(text);

}

return 0;

}

Задать препроцессорную константу можно прямо из консоли. Например для компилятора g++ применяется следующий формат

$g++ -D IN_DEBUG ./main.cpp.

Теги: Уроки по C++
Категория Уроки по C++   |   0 комм.
Нет результатов.