Препроцессор Си
Препроцессор C — макропрепроцессор для языков программирования C, Objective-C и C++.
Общая информация[править]
Препроцессор автоматически запускается компилятором C перед компиляцией. Он называется макропроцессором, потому что позволяет определять макросы, которые являются сокращенными идентификаторами для более длинных конструкций.
Во многих реализациях языка Си это отдельная программа, вызываемая компилятором в качестве первой части трансляции. Таким образом, на вход компилятора попадает текст, который может отличаться от того, который видит программист. Символ # (перед которым возможны символы-разделители) является знаком для препроцессора. Синтаксис таких строк не зависит от грамматики C, они могут появляться где угодно и не зависят от области видимости. Иногда препроцессор Си используется также для обработки других видов текстовых файлов.
Препроцессор языка Си предоставляет четыре отдельные возможности, которые вы можете использовать по своему усмотрению:
- Включение заголовочных файлов. Это файлы с декларациями, которые могут быть вставлены в вашу программу.
- Развертка макросов. Вы можете создать макросы, которые являются сокращениями для произвольных фрагментов языка Си, а затем препроцессор Си заменит макросы их определениями во всей программе.
- Условная компиляция. Используя специальные директивы препроцессирования, вы можете включать или исключать части программы в соответствии с различными условиями.
- Контроль строк. Если вы используете препроцессор для объединения или перестановки исходных файлов в промежуточный файл, вы можете управлять порядком строк (иногда используют кальку «порядок инклюдов»), и это в ряде случаев влияет на результат компиляции.
История[править]
Препроцессор появился в языке Си в 1973 году в связи с признанием полезности механизмов включения файлов, доступных в BCPL. Его первоначальная версия предлагала только включение файлов и простую замену строк с помощью #include
и #define
для макросов без параметров, соответственно. Вскоре она была расширена для включения макросов с аргументами и условной компиляции.
Включение файлов[править]
Одно из самых распространенных применений препроцессора — это включение другого файла:
#include <stdio.h> int main(void) { printf("Hello, World!\n"); return 0; }
Препроцессор заменяет строку #include <stdio.h>
текстовым содержимым файла 'stdio.h'
, в котором, помимо прочего, объявлена функция printf()
.
В другом варианте синтаксиса используются двойные кавычки (например, #include "stdio.h"
), это влияет на порядок поиска заголовка. Если имя файла заключено в угловые скобки, файл ищется в стандартных путях включения компилятора. Если имя файла заключено в двойные кавычки, то путь поиска расширяется и включает текущий каталог исходных файлов. Компиляторы языка Си и среды программирования имеют средства, позволяющие программисту определить, где можно найти включаемые файлы. Это может быть сделано с помощью флага командной строки, который может быть параметризован с помощью makefile, так что, например, для разных операционных систем может быть использован разный набор включаемых файлов.
По соглашению, включаемые файлы именуются с расширением .h или .hpp, но это не является обязательным требованием. Файлы с расширением .def могут обозначать файлы, предназначенные для многократного включения, каждый раз разворачиваясь в одно и то же повторяющееся содержимое; #include "icon.xbm"
, скорее всего, включает файл изображения XBM (который в то же время является исходным файлом C).
Как правило, #include
подразумевает использование #include-guards
(«гарды») или директивы #pragma once
для предотвращения двойного включения.
Условная компиляция[править]
Условная компиляция реализуется директивами if-else #if
, #ifdef
, #ifndef
, #else
, #elif
и #endif
. Варианты #ifdef и #ifndef являются простыми сокращениями для #if defined(…) и #if !defined(…).
#if VERBOSE >= 2 printf("сообщение трассировки"); #endif
Между директивами #if и #endif допускается произвольное количество директив #elif и не более одной директивы #else. Если директива #else присутствует, то между ней и директивой #endif на данном уровне вложенности не должно быть других директив #elif.
Литература[править]
- Richard M. Stallman The C Preprocessor (1992).
- Керниган Б., Ритчи Д. Язык программирования Си = The C programming language. — 2-е изд. — М.: Вильямс, 2007. — С. 304. — ISBN 0-13-110362-8.
- Гукин Д. Язык программирования Си для «чайников» = C For Dummies. — М.: Диалектика, 2006. — С. 352. — ISBN 0-7645-7068-4.
Ссылки[править]
↑ [+] | |
---|---|
Компиляторы |
Borland Turbo C • Clang • GCC • LCC • Pelles C • PCC • TCC • Visual C++ (C++/CLI • C++/CX) • Watcom C/C++ compiler |
Библиотеки |
Стандартная библиотека языка Си • glibc • dietlibc • uClibc • Newlib • Eglibc • Bionic |
Особенности |
Операторы • C-строка • Синтаксис • Препроцессор • Заголовочные файлы • Типы данных • Функции |
Некоторые потомки |
C++ • C# • D • Objective-C • Swift • Java • Alef[en] • Limbo • Go • Vala |
C и другие языки |
C и C++ (Совместимость[en] • Операторы) • Сравнение Pascal и C[en] • Компилятор C в байт-код Java |
Одним из источников этой статьи является статья в википроекте «Руниверсалис» («Руни», руни.рф), называющаяся «Препроцессор Си». Материал указанной статьи полностью или частично использован в Циклопедии по лицензии CC BY-SA. Всем участникам Руниверсалиса предлагается прочитать «Обращение к участникам Руниверсалиса» основателя Циклопедии и «Почему Циклопедия?». |