Включить директиву
Многие языки программирования и другие компьютерные файлы имеют директиву , часто называемую include
, import
, или copy
, что приводит к вставке содержимого указанного файла в исходный файл. Эти включенные файлы называются заголовочные файлы или тетради . Они часто используются для определения физического расположения данных программы, фрагментов процедурного кода и/или прямых объявлений, одновременно обеспечивая инкапсуляцию и повторное использование кода или данных.
Заголовочные файлы
[ редактировать ]В компьютерном программировании — заголовочный файл программы это файл, который позволяет программистам разделять определенные элементы исходного кода на файлы многократного использования. заголовков обычно содержат предварительные объявления классов Файлы , подпрограмм , переменных и других идентификаторов . Программисты, желающие объявить стандартизированные идентификаторы более чем в одном исходном файле, могут поместить такие идентификаторы в один файл заголовка, который затем может включаться в другой код всякий раз, когда требуется содержимое заголовка. Это сделано для того, чтобы интерфейс в заголовке был отделен от реализации . [1]
Стандартная библиотека C и стандартная библиотека C++ традиционно объявляют свои стандартные функции в заголовочных файлах.
Некоторые новые компилируемые языки (например, Java и C# ) не используют предварительные объявления; идентификаторы распознаются автоматически из исходных файлов и считываются непосредственно из динамической библиотеки символов . Это означает, что файлы заголовков не нужны.
Цель
[ редактировать ]The include
Директива позволяет библиотеки разрабатывать кода, которые помогают:
- гарантировать, что все используют одну и ту же версию определения структуры данных или процедурного кода во всей программе,
- легко найти перекрестные ссылки, где компоненты используются в системе,
- легко менять программы при необходимости (редактировать нужно только один файл) и
- экономьте время за счет повторного использования макетов данных.
Пример
[ редактировать ]Пример ситуации, в которой использование директивы include дает преимущества, — это обращение к функциям в другом файле. Предположим, существует некоторый исходный файл C , содержащий функцию add
, на который ссылаются во втором файле, сначала объявляя его внешнее существование и тип (с прототипом функции ) следующим образом:
int add(int, int);
int triple(int x)
{
return add(x, add(x, x));
}
Одним из недостатков этого подхода является то, что прототип функции должен присутствовать во всех файлах, использующих эту функцию. Еще одним недостатком является то, что если тип возвращаемого значения или аргументы функции будут изменены, все эти прототипы необходимо будет обновить. Помещение прототипа в один отдельный файл позволяет избежать этих проблем. Предполагая, что прототип перемещен в файл add.h
, второй исходный файл может стать:
#include "add.h"
int triple(int x)
{
return add(x, add(x,x));
}
Теперь каждый раз, когда код компилируется, в него добавляются новейшие прототипы функций. add.h
будут включены в файлы, использующие их, что позволяет избежать потенциальных ошибок.
Языковая поддержка
[ редактировать ]С/С++
[ редактировать ]В C и C++ языках программирования #include
препроцессора директива заставляет компилятор заменить эту строку всем текстом содержимого именованного исходного файла (если оно заключено в кавычки: "") или именованного заголовка (если оно заключено в угловые скобки: <>); [2] заголовок не обязательно должен быть исходным файлом. [3] Включение продолжается рекурсивно для этого включенного содержимого до предела вложенности, определенного реализацией. Заголовки не обязательно должны иметь имена, соответствующие файлам: в стандартных заголовках C++ обычно используются такие слова, как «вектор», следовательно, #include <vector>
, тогда как в стандартных заголовках C есть идентификаторы в виде имен файлов с расширением «.h», как в #include <stdio.h>
. «Исходный файл» может быть любым файлом с именем любой формы, но чаще всего он имеет расширение «.h» и называется «заголовочным файлом» (иногда «.hpp» или «.hh», чтобы различать C++). заголовки), хотя также могут быть включены файлы с расширениями .c, .cc и .cpp (особенно в методе единой единицы компиляции ), а иногда используются и другие расширения.
Эти две формы #include
Директива может определить, какой заголовок или исходный файл включить в зависимости от реализации. На практике обычно форма в угловых скобках ищет исходные файлы в стандартном системном каталоге (или наборе каталогов), а затем ищет исходные файлы в локальных или специфичных для проекта путях (указанных в командной строке, в переменной среды, Makefile или другом файле сборки), тогда как форма с кавычками не выполняет поиск в стандартном системном каталоге, а ищет только по локальным или специфичным для проекта путям. [4] Если конфликтов нет, для указания включений, специфичных для проекта, также можно использовать форму угловых скобок, но это считается плохой формой. Тот факт, что заголовки не обязательно соответствуют файлам, является, прежде всего, технической особенностью реализации и используется для исключения расширения .h при включении стандартных заголовков C++; в обычном использовании «заголовок» означает «файл заголовка».
Например:
#include <stdio.h> // Include the contents of the standard header 'stdio.h' (probably a file 'stdio.h').
#include <vector> // Include the contents of the standard header 'vector' (probably a file 'vector.h').
#include "user_defined.h" // Include the contents of the file 'user_defined.h'.
В C и C++ могут возникнуть проблемы, если два (или более) включаемых файла содержат один и тот же третий файл. Одним из решений является предотвращение включения включаемых файлов любых других файлов, что может потребовать от программиста вручную добавлять дополнительные директивы включения в исходный файл. Другое решение — использовать include Guards . [5]
Начиная с C++20 , заголовки также можно импортировать как единицы заголовка , то есть отдельные единицы перевода, синтезированные из заголовка. [6] Они предназначены для использования вместе с модулями . Синтаксис, используемый в этом случае:
exportoptional import header-name;
Например:
import <stdio.h>; // supporting this is optional
import <vector>; // supporting this is mandated by the standard
export 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
или $include
директива компилятора, в которой $i
или $include
Директива сразу следует за началом блока комментариев в виде
{$i filename.pas}
(*$I filename.inc*)
{$include filename.inc}
(*INCLUDE filename.pas*)
Где $i
или $include
Директива не чувствительна к регистру , а имя_файла.pas или имя_файла.inc — это имя включаемого файла. (Обычно было называть включаемые файлы Паскаля расширением .inc , но это не обязательно.) Некоторые компиляторы, чтобы предотвратить неограниченную рекурсию, ограничивают вызов включаемого файла определенным числом, запрещают вызов самого себя или любого открытого в данный момент файла. , или ограничены максимум одним включаемым файлом за раз, например, включаемый файл не может включать себя или другой файл. Однако программа, включающая другие файлы, может включать их несколько, по одному.
PHP
[ редактировать ]В 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
директивы), то есть файлы заголовков не нужны.
См. также
[ редактировать ]- Интерфейс прикладного программирования (API)
- Предварительно скомпилированный заголовок
- Подпрограмма
- Модульное программирование
- #прагма один раз
- Только заголовок
- Единство сборки
- Включение
- Уязвимость включения файлов
- Одно правило определения (ODR)
- Язык определения интерфейса (IDL)
- Файл реализации класса
Ссылки
[ редактировать ]- ^ Алан Гриффитс (2005). «Разделение интерфейса и реализации в C++» . АККУ . Проверено 7 мая 2013 г.
- ^ Стандарт C11, 6.10.2 Включение исходного файла, стр. 164–165.
- ^ Стандарт C11, 7.1.2 Стандартные заголовки, стр. 181, сноска 182: «Заголовок не обязательно является исходным файлом, равно как и
<
и>
последовательности с разделителями в именах заголовков обязательно являются допустимыми именами исходных файлов. - ^ Столлман, Ричард М. (июль 1992 г.). «Препроцессор C» (PDF) . Архивировано из оригинала (PDF) 4 сентября 2012 года . Проверено 19 февраля 2014 г.
- ^ Пайк, Роб (21 февраля 1989 г.), Заметки по программированию на C , архив документов Cat-v , получено 9 декабря 2011 г.
- ^ «Объединение модулей — P1103R3» (PDF) .
- ^ «P1502R1 — Заголовочные блоки стандартной библиотеки для C++20» .
- ^ «Исходные спецификации COBOL для общего бизнес-ориентированного языка» (PDF) . Министерство обороны . Апрель 1960 г. с. IX-9. Архивировано из оригинала (PDF) 12 февраля 2014 года . Проверено 11 февраля 2014 г.
- ^ «КОПИЯ Заявление». CODASYL COBOL Журнал развития, 1968 г. Июль 1969 г. LCCN 73601243 .
- ^ "включать" . php.net . Группа PHP . Проверено 20 февраля 2014 г.
- ^ "требовать" . php.net . Группа PHP . Проверено 20 февраля 2014 г.