1) Препроцессорные обозначения строк
| #line константа | Указывает компилятору, что следующая строка программы имеет номер, определяемый целой десятичной константой. |
Директива может одновременно изменять и имя файла:
#line константа “имя_файла“
После препроцессорной обработки каждая строка программы имеет вид:
Имя_файла номер_строки: текст_строки
2) Реакция на ошибки
| #error последовательность_лексем | Выдаёт диагностическое сообщение в виде последовательности лексем |
Например:
#define N 1
...
#if (N!= 10)
#error N not equal 10!
#endif
...
Сообщение об ошибке в окне Output будет выглядеть так:
имя_файла(номер_строки): fatal error C1189:
#error: N not equal 10!
В случае обнаружения ошибки препроцессорная обработка прекращается и в выходной файл препроцессора попадает только та часть текста, которая предшествовала #if.
3) Пустая директива
| # | Не вызывает никаких действий. |
4) Прагмы
| #pragma последовательность_лексем | Определяет действия, зависящие от конкретной реализации компилятора. |
Для каждого компилятора существует свой набор прагм, управляющих процессом компиляции. Если препро-цессор встречает прагму, которая ему неизвестна, он её игнорирует как пустую директиву. Например, в Microsoft Visual Studio С++
| #pragma pack(n) | влияет на упаковку смежных элементов в структурах, объединениях и объектах |
классов (n = 1,2,4); осуществляетвыравнивание элементов в памяти по границам байтов (n = 1), машинных слов (n = 2), двойных слов (n = 4) и т.д.
| #pragma once | помещается в первой строке заголовочного файла и обеспечивает защиту от его повторного включения при использовании директивы #include. |
5) Предопределенные макросы
Предопределенные макросы – заранее определённые макроимена – выдают информацию о версии программы и месте возникновения ошибки.
| __LINE__ | – | десятичная константа – номер текущей строки обрабатываемого текста (начинается с 1); |
| __FILE__ | – | строка символов – имя компилируемого файла (изменяется, когда препроцессор встречает директиву #include, и восстанавливается после включения файла); |
| __DATE__ | – | строка символов в формате “месяц число год” – дата начала обработки исходного файла; |
| __TIME__ | – | строка символов в формате “час:мин:сек” – время начала обработки исходного файла; |
| __STDC__ | – | константа, = 1, если компилятор соответствует ANSI-стандарту; в противном случае не определено; |
| __cplusplus | – | равно 1, если компилируется программа на языке С++; в противном случае не определено: #ifdef __cplusplus ... // Действия С++ #endif |
Макросы __FILE__, __DATE__ и __TIME__ могут использоваться в сообщениях, выдаваемых в начале программы, для указания используемой версии программы, например,
cout << "Файл " << __FILE__ << " от "
<< __DATE__ << endl;
В конкретных реализациях языка набор предопределённых имён шире.
Задание.
1. Создать программу на языке С++, в которой алгоритм сортировки одномерного массива оформить в виде макроопределения шаблона функции (см. листинг 11.5).
Алгоритм сортировки (см. Приложение 1) выбирается следующим образом (N – номер слушателя по журналу):
если N % 6 = 0 - сортировка выбором (по возрастанию),
если N % 6 = 1 - сортировка обменами (по возрастанию),
если N % 6 = 2 - сортировка вставками (по возрастанию),
если N % 6 = 3 - сортировка выбором (по убыванию),
если N % 6 = 4 - сортировка обменами (по убыванию),
если N % 6 = 5 - сортировка вставками (по убыванию).
Отсортировать:
а) Массив целых чисел (число элементов n = 50). Массив заполнить, используя генератор случайных чисел.
б) Массив вещественных чисел (n = 25). Массив заполнить считыванием из текстового файла.
2. Вывод значений массива на экран оформить в виде макроса (см. листинг 11.4).
3. Создать и проанализировать файл с результатами препроцессорной обработки текста программы (см. Приложение 2).






