- •1. Языки, грамматики и их классификация. Примеры контекстно-свободных грамматик.
- •2 Трансляция арифметических выражений.
- •3 Классы. Свойства и методы, защита элементов классов. Создание и уничтожение объектов.
- •4 Управление динамической памятью
- •5 Технология создания программ и комплексов. Визуальное программирование.
- •6 Препроцессор и его основные возможности.
- •7 Адреса, указатели, ссылки. Адресная арифметика.
6 Препроцессор и его основные возможности.
Схема работы препроцессора – сканирование текста
Вставка текстов # INCLUDE
Определение препроцессорных переменных # DEFINE
Определение макросов – препроцессорных функций
Макросы с параметрами
Отмена препроцессорных переменных # UNDEF
Проверка препроцессорных выражений # IF, # IFDEF
Препроцессор представляет собой разновидность транслятора со специализированного языка работающего в режиме интерпретации, т.е. он распознает свои операторы в тексте и тут же их выполняет. В качестве входных данных препроцессор получает программу на языке препроцессора, а в результате должна получиться программа на языке программирования, например Си++ или Паскале.
Для внесения изменений в исходный текст используются переменные препроцессора, которые имеют какие-то значения и могут быть активными для замены или неактивными.
При своей работе препроцессор последовательно сканирует (просматривает) исходный текст. Если встречается оператор препроцессора, то он выполняется, если встречается активная препроцессорная переменная (ее имя), то вместо нее в текст вставляется ее значение. Сканирование продолжается с начала вставленного фрагмента, потому, что в нем также могут быть препроцессорные переменные.
Все операторы препроцессора записываются в отдельных строках, начинаются с символа # и могут продолжаться на нескольких следующих строках.
Основной оператор препроцессора, который позволяет компоновать текст, оператор вставки из файла имеет вид:
# include “имя-файла”
Если указанный текстовый файл не будет найден, препроцессор аварийно завершит свою работу. Для уточнения перед именем можно указать местоположение файла – имя диска и путь к файлу.
Препроцессорные переменные бывают только символьного типа, т.е. их значения рассматриваются как символьные строки, но при записи они ограничиваются только пробелом в начале строки и концом строки текста. В частности, значением может быть и пустая строка, не содержащая ни одного символа. В качестве имен препроцессорных переменных используются обычные идентификаторы, но чтобы отличать их от переменных в программе, они обязательно должны быть определены и активированы специальным оператором препроцессора.
Описание препроцессорных переменных и присвоение им значений выполняется оператором:
# define ИМЯ ВЫРАЖЕНИЕ
Заданное выражение в символьной форме является значением переменной и она становится активной. В дальнейшем это значение можно заменить другим с помощью другого оператора # define.
Использование имени препроцессорной переменной в операторе отмены # undef делает ее неактивной, т.е. в дальнейшем препроцессор не заменяет вхождение имени переменной в тексте на ее значение до повторного определения и активации.
Стандартная функция defined (<имя ПП-переменной>) возвращает истину, если указанная препроцессорная переменная уже определена. Эту функцию можно использовать только в препроцессорных выражениях.
Последовательное сканирование текста можно изменить на условное, т.е. выборочное, если использовать соответствующий оператор:
# if <Условное выражение>
// Фрагмент сканируется, если условие истинно
# else
// Фрагмент сканируется, если условие ложно
# endif
В этом случае сканируется только один из фрагментов исходного текста, а второй игнорируется и в результат не попадет ни в каком виде. Конструкция # else и последующий фрагмент текста могут быть опущены.
Для внесения в текст изменений, зависящих от контекста, в языке препроцессора предусмотрены макросы – аналоги функций с параметрами из языков программирования. Например, макрос
# define max(x,y) ( (x) > (y) ? (x) : (y) )
будет заменяться в тексте в зависимости от значений параметров x и y, с которыми его используют.
Использование макросов вместо обычных функций иногда может привести к увеличению размера загрузочной программы, но дать экономию во времени ее выполнения.
