Статья: Макросы в C++
Название: Макросы в C++ Раздел: Рефераты по информатике, программированию Тип: статья |
Макросы в 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 препроцессор - очень простой макропроцессор. Когда вы попытаетесь сделать что-либо нетривиальное, вы, вероятно, обнаружите, что сделать это либо невозможно, либо чрезвычайно трудно. |