Макропідстановки засобами препроцесора

Макрос, за визначенням, є засіб заміни однієї послідовності символів іншої. Для виконання замін повинні бути задані відповідні макроозначення. Просте макроозначення ми вже ввели, розглядаючи директиву

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

Така директива зручна, проте вона має істотний недолік - рядок заміщення фіксований. Великими можливостями володіє наступне макроозначення з параметрами

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

Тут ім'я - ім'я макросу (ідентифікатор), список_параметров -список розділених комами ідентифікаторів. Між ім'ям макросу і списком параметрів не повинно бути пропусків.

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

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

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

max(X,Y) замінюється виразом

(X < Y ? Y : X)

а використання

max(Z,4) приведе до формування виразу

(Z < 4 ? 4 : Z)

У першому випадку при дійсному значенні х < у повертається значення Y, інакше - значення х. У другому прикладі z порівнюється з константою 4 і вибирається більше із значень.

Не менш часто використовується визначення

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

З його допомогою в програму можна вставляти вираз для визначення абсолютних значень змінних. Конструкція

ABS(E - Z)

замінюється виразом

(E - Z < 0 ? -(E - Z) : E-Z )

в результаті обчислення якого визначається абсолютне значення виразу Е - z.

Порівнюючи макроси з функціями, найчастіше відзначають, що на відміну від функції, визначення якої завжди присутнє в одному екземплярі, коди, що формуються макросом, вставляються в програму стільки разів, скільки разів використовується макрос. В цьому відношенні макроси подібні вбудовуваним (Online) функціям, але на відміну від вбудовуваних функцій підстановка для макросу виконується завжди. Звернемо увагу на ще одну відмінність: функція визначена для даних того типа, який вказаний в специфікації її параметрів і повертає значення тільки одного конкретного типа. Макрос придатний для обробки параметрів будь-якого типа, допустимих у виразах, що формуються при обробці рядка заміщення. Тип набуваючого значення залежить тільки від типів параметрів і від самих виразів. Таким чином, макрос може замінювати декілька функцій. Наприклад, приведені макроси max () і abs() вірно працюють для параметрів з цілими або плаваючими типами, а результат залежить тільки від типів параметрів. Механізм перевантаження і шаблони функцій дозволяють вирішувати ті ж задачі, що і макроси. Саме тому на відміну від мови С в програмах на С++ макрозасоби використовуються рідше.