Урок №22. Директивы препроцессора
Препроцессор лучше всего рассматривать как отдельную программу, которая выполняется перед компиляцией. При запуске программы, препроцессор просматривает код сверху вниз, файл за файлом, в поиске директив. Директивы — это специальные команды, которые начинаются с символа # и НЕ заканчиваются точкой с запятой. Есть несколько типов директив, которые мы рассмотрим ниже.
Директива #include
Вы уже видели директиву #include в действии. Когда вы подключаете файл с помощью директивы #include, препроцессор копирует содержимое подключаемого файла в текущий файл сразу после строки с #include. Это очень полезно при использовании определенных данных (например, предварительных объявлений функций) сразу в нескольких местах.
Директива #include имеет две формы:
#include <filename> , которая сообщает препроцессору искать файл в системных путях (в местах хранения системных библиотек языка С++). Чаще всего вы будете использовать эту форму при подключении заголовочных файлов из Стандартной библиотеки C++.
#include «filename» , которая сообщает препроцессору искать файл в текущей директории проекта. Если его там не окажется, то препроцессор начнет проверять системные пути и любые другие, которые вы указали в настройках вашей IDE. Эта форма используется для подключения пользовательских заголовочных файлов.
Директива #define
Директиву #define можно использовать для создания макросов. Макрос — это правило, которое определяет конвертацию идентификатора в указанные данные.
Есть два основных типа макросов: макросы-функции и макросы-объекты.
Макросы-функции ведут себя как функции и используются в тех же целях. Мы не будем сейчас их обсуждать, так как их использование, как правило, считается опасным, и почти всё, что они могут сделать, можно осуществить с помощью простой (линейной) функции.
Макросы-объекты можно определить одним из следующих двух способов:
#define идентификатор текст_замена
Верхнее определение не имеет никакого текст_замена , в то время как нижнее — имеет. Поскольку это директивы препроцессора (а не простые стейтменты), то ни одна из форм не заканчивается точкой с запятой.
Макросы-объекты с текст_замена
Когда препроцессор встречает макросы-объекты с текст_замена , то любое дальнейшее появление идентификатор заменяется на текст_замена . идентификатор обычно пишется заглавными буквами с символами подчёркивания вместо пробелов.
Директива (программирование)
В языках программирования объявле́ние (англ. declaration) включает в себя указание идентификатора, типа, а также других аспектов элементов языка, например, переменных и функций. Объявление используется, чтобы уведомить компилятор о существовании элемента; это весьма важно для многих языков (например, таких как Си), требующих объявления переменных перед их использованием.
Побо́чные эффе́кты (англ. side effects) — любые действия работающей программы, изменяющие среду выполнения (англ. execution environment). Например, к побочным эффектам относятся.
Из-за путаницы с терминологией словом «оператор» в программировании нередко обозначают операцию (англ. operator), см. Операция (программирование).Инстру́кция или опера́тор (англ. statement) — наименьшая автономная часть языка программирования; команда или набор команд. Программа обычно представляет собой последовательность инструкций.
Сопрограммы (англ. coroutines) — методика связи программных модулей друг с другом по принципу кооперативной многозадачности: модуль приостанавливается в определённой точке, сохраняя полное состояние (включая стек вызовов и счётчик команд), и передаёт управление другому. Тот, в свою очередь, выполняет задачу и передаёт управление обратно, сохраняя свои стек и счётчик.
В информатике и теории автоматов состояние цифровой логической схемы или компьютерной программы является техническим термином для всей хранимой информации, к которой схема или программа в данный момент времени имеет доступ. Вывод данных цифровой схемы или компьютерной программы в любой момент времени полностью определяется его текущими входными данными и его состоянием.
Препроцессор языка С
Препроцессор (англ. preprocessor ) – программа , выполняющая предварительную обработку входных данных для другой программы [19.1]. Препроцессор языка программирования С просматривает программу до компилятора и заменяет в программе определенные сочетания символов (символические аббревиатуры) на соответствующие директивы. Он отыскивает и подключает к программе необходимые файлы и может изменить условия компиляции [19.1]. Препроцессор имеет тот же смысл, что и буферный процессор .
Препроцессор языка С выполняет макроподстановку, условную компиляцию и включение именованных файлов. Строки, начинающиеся со знака # (перед которыми разрешены символы пустого пространства), задают препроцессору инструкции-директивы. Их синтаксис не зависит от остальной части языка; они могут фигурировать где угодно и оказывать влияние (независимо от области действия) вплоть до конца единицы трансляции. Границы строк принимаются во внимание: каждая строка анализируется отдельно (но есть возможность и сцеплять строки). Лексемами для препроцессора являются все лексемы языка и последовательность символов, задающие имена файлов. Кроме того, любой символ, не определенный каким-либо другим способом, также воспринимается как лексема [19.2]. Влияние символов пустого пространства, отличающихся от пробелов и горизонтальных табуляций, внутри строк препроцессора не определено.
В предыдущих лабораторных работах уже встречались строки с начальным символом #. Это # include и # define . Первая директива ( инструкция ) использовалась для подключения заголовочных файлов, в первую очередь из библиотеки языка С, а вторая – для подстановки символов или чисел в определенные места программного кода.
Имеются следующие директивы препроцессора:
| #define | #endif | # ifdef | #line |
| #elif | #error | #ifndef | # pragma |
| #else | #if | #include | #undef |
Каждая директива препроцессора должна занимать отдельную строку. Например, строка
Директива (программирование)
. В компьютерном программировании директива или pragma (от «прагматика») является языковой конструкцией , который указывает, как компилятор (или другой переводчик ) должен обрабатывать свой ввод. Директивы не являются частью грамматики языка программирования и могут отличаться от компилятора к компилятору. Они могут обрабатываться препроцессором , чтобы указать поведение компилятора, или функционировать как форма внутриполосной параметризации.
В некоторых случаях директивы определяют глобальное поведение, в то время как в других случаях они влияют только на локальный раздел, например блок программного кода. В некоторых случаях, например в некоторых программах на C, директивы являются необязательными подсказками компилятора и могут игнорироваться, но обычно они предписывают и должны соблюдаться. Однако директива не выполняет никаких действий на самом языке, а только изменяет поведение компилятора.
Этот термин может использоваться для обозначения проприетарных сторонних тегов и команд (или разметки), встроенных в код, которые приводят к дополнительной исполняемой обработке, расширяющей существующие конструкции компилятора, ассемблера и языка, присутствующие в среде разработки. Термин «директива» также применяется по-разному, аналогично термину команда.
Содержание
- 1 Препроцессор C
- 2 История
- 3 Другие языки
- 3.1 Язык ассемблера
- 3.2 PL / SQL
Препроцессор C
В C и C ++ язык поддерживает простой препроцессор macro . Строки исходного кода, которые должны обрабатываться препроцессором, такие как #define и #include , называются директивами препроцессора.
Другая конструкция C, директива #pragma , используется для указания компилятору использовать прагматические или зависящие от реализации функции. Двумя известными пользователями этой директивы являются OpenMP и OpenACC.
Синтаксические конструкции, похожие на директивы препроцессора языка C, такие как C # #if , также обычно называются «директивами», хотя в этих случаях может не быть задействована реальная фаза предварительной обработки.
Все команды препроцессора начинаются с символа решетки (#).
История
Директивы датируются АЛГОЛОМ 68, где они известны как прагматики (от «прагматический») и обозначаются прагматиками. или пр ; в новых языках, особенно в C, это сокращено до «прагма» (без «т»).
Обычно прагматики в АЛГОЛе 68 используются для определения режима сглаживания, что означает, «как указываются ключевые слова». Далее следуют различные такие директивы, определяющие режимы POINT, UPPER, RES (зарезервировано) или котировки. Обратите внимание на использование строчки для самого ключевого слова pragmat (сокращенно pr ), либо в режиме ТОЧКА, либо в режиме кавычек:
Сегодня директивы наиболее известны на языке C, созданном в начале 1970-х годов, и продолжаются в текущем стандарте C99, где они являются либо инструкциями для препроцессора C, либо, в форме #pragma , директивами для самого компилятора. Они также в некоторой степени используются в более современных языках; увидеть ниже.