Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Metodichka_OAiP.doc
Скачиваний:
30
Добавлен:
11.05.2015
Размер:
1.61 Mб
Скачать

7. Операция defined

При условной обработке текста (при условной компиляции с использованием директив #if, #elif) для упрощения записи сложного условия выбора можно использовать унарную препроцессорную операцию

#defined операнд

где операнд – либо идентификатор, либо заключенный в скобки идентификатор, либо обращение к макросу. Если идентификатор операнда до этого определен с помощью команды #define как препроцессорный, то выражение defined операнд принимает значение 1L, т.е. считается истинным. В противном случае его значение равно 0L.

Выражение #if defined операнд

эквивалентно выражению #ifdef операнд

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

# defined Y && !defined N

важный_текст

#endif

Обработку препроцессор ведет следующим образом. Во-первых, определяется истинность выражений defined Y и !defined N. Получаем два значения, каждое 0L или 1L. К результатам применяется операция && (конъюнкция), и при истинности ее результата важный_текст передается компилятору.

Не используя операцию defined, то же самое условие можно записать таким наглядным способом:

Пример 10.16

#ifdef Y

#ifndef N

важный_текст

#endif

#endif

Таким образом, из примера видно, что:

#if defined эквивалентно #ifdef

#if !defined эквивалентно #ifndef

Стандарт языка Си не определил defined в качестве ключевого слова. В тексте программы его можно использовать в качестве идентификатора, свободно применяемого программистом для обозначения объектов, defined имеет специфическое значение только при формировании выражений-условий, проверяемых в директивах #if и #elif. В то же время идентификатор defined запрещено использовать в директивах #define и #undef.

8. Макроподстановки средствами препроцессора

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

#define идентификатор строка_замещения

С помощью директивы #define можно вводить собственные обозначения базовых или производных типов. Например, директива

#define REAL long double

вводит название (имя) REAL для типа long double. Далее в тексте программы можно определять конкретные объекты, используя REAL в качестве обозначения их типа (long double):

REAL x, array[6];

Идентификатор в команде #define может определять, как видим, имя константы, если строка_замещения задает значение этой константы. В более общем случае идентификатор служит обозначением некоторого выражения, например:

#define RANGE ((INT_MAX) - (INT_MIN)+1)

Идентификаторы, входящие в строку замещения, в свою очередь могут быть определены как препроцессорные, и их значения будут подставлены вместо них (вместо INT_MAX и INT_MIN в нашем примере).

Допустимость выполнять с помощью #define «цепочки» подстановок расширяет возможности этой директивы, однако она имеет существенный недостаток – строка замещения фиксирована. Большие возможности предоставляет макроопределение с параметрами

#define имя(список параметров) строка_замещения

Здесь имя – имя макроса (идентификатор), список параметров – список разделенных запятыми идентификаторов. Между именем макроса и скобкой, открывающей список параметров, не должно быть пробелов.

Для обращения к макросу («для вызова макроса») используется конструкция («макровызов») вида

Имя_макроса (список_аргументов)

В списке аргументы разделены запятыми. Каждый аргумент – препроцессорная лексема.

Классический пример макроопределения

#define max(a,b) (a < b ? b : а)

позволяет формировать в программе выражение, определяющее максимальное из двух значений аргументов. При таком определении вхождение в программу макровызова max(X,Y) заменяется выражением (X<Y ? Y: X), а использование конструкции вида max(Z,4) приведет к формированию выражения (Z<4 ? 4:Z).

В первом случае при истинном значении X < Y возвращается значение Y, иначе – значение X. Во втором примере значение переменной Z сравнивается с константой 4 и выбирается большее из значений. Не менее часто используется определение

#define ABS(X) (Х<0? - (Х):Х)

С его помощью в программу можно вставлять выражение для определения абсолютных значений переменных. Конструкция ABS(E-Z) заменяется выражением (E-Z<0?-(E-Z):E-Z), в котором результат вычисления определяет абсолютное значение выражения E-Z. Обратите внимание на скобки. Без них могут появиться ошибки в результатах.

Следует отметить, что последовательные препроцессорные подстановки выполняются в строке замещения, но не действуют на параметры макроса.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]