C++ Программирование в среде С++ Builder 5

Типичное применение препроцессорных директив


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

Предотвращение включения файлов

Иногда при использовании заголовков может происходить дублирование кода из-за повторного включения некоторого файла. (Допустим, у вас имеется исходный файл myprog.c, который подключает директивой # include два заголовка headerl.h и header2.h. Если, в свою очередь, оба этих файла подключают некоторый headerO.h, то последний будет дважды включен в исходный файл myprog.c. Это ни к чему, хотя обычно и не приводит к ошибке.)

Чтобы предотвратить повторное включение кода заголовочного файла, можно организовать контроль следующим образом (как говорят, “поставить часового”):

/*

** header0.h: Заголовочный файл, который может оказаться

** многократно включенным...

*/

#ifndef _HEADERO_H

#define _HEADERO_H

/* /



** Здесь идут макросы, определения типов

** и т.д. вашего заголовочного файла...

*/

*endif

Переключение разделов кода

Директивы условной компиляции могут использоваться для простого переключения между двумя различными вариантами кода — старым и экспериментальным алгоритмом, например. Это можно сделать так:

/*

** Измените определение на 0, чтобы вернуться к старому варианту.

*/

*define NEW_VER I

#if NEW_VER /*

** Экспериментальный код.

*/

#else /*

** Старый код.

*/

*endif

Или, если не вводить дополнительный идентификатор:

/*

** Измените на 1, когда новый код будет отлажен.

*/

*if 0 /*

** Экспериментальный код.

*/

#else /*

* * Старый код.

*/

*endif

Отладочные диагностические сообщения

При отладке программ можно с большой пользой применять макросы, генерирующие операторы вывода различных сообщений с указанием файла и номера строки, например:

#define INFO(msg)

printf(#msg "\n")

#define DIAG(msg)

printf("File " _FILE_ " Line %d: " \ #msg "\n", _LINE_)

void SomeFunc(void)

{

INFO(Entering SomeFunc.);

/* Выводит информационное сообщение. */

if (someError)

DIAG(Error encountered!);

/* Выводит сообщение об ошибке. */

INFO(Exiting SomeFunc...) ;

}

Макрос assert()

В заголовочном файле assert.h определен макрос assert (), выполняющий примерно то же самое, что и показанный выше пример. Его “прототип” можно записать как

void assert(int test);

Макрос расширяется в оператор if, проверяющий условие test. Если его значение равно 0, печатается сообщение Assertion failed: с указанием имени файла и номера строки. Вот пример:

#include <assert.h>

assert(!someError) ;

Если перед включением 41айла assert.h определить символ ndebug, операторы assert () будут “закомментированы”.



Содержание раздела