То вони можуть не зрозуміти важливої деталі

За допомогою #define можна керувати регістровими змінними:

#define REG1 register

#define REG2 register

#define REG3

REG1 int i;

REG2 int j;

REG3 int k;

Тут REG3 компілятор ігнорує.

2. Макроси (макропідстановки)

#define<ідентифікатор1>(<список параметрів>)<текст>

Текст у цьому випадку може містити ідентифікатори, розташовані у списку параметрів. Наприклад:

#define ADD(x,y)((x)+(y));

#define MAX(x,y)((x)>(y))?(x):(y)

int i;

i=ADD(5,4)*3//це еквівалентно ((5)+(4))*3

i=ADD(b-3,6)*c//це еквівалентно ((b-3)+(6))*c

Визначимо функцію ADD в описаному вище фрагменті так:

#define ADD(x,y)x+y

У відповідному рядку отримаємо 5 + 4 * 3, тобто за відсутності дужок можна не досягти бажаного результату внаслідок пріоритету операцій. Отже, макропідстановки (макроси) у деякому розумінні є аналогами функцій, але між ними існує суттєва відмінність. Оскільки макроси – це звичайні текстові підстановки, то в місце їх виклику вставляється відповідний текст, тому вони працюють швидше за функції. Адже в точці виклику функції відбувається генерація виклику, засилання формальних параметрів (фактичних), повернення у точку виклику після роботи функції – усі ці дії вимагають часу. Однак використання макросів значно збільшує текст самої програми.

З використанням директиви #define можна здійснити конкатенацію текстових елементів, тобто утворити нові ідентифікатори. У директиві #define конкатенація здійснюється синтаксично з використанням ##:

#define concat(x,y)x##y

concat (x,3)=5;//еквівалентно x3=5

Наприклад:

#define AB'стандарт'

#define A'відхилення від'

#define B'стандарту'

char*s=concat(A,B);

printf("s=%s',s);

У цьому фрагменті надрукується "відхилення від стандарту". У макросах спочатку відбувається підстановка замість формальних параметрів їх фактичних значень, а потім виконується послідовність дій, описаних у макросі. Тому надрукується не 'стандарт', а "відхилення від стандарту".

Використання формального параметра, перед яким стоїть значок #<параметр>, приводить до його перетворення на текстовий рядок 'параметр'. Припустимо, що нам необхідно вивести на екран значення деякого параметра макросу у формі "параметр"=<значення>. Наведемо фрагмент програми:

#define write(x)

printf(#x'=%d\n',x)

int a=5,b=3,c=2;

write(a); /*надрукується a=5*/

write(b); /*надрукується b=3*/

write(c); /*надрукується c=2*/

Спочатку конструкція #x перетворюється на текстовий рядок #x->'x', послідовність двох текстових рядків у функції printf сприймається як один:

printf("x"=%d\n',x)

printf("x=%d\n',x)

3.6.2. Директива #undef [<ім’я>]

Директива #undef [<ім ' я>] відмінює дію макровизначення чи мак­ропідстановки, ім'я може бути відсутнім. Така директива не є помил­кою у більшості компіляторів. Не вважається помилкою також використання імені, яке раніше не було визначене. У випадку використання макросів параметри можуть бути опущені. Наприклад:

#define ADD(x,y)(x)+(y)

#define width 80

Main()

{printf ("проба\n');

int i=ADD(5,4);

printf("i=%d\n',i);

#undef ADD

{float i=ADD(3.5,4);

}}

Директива #include

Є два основні типи директиви #include:

#include "шлях"

#include <шлях>

Якщо використовуються подвійні лапки та вказується повний шлях до відповідного файла, то пошук здійснюється за цим шляхом. Якщо шлях указано не повністю, то пошук здійснюється:

a у робочому поточному каталозі, де знаходиться файл відповідної С -програми;

a у каталогах, указаних у командному рядку;

a у стандартних каталогах, що задаються командою pass операційної системи MS-DOS.

Якщо використовуються кутові дужки, то послідовність пошуку відрізняється тим, що ігнорується пошук у робочому каталозі, тобто файл шукається в каталогах, указаних у командному рядку компіляції, та в стандартних. Шлях у цій директиві також може задаватися з використанням макропідстановок:

#define myway "e:\bc\bin\bc\mylib.h'

#include myway


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



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