Макроподстановки

Оператор defined

При условной обработке текста для упрощения записи сложного условия выбора можно использовать унарный препроцессорный оператор

defined операнд

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

#ifdef Y

#ifndef N

_текст

#endif

#endif

Используя defined получим

#if defined Y &&!defined N

_текст

#endif

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

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

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

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

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

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

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

# define REAL long double

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

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

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

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

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

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

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

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

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

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

#define max(x,y) (x<y?y:x)

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

max(a,b) заменяется выражением:(a<b?b:a).


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: