Инструкции

Справочный раздел

В этом разделе Вы найдетё инструкции, справочники, и всевозможные хелпы по использованию программного обеспечения.

Разделы инструкций

В сети

Пользователей: 196
Из них просматривают:
Аналоги: 114. Даташиты: 18. Инструкции: 11. Новости: 2. Остальное: 2. Профиль пользователя: 2. Теги: 1. Форум: 46.
Участников: 2
Гостей: 194

Google , Яндекс , далее...
Рекорд 2375 человек онлайн установлен 26.12.2015.

Партнёры


Партнёры

Новые объявления

В настоящее время нет объявлений.
Оглавление

#define

Директива определения макроподстановки (макроса).
Директива может иметь один из двух форматов:

 

#define <идентификатор> [значение]

 

или

 

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

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

 
Первая форма директивы получила название директивы определения символа или простого макроса, а вторая - директива определения макроса-функции (из-за внешнего сходства с определением функции).

 
Действие директивы в любом из форматов заключается в том, что препроцессор, встретив в тексте программы определенный директивой идентификатор, осуществляет подстановку вместо него соответствующего значения или тела, причем подстановка осуществляется именно путем ввода текстовых символов. Это, в частности, подразумевает, что в качестве идентификатора можно использовать даже ключевые слова языка Си!

 
Рассмотрим ряд примеров.

 
Пусть указаны следующие директивы:

 

#define D1 7

#define D2 + 5 *

#define D3 if

 
А далее в тексте программы эти символы используются так:

 

for (i = D1; i < D1 D2 3; i++)

      D3 (i == 5) break;

 
После того, как препроцессор обработает указанные строки, будет сгенерирован следующий текст программы:

 

for (i = 7; i < 7 + 5 * 3; i++)

      if (i == 5) break;

 
To есть вместо символов D1, D2 и D3 соответственно будут подставлены их значения. Смысл полученного текста лежит на совести программиста.

 
При объявлении макроса-функции перед тем, как осуществить замену символа в тексте программы, препроцессор осуществляет подстановку вместо псевдо-параметров их фактические значения, и лишь затем тело макроса подставляется в текст:

 

#define foo(x) x + 5


int k = foo(45*x);

// после обработки препроцессором заменится на

 

int k = 45*x + 5;

 

Важно понимать, что любой макрос-это именно текстовая подстановка, т.е. в отличие от настоящей функции не происходит никакой передачи параметров, вызова и т.п. - именно поэтому псевдопараметр макроса не имеет типа.

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

 

#define LINE 56 // определяем константу

#define cnt(x, y) while(x[y++] != ‘ ‘);

 

for (i = 0; i < LINE; i ++) arr[i] = i;

count = cnt(arr, i) * 12;

     

В результате обработки препроцессором будет сформирован следующий текст (комментарии из текста удаляются):

 

for (i = 0; i < 56

count = while(arr[i++] != ‘ ‘); * 12;

 
B первом операторе из-за наличия однострочного комментария в строке определения макроса будет удалена важная часть, а во втором получится сразу две ошибки: во-первых, макрос - это не функция, и в итоге оператор присваивания приобретает недопустимый вид, а во-вторых, умножение на 12 окажется отделенным точкой с запятой из тела макроса от остальной части оператора, что, естественно, так же недопустимо.


В связи с этими особенностями макросов настоятельно рекомендуется придерживаться следующих правил:
1. В определении макроса, если это необходимо, использовать только комментарии вида /*...*/
2. Заключать в круглые скобки как все тело макроса, так и входящие в него псевдопараметры
3.  Не завершать тело макроса точкой с запятой Примеры правильно определенных макросов:

#define LINE 56 /* числовую константу можно без скобок */

#define cnt(x,y) ( (x) * (y) ) /* скобки лишними не бывают! */


Если определяемый макрос не умещается на одной строке, допускается использовать символ переноса - обратная черта.

 

Допускается повторно определять один и тот же макрос в разных местах программы, это сопровождается предупреждением компилятора, но, в сущности, безопасно. Переопределенный макрос начинает действовать для строк программы, находящихся ниже его определения, а выше действует старое определение.

Комментарии принадлежат их авторам. Мы не несем ответственности за их содержание.

Разное

Интересно

Во время поиска небольших радиодеталей, упавших со стола, вероятность их обнаружения прямо пропорциональна размеру детали и обратно пропорциональна их значению для завершения работы