Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Подбельский Фомин_Программирование на языке СИ_...doc
Скачиваний:
356
Добавлен:
10.08.2019
Размер:
53.81 Mб
Скачать

Операция defined.

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

defined операнд

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

Выражение

#if defined операнд

эквивалентно выражению

#ifdef операнд

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

#if defined Y && !defined N

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

#endif

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

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

#ifdef Y

#ifndef N

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

#endif

#endif

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

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

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

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

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

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

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

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

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

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

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

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

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

Здесь имя - имя макроса (идентификатор),

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

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

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

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

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

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

заменяется выражением

а использование конструкции вида

приведет к формированию выражения

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

Не менее часто используется определение

С его помощью в программу можно вставлять выражение для

определения абсолютных значений переменных. Конструкция

заменяется выражением

в результате вычисления которого определяется абсолютное значение выражения E-Z. Обратите внимание на скобки. Без них могут появиться ошибки в результатах.

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