русс | укр

Мови програмуванняВідео уроки php mysqlПаскальСіАсемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование


Linux Unix Алгоритмічні мови Архітектура мікроконтролерів Введення в розробку розподілених інформаційних систем Дискретна математика Інформаційне обслуговування користувачів Інформація та моделювання в управлінні виробництвом Комп'ютерна графіка Лекції


Директиви макропідстановок #define i #undef


Дата додавання: 2014-04-22; переглядів: 2299.


Директива #define виконує задані заміни (макропідстановки, макрозаміщення, макрозаміни) в тексті програми. Основним призначенням директиви #define є створення іменованих констант (макроконстант) і функціональних макровизначень (макросів) з параметрами.

Для виконання заданих макрозамін у тексті програми використовують директиву #define, що має таку форму:

 

#define ім’я_макросу текст_заміни

 

Ім’я макросу записується за правилами запису ідентифікаторів і задає лексему програми, яка має бути замінена вказаним далі текстом заміни. Між іменем макросу та текстом макропідстановки може стояти довільна кількість символів пробілу. Кінець тексту заміни задає символ кінця рядка. Імена макросів часто задають заголовними літерами.

Директиву #define можна використовувати для створення іменованих констант таким чином:

 

#define ARRAY_SIZE 20

int a[ ARRAY_SIZE ];

 

Після пре процесорного опрацювання всі рядки символів ARRAY_SIZE, які будуть знайдені в програмі, будуть замінені на текст заміни, тобто на число 20. Такий спосіб створення констант здебільшого використовується в програмах на мові С, в С++ бажано використовувати константи.

В текстах макропідстановок можна використовувати імена макросів, визначених раніше. Наприклад:

 

#define MIN 10

#define MAX MIN*20

#define RANGE (MAX-MIN)

 

Макроси з параметрами, які також називають функціональними макровизначеннями або просто макросами, дають змогу здійснювати макропідстановки, подібні до викликів функцій. Формальні параметри, вказані в списку #define, під час препроцесування замінюються фактичними виразами, заданими в звертанні до макросу. Синтаксис макросу з параметрами такий:

 

#define ім’я_макросу(список_параметрів) вираз_для_заміни

 

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

Наведемо приклад макросу, що виконує піднесення до куба заданого аргументу:

 

#include <iostream>

using namespace std;

#define CUBE(x) ((x)*(x)*(x))

int main() {

cout << CUBE(3) << endl;

}

 

У виразі підстановки макросу кожен з параметрів і весь вираз слід брати в дужки, щоб уникнути можливих помилок у випадках, коли аргументи виклику є виразами, або коли сам макрос є елементом іншого виразу. Наприклад, якби вираз підстановки CUBE(x) був записаний як (x*x*x), то звертання CUBE(а+1) було б замінене помилковим виразом (а+1*а+1*а+1). Якщо опустити зовнішні дужки, то помилковим буде значення виразу 1.0/CUBE(а), оскільки результат підстановки буде мати вигляд 1.0/(а)*(а)*(а).

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

Операції # i ## розширюють можливості директиви #define. Їх можна використовувати тільки в тексті макропідстановки.

Операція # називається операцією перетворення в стрінг, вона перетворює в символьний рядок аргумент, перед яким записано знак #. Наприклад:

 

#include <iostream>

using namespace std;

#define OUT(x) cout << #x " = " << x << endl;

int main() {

int a = 123;

OUT( a ); // a = 123

OUT( a + 4 ); // a + 4 = 127

OUT( sin( 3.14 ) ); // sin( 3.14 ) = 0.00159265

}

 

#x – це символьний рядок, який буде записаний в дужках після імені макросу. За допомогою цієї операції можна легко вивести у рядки виведення імена змінних і вирази.

Операцію ## називають операцією конкатенації або склеювання. Вона призначена для об’єднання (конкатенації) двох лексем в одну нову лексему. В наступному прикладі виконується склеювання ідентифікаторів змінних:

 

#include <iostream>

using namespace std;

#define OUT(x,y) cout << x << "\t" << y << "\t" << x##y << endl;

int main() {

int a = 2, b = 3, ab = 4;

OUT( a, b ); // 2 3 4

}

 

При виконанні макросу на екран будуть виведені три числа: значення змінних a, b, ab. В процесі виконання замін у макросі відбулись склеювання лексем x##y, в результаті отримали ідентифікатор ab.

Операції # i ## можна використовувати разом:

 

#define OUT1(x,y) cout << #x#y << " = " << x##y << endl;

 

Директива #undef вказує препроцесору про відміну макровизначення, попередньо встановленого через #define. Синтаксис директиви такий:

 

#undef ім’я_макросу

 

У частині програми, записаній після #undef, вказаний макрос вважається невизначеним, жодні зміни не виконуються. Директиву #undef можна використовувати для зміни тексту заміни макросу:

 

#define MAX 100 // МАХ буде замінено на 100

#undef MAX // МАХ невизначений

#define MAX 200 // МАХ буде замінено на 200

 


<== попередня лекція | наступна лекція ==>
Директиви препроцесора. Призначення директив препроцесора | Директиви умовної компіляції


Онлайн система числення Калькулятор онлайн звичайний Науковий калькулятор онлайн