Связь и интернет Архив Программирование
   
Сделать стартовойСделать закладку            
   ПОИСК  
   
Главная / C / C++ / Введение в язык C++ / Функции и Файлы /
8  Perl
8  PHP
8  JavaScript
8  HTML
8  DHTML
8  XML
8  CSS
8  C / C++
8  Pascal и Delphi
8  Турбо Ассемблер
8  MySQL
8  CASE-технологии
8  Алгоритмы
8  Python
8  Обратная связь
8  Гостевая книга
Новости о мире


Макросы - Программирование от RIN.RU
Макросы

Макросы в C они очень важны, но в C++ применяются гораздо меньше. Первое правило относительно них такое: не используйте их, если вы не обязаны это делать. Как было замечено, почти каждый макрос проявляет свой изъян или в языке, или в программе. Если вы хотите использовать макросы, прочитайте, пожалуйста, вначале очень внимательно руководство по вашей реализации C препроцессора.


Простой макрос определяется так:


#define name rest of line


Когда name встречается как лексема, оно заменяется на rest of line.


Например:


named = name


после расширения даст:


named = rest of line


Можно также определить макрос с параметрами.


Например:


#define mac(a,b) argument1: a argument2: b


При использовании mac должно даваться две строки параметра. После расширения mac() они заменяют a и b.


Например:


expanded = mac(foo bar, yuk yuk)


после расширения даст


expanded = argument1: foo bar argument2: yuk yuk


Макросы обрабатывают строки и о синтаксисе C++ знают очень мало, а о типах C++ или областях видимости - ничего. Компилятор видит только расширенную форму макроса, поэтому ошибка в макросе диагностируется когда макрос расширен, а не когда он определен. В результате этого возникают непонятные сообщения об ошибках.


Вот такими макросы могут быть вполне:


#define Case break;case
#define nl <<"\n"
#define forever for(;;)
#define MIN(a,b) (((a)<(b))?(a):(b))


Вот совершенно ненужные макросы:


#define PI 3.141593
#define BEGIN {
#define END }


А вот примеры опасных макросов:


#define SQUARE(a) a*a
#define INCR_xx (xx)++
#define DISP = 4


Чтобы увидеть, чем они опасны, попробуйте провести расширения в следующем примере:


int xx = 0; // глобальный счетчик




void f() {
int xx = 0; // локальная переменная
xx = SQUARE(xx+2); // xx = xx+2*xx+2
INCR_xx; // увеличивает локальный xx
if (a-DISP==b) { // a-= 4==b
// ...
}
}


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


Обратите внимание на различие результатов расширения этих двух макросов:


#define m1(a) something(a) // глубокомысленный комментарий
#define m2(a) something(a) /* глубокомысленный комментарий */


например,


int a = m1(1)+2;
int b = m2(1)+2;


pасширяется в


int a = something(1) // глубокомысленный комментарий+2;
int b = something(1) /* глубокомысленный комментарий */+2;


С помощью макросов вы можете разработать свой собственный язык. Скорее всего, для всех остальных он будет непостижим. Кроме того, C препроцессор - очень простой макропроцессор. Когда вы попытаетесь сделать что-либо нетривиальное, вы, вероятно, обнаружите, что сделать это либо невозможно, либо чрезвычайно трудно (но см. этот раздел).



 8  Комментарии к статье  8  Обсудить в форуме  8  Обсудить в чате

8  В тему

Введение

Компоновка

Заголовочные Файлы

Файлы как Модули

Как Создать Библиотеку

Функции

 
  
  
    Copyright ©  RIN 2003 - 2004      * Обратная связь