Макросы с параметрами

Формат директивы #define, определяющей макрос с параметрами:

#define идентификатор_макроса(аргументы) замещающий_текст

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

идентификатор_макроса(аргументы)

Макрос, определяемый директивой препроцессора #define, это символическое имя некоторых операций. Как и в случае символических констант, идентификатор макроса заменяется на замещающий текст до начала компиляции программы. Но сначала в замещающий текст подставляются значения параметров, а затем уже этот расширенный макрос подставляется в текст вместо идентификатора макроса и списка его параметров. Например, следующий макрос с одним параметром определяет площадь круга, принимая в качестве параметра радиус:

#define CIRC(x) (3.14159*(x)*(x))

Везде в тексте файла, где появится идентификатор CIRC(A), значение аргумента А будет использовано для замены х в замещающем тексте, далее полученный расширенный макрос будет использован для замещения. Если полученное результирующее выражение состоит из констант, его значение будет вычислено во время компиляции.

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

#define Ell(x,y) (3.14159*(x)*(y))

Вызов этого макроса может иметь вид S=Ell(R1,R2). С точки зрения получаемых результатов макросы эквивалентны функциям. То есть можно записать:

double Ell(double x,y){ return 3.14159*x*y;}

Таким образом, возникает вопрос, что выгоднее использовать: макросы или функции. Вызов функции сопряжён с накладными расходами и затягивает выполнение программы. С другой стороны, макрос расширяется во всех местах текста, где используется его вызов. Если таких мест в программе много, то это увеличивает размер текста и, соответственно, размер выполняемого модуля. Таким образом, функции позволяют сокращать объём выполняемого файла, а макросы – сокращать время выполнения. Недостатком макроса является отсутствие встроенного контроля согласования типов аргументов и формальных параметров. Отсутствие соответствующих предупреждений компилятора может приводить к ошибкам программы. Однако наибольший недостаток макросов – возможность появления побочных эффектов, если в качестве аргумента макроса передаётся некоторое выражение:

S=CIRC(a++)-> S=(3.14159*(a++)*(a++)) //a увеличено не на 1, а на 2S=CIRC(++a)-> S=(3.14159*(++a)*(++a)) //площадь определена неверно S =(3.14159*(a+1)*(a+2))

Директива #undef

Определения символических констант и макросов могут быть аннулированы при помощи директивы препроцессора #undef, имеющей вид:

#undef идентификатор

Директива отменяет определение символической константы или макроса с указанным идентификатором. Таким образом, область действия символической константы или макроса начинается с места их определения и заканчивается явным их аннулированием директивой #undef или концом файла. После аннулирования соответствующий идентификатор может быть снова использован в директиве #define. Не является ошибкой использование директивы #undef для идентификатора, который не был определён директивой #define.


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



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