Многие языки программирования и другие компьютерные файлы имеют директиву , часто называемую include
, import
или copy
, которая заставляет содержимое указанного файла вставляться в исходный файл. Эти включенные файлы называютсязаголовочные файлыилитетради. Они часто используются для определения физического расположения данных программы, фрагментов процедурного кода и/илипредварительных объявлений, одновременно обеспечиваяинкапсуляциюи повторное использование кода или данных.
В компьютерном программировании заголовочный файл — это файл, который позволяет программистам разделять определенные элементы исходного кода программы на файлы многократного использования. Файлы заголовков обычно содержат предварительные объявления классов , подпрограмм , переменных и других идентификаторов . Программисты, желающие объявить стандартизированные идентификаторы более чем в одном исходном файле, могут поместить такие идентификаторы в один файл заголовка, который затем может включаться в другой код всякий раз, когда требуется содержимое заголовка. Это сделано для того, чтобы интерфейс в заголовке был отделен от реализации .[1]
Стандартная библиотека C и стандартная библиотека C++ традиционно объявляют свои стандартные функции в заголовочных файлах.
Некоторые новые компилируемые языки (например, Java и C# ) не используют упреждающие объявления; идентификаторы распознаются автоматически из исходных файлов и считываются непосредственно из символов динамической библиотеки . Это означает, что файлы заголовков не нужны.
Директива include
позволяет разрабатывать библиотеки кода, которые помогают:
Пример ситуации, в которой использование директивы include дает преимущества, — это обращение к функциям в другом файле. Предположим, что существует некоторый исходный файл C , содержащий функцию add
, на которую ссылаются во втором файле, сначала объявляя ее внешнее существование и тип (с прототипом функции ) следующим образом:
интервал добавить ( интервал , интервал ); int тройное ( int x ) { return add ( x , add ( x , x )); }
Одним из недостатков этого подхода является то, что прототип функции должен присутствовать во всех файлах, использующих эту функцию. Еще одним недостатком является то, что если тип возвращаемого значения или аргументы функции будут изменены, все эти прототипы необходимо будет обновить. Помещение прототипа в один отдельный файл позволяет избежать этих проблем. Если предположить, что прототип перемещен в файл add.h
, второй исходный файл может стать:
#include "add.h" int тройное ( int x ) { return add ( x , add ( x , x )); }
Теперь при каждой компиляции кода новейшие прототипы функций add.h
будут включаться в использующие их файлы, что позволяет избежать потенциальных ошибок.
В языках программирования C и C++ директива #include
препроцессора заставляет компилятор заменить эту строку полным текстом содержимого именованного исходного файла (если оно заключено в кавычки: «») или именованного заголовка (если оно заключено в угловые скобки: < >); [2] заголовок не обязательно должен быть исходным файлом. [3] Включение продолжается рекурсивно для этого включенного содержимого до предела вложенности, определенного реализацией. Заголовки не обязательно должны иметь имена, соответствующие файлам: в стандартных заголовках C++ обычно используются такие слова, как «вектор», следовательно , в то время как в стандартных заголовках C есть идентификаторы в виде имен файлов с расширением «.h», как в . «Исходный файл» может быть любым файлом с именем любой формы, но чаще всего он имеет расширение «.h» и называется «заголовочным файлом» (иногда «.hpp» или «.hh» для обозначения C++). заголовки), хотя файлы с расширениями .c, .cc и .cpp также могут быть включены (особенно в методе единой единицы компиляции ), а иногда используются и другие расширения.#include <vector>
#include <stdio.h>
Эти две формы #include
директивы могут определить, какой заголовок или исходный файл включить в зависимости от реализации. На практике обычно форма в угловых скобках ищет исходные файлы в стандартном системном каталоге (или наборе каталогов), а затем ищет исходные файлы в локальных или специфичных для проекта путях (указанных в командной строке, в переменной среды, Makefile или другом файле сборки), тогда как форма с кавычками не выполняет поиск в стандартном системном каталоге, а ищет только по локальным или специфичным для проекта путям. [4] Если конфликтов нет, для указания включений, специфичных для проекта, также можно использовать форму угловых скобок, но это считается плохой формой. Тот факт, что заголовки не обязательно должны соответствовать файлам, является, прежде всего, технической особенностью реализации и используется для исключения расширения .h при включении стандартных заголовков C++; в обычном использовании «заголовок» означает «файл заголовка».
Например:
#include <stdio.h> // Включаем содержимое стандартного заголовка «stdio.h» (вероятно, файл «stdio.h»). #include <vector> // Включаем содержимое стандартного заголовка «vector» (вероятно, файл «vector.h»). #include "user_defined.h" // Включаем содержимое файла user_defined.h.
В C и C++ могут возникнуть проблемы, если два (или более) включаемых файла содержат один и тот же третий файл. Одним из решений является исключение включения включаемых файлов любых других файлов, что может потребовать от программиста вручную добавлять дополнительные директивы включения в исходный файл. Другое решение — использовать include Guards . [5]
Начиная с C++20 , заголовки также можно импортировать как единицы заголовка , то есть отдельные единицы перевода, синтезированные из заголовка. [6] Они предназначены для использования вместе с модулями . Синтаксис, используемый в этом случае:
экспортировать необязательное имя заголовка импорта;
Например:
импортировать < stdio . ч > ; // поддержка этого необязательна import <vector> ; // поддержка этого предусмотрена стандартным экспортом import "user_defined.h" ;
Единицы заголовков предусмотрены для всех заголовков стандартной библиотеки C++. [7]
COBOL (а также RPG IV ) позволяет программистам копировать тетради в исходный код программы аналогично файлам заголовков, но также позволяет заменять в них определенный текст другим текстом. Ключевое слово COBOL для включения — COPY
, а замена выполняется с использованием этого REPLACING ... BY ...
предложения. Директива include присутствует в COBOL начиная с COBOL 60, но была изменена с исходной INCLUDE
[8] на COPY
1968 год. [9]
Фортран не требует файлов заголовков как таковых . Однако в Fortran 90 и более поздних версиях есть две связанные функции: include
операторы и модули. Первый может использоваться для совместного использования общего файла, содержащего интерфейсы процедур, во многом аналогично заголовку C, хотя спецификация интерфейса не требуется для всех разновидностей процедур Фортрана. Этот подход обычно не используется; вместо этого процедуры обычно группируются в модули, на которые затем можно ссылаться с помощью use
оператора в других областях кода. Для модулей информация об интерфейсе типа заголовка автоматически генерируется компилятором и обычно помещается в отдельные файлы модулей, хотя некоторые компиляторы помещают эту информацию непосредственно в объектные файлы. Сама спецификация языка не требует создания каких-либо дополнительных файлов, хотя интерфейсы процедур модулей почти повсеместно распространяются таким образом.
Большинство компиляторов Pascal поддерживают директиву компилятора $i
or $include
, в которой директива $i
or $include
следует сразу за началом блока комментариев в форме
{$i filename.pas}
(*$I filename.inc*)
{$include filename.inc}
(*INCLUDE filename.pas*)
Если директива $i
или $include
не чувствительна к регистру , а имя_файла.pas или имя_файла.inc — это имя файла, который необходимо включить. (Обычно было называть включаемые файлы Паскаля расширением .inc , но это не обязательно.) Некоторые компиляторы, чтобы предотвратить неограниченную рекурсию, ограничивают вызов включаемого файла определенным числом, запрещают вызов самого себя или любого открытого в данный момент файла. , или ограничены максимум одним включаемым файлом за раз, например, включаемый файл не может включать себя или другой файл. Однако программа, включающая другие файлы, может включать их несколько, по одному.
В PHP директива include
вызывает включение и оценку другого файла PHP. [10] Аналогичными командами являются require
, которые при неудачном включении создают фатальное исключение и останавливают выполнение сценария, [11] и include_once
и require_once
, которые предотвращают повторное включение или требование файла, если он уже был включен или требуется, избегая C. проблема двойного включения.
Существует множество форм директивы include, например:
include ...
( Фортран , МАСМ )<!--#include ... -->
(HTML SSI )import ...;
( Джава )import ... from ...
( JavaScript как в ECMAScript )var ... = require("...")
(JavaScript с CommonJS )<%@ include ... %>
( ДЖСП ){$I ...}
( UCSD Паскаль , Турбо Паскаль )%include ...
( ПЛ/Я )import ...
( Питон )/COPY QCPYLESRC,QBC
(RPG IV – первый аргумент – имя файла, второй аргумент – тетрадь)use ...;
( Ржавчина )using ...;
( С# )local ... = require("...")
( Луа )import ...;
( Д )Современные языки (например, Haskell и Java ) склонны избегать тетрадей или включений, предпочитая модули и системы импорта/экспорта для управления пространством имен . Некоторые из этих языков (например, Java и C# ) не используют упреждающие объявления, вместо этого идентификаторы распознаются автоматически из исходных файлов и считываются непосредственно из символов динамической библиотеки (обычно на которые ссылаются директивы import
или using
), что означает, что файлы заголовков не нужны.
<
с >
разделителями в именах заголовков не обязательно являются действительными именами исходных файлов.