// Эта программа работает корректно.
#include <iostream>
using namespace std;
#define EVEN(a) (a)%2==0 ? 1 : 0
int main()
{
if(EVEN(9+1)) cout << "четное число";
else cout << "нечетное число";
return 0;
}
Теперь сумма 9+1 вычисляется до выполнения операции деления по модулю. В общем случае лучше всегда заключать параметры макроопределения в круглые скобки, чтобы избежать непредвиденных результатов, подобных описанному выше.
Использование макроопределений вместо настоящих функций имеет одно существенное достоинство: поскольку код макроопределения расширяется в строке, и нет никаких затрат системных ресурсов на вызов функции, скорость работы вашей программы будет выше по сравнению с применением обычной функции. Но повышение скорости является платой за увеличение размера программы (из-за дублирования кода функции).
Важно! Несмотря на то что макроопределения все еще встречаются в C++-коде, макросы, действующие подобно функциям, можно заменить спецификатором inline, который справляется с той же ролью лучше и безопаснее. (Вспомните: спецификатор inline обеспечивает вместо вызова функции расширение ее тела в строке.) Кроме того, inline-функции не требуют дополнительных круглых скобок, без которых не могут обойтись макроопределения. Однако макросы, действующие подобно функциям, все еще остаются частью С++-программ, поскольку многие С/С++-программисты продолжают использовать их по привычке.
Директива #error отображает сообщение об ошибке.
Директива #error дает указание компилятору остановить компиляцию. Она используется в основном для отладки. Общий формат ее записи таков.
#error сообщение
Обратите внимание на то, что элемент сообщение не заключен в двойные кавычки. При встрече с директивой #error отображается заданное сообщение и другая информация (она зависит от конкретной реализации рабочей среды), после чего компиляция прекращается. Чтобы узнать, какую информацию отображает в этом случае компилятор, достаточно провести эксперимент.
Директива #include включает заголовок или другой исходный файл.
Директива препроцессора #include обязывает компилятор включить либо стандартный заголовок, либо другой исходный файл, имя которого указано в директиве #include. Имя стандартных заголовков заключается в угловые скобки, как показано в примерах, приведенных в этой книге. Например, эта директива
#include <vector>
Включает стандартный заголовок для векторов.
При включении другого исходного файла его имя может быть указано в двойных кавычках или угловых скобках. Например, следующие две директивы обязывают C++ прочитать и скомпилировать файл с именем sample.h:
#include <sample.h>
#include "sample.h"
Если имя файла заключено в угловые скобки, то поиск файла будет осуществляться в одном или нескольких специальных каталогах, определенных конкретной реализацией.
Если же имя файла заключено в кавычки, поиск файла выполняется, как правило, в текущем каталоге (что также определено конкретной реализацией). Во многих случаях это означает поиск текущего рабочего каталога. Если заданный файл не найден, поиск повторяется с использованием первого способа (как если бы имя файла было заключено в угловые скобки). Чтобы ознакомиться с подробностями, связанными с различной обработкой директивы #include в случае использования угловых скобок и двойных кавычек, обратитесь к руководству пользователя, прилагаемому к вашему компилятору. Инструкции #include могут быть вложенными в другие включаемые файлы.
Существуют директивы, которые позволяют избирательно компилировать части исходного кода. Этот процесс, именуемый условной компиляцией, широко используется коммерческими фирмами по разработке программного обеспечения, которые создают и поддерживают множество различных версий одной программы.