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

10. Отличия макросов от функций

Сравнивая макросы с функциями, заметим, что в отличие от функции, определение которой всегда присутствует в одном экземпляре, тексты, формируемые макросом, вставляются в программу столько раз, сколько раз используется макрос. Обратим внимание на еще одно отличие: функция определена для данных того типа, который указан в спецификации ее параметров и возвращает значение только одного конкретного типа. Макрос пригоден для обработки параметров любого типа, допустимых в выражениях, формируемых при обработке строки замещения. Тип получаемого значения зависит только от типов параметров и от самих выражений. Таким образом, макрос может заменять несколько функций. Например, приведенные выше макросы mах() и ABS() верно работают для параметров любых целых и вещественных типов, а результат зависит только от типов параметров.

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

11. Препроцессорные операции в строке замещения

В последовательности лексем, образующей строку замещения, предусматривается использование двух операций – ‘#’ и ‘##’, первая из которых помещается перед параметром, а вторая – между любыми двумя лексемами. Операция ‘#’ требует, чтобы текст, замещающий данный параметр в формируемой строке, заключался в двойные кавычки.

В качестве полезного примера с операцией ‘#’ рассмотрим следующее макроопределение:

#define print (A) printf (#A”=%f”, А)

К макросу print (А) можно обращаться, подставляя вместо параметра А произвольные выражения, формирующие результаты вещественного типа.

Пример 10.18

print (sin (a/2)); – обращение к макросу;

printf (“sin (a/2)””=%f”, sin (a/2)); – макрорасширение.

Фрагмент программы:

double а=3.14159;

print (sin (a/2));

Результат выполнения (на экране дисплея):

sin (a/2)=1.0

Операция ‘##’, допускаемая только между лексемами строки замещения, позволяет выполнять конкатенацию лексем, включаемых в строку замещения.

Чтобы пояснить роль и место операции ‘##’, рассмотрим, как будут выполняться макроподстановки в следующих трех макроопределениях с одинаковым списком параметров и одинаковыми аргументами.

Пример 10.19

#define zero (a, b, с, d) a (bcd)

#define one (a, b, c, d) a (b с d)

#define two (a, b, c, d) a (b##c##d)

Макровызов: Результат макроподстановки:

zero(sin, x, +, у) sin(bcd)

one (sin, x, +, у) sin(x + у)

two(sin, x, +, y) sin(x+y)

В случае zero() последовательность “bcd” воспринимается как отдельный идентификатор. Замена параметров b, с, d не выполнена. В строке замещения макроса оnе() аргументы отделены пробелами, которые сохраняются в результате. В строке замещения для макроса two() использована операция ‘##’, что позволило выполнить конкатенацию аргументов без пробелов между ними.

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