#include директива (C/C++)
Указывает препроцессору включить содержимое указанного файла в точку, в которой появится директива.
Синтаксис
#include « path-spec «
#include path-spec >
Замечания
Вы можете упорядочить определения констант и макросов включаемые файлы (также известные как файлы заголовков), а затем использовать #include директивы для их добавления в любой исходный файл. Включаемые файлы также позволяют внедрять объявления внешних переменных и сложных типов данных. Типы можно определять и именовать только один раз во включаемом файле, созданном с этой целью.
Спецификация пути — это имя файла, которое может предшествовать спецификации каталога. Имя файла должно указывать на существующий файл. Синтаксис спецификации пути зависит от операционной системы, в которой компилируется программа.
Сведения о том, как ссылаться на сборки в приложении C++, скомпилированном с помощью /clr директивы, см #using . в директиве.
Обе формы синтаксиса приводят #include к замене директивы всем содержимым указанного файла. Разница между двумя формами — это порядок путей, которые выполняет препроцессор при неполном указании пути. В приведенной ниже таблице показывается различие между этими формами синтаксиса.
| Форма синтаксиса | Действие |
|---|---|
| Форма в кавычках | Препроцессор ищет включаемые файлы в следующем порядке: |
1) В том же каталоге, что и файл, содержащий инструкцию #include .
2) В каталоги открытых в настоящее время файлов включают файлы в обратном порядке, в котором они были открыты. Поиск начинается в каталоге родительского включаемого файла, а затем выполняется в каталогах всех включаемых файлов-прародителей.
3) Вдоль пути, заданного каждым /I параметром компилятора.
1) Вдоль пути, заданного каждым /I параметром компилятора.
Как только препроцессор найдет файл с заданным именем, поиск останавливается. Если вы заключаете полную, однозначное описание пути включения файла между двойными кавычками ( » » ), препроцессор выполняет поиск только по этой спецификации пути и игнорирует стандартные каталоги.
Если имя файла, заключенное в двойные кавычки, является неполной спецификацией пути, препроцессор сначала выполняет поиск в каталоге родительского файла. Родительский файл — это файл, содержащий директиву #include . Например, если в файл с именем file1 включен файл с именем file2, файл1 является родительским файлом.
Включить файлы можно вложить: #include директива может отображаться в файле, именованном другой #include директивой. Например, file2 может включать файл3. В этом случае файл1 по-прежнему будет родительским элементом file2, но это будет бабушка и дедушка файла3.
При добавлении файлов вложены и при компиляции в командной строке поиск каталога начинается в каталоге родительского файла. Затем он проходит через каталоги любых бабушки и дедушки файлов. Таким образом, поиск начинается относительно каталога, в котором находится исходный файл, обрабатываемый в текущий момент. Если файл не найден, поиск перемещается в каталоги, указанные параметром /I компилятора (дополнительные каталоги включения). Наконец, выполняется поиск каталогов, указанных переменной INCLUDE среды.
В среде INCLUDE разработки Visual Studio переменная среды игнорируется. Вместо этого используются значения, указанные в свойствах проекта для каталогов include. Дополнительные сведения о настройке каталогов включения в Visual Studio см. в разделе «Включить каталоги» и «Дополнительные каталоги включения».
В приведенном ниже примере демонстрируется включение файлов с помощью угловых скобок:
#include
В примере добавляется содержимое файла с именем stdio.h исходной программы. Угловые скобки приводят к тому, что препроцессор выполняет поиск каталогов, указанных INCLUDE переменной среды, stdio.h после поиска каталогов, указанных параметром компилятора /I .
В следующем примере демонстрируется включение файлов, заданных в кавычках:
#include "defs.h"
В примере добавляется содержимое файла, указанного defs.h в исходной программе. Кавычки означают, что препроцессор сначала попытается найти этот файл в каталоге, содержащем родительский исходный файл.
Для включаемых файлов поддерживается до 10 уровней вложения. После завершения обработки вложенного #include препроцессора продолжает вставлять вложенный родительский файл в исходный файл.
Только для систем Майкрософт
Чтобы найти исходные файлы для включения, препроцессор сначала выполняет поиск каталогов, указанных параметром компилятора /I . /I Если параметр отсутствует или не удается, препроцессор использует INCLUDE переменную среды для поиска файлов в угловых скобках. Переменная INCLUDE среды и /I параметр компилятора могут содержать несколько путей, разделенных точкой с запятой ( ; ). Если несколько каталогов отображаются как часть /I параметра или в INCLUDE переменной среды, препроцессор выполняет поиск по порядку, в котором они отображаются.
Представим себе следующую команду:
CL /ID:\msvc\include myprog.c
вызывает препроцессор поиска каталога D:\msvc\include\ для включения файлов, таких как stdio.h . Ниже еще один пример:
SET INCLUDE=D:\msvc\include CL myprog.c
Эта инструкция действуют точно так же. Если найти файл в обоих наборах каталогов не удастся, возникает неустранимая ошибка компилятора.
Если имя файла полностью указано для файла include, имеющего путь, содержащий двоеточие (например, F:\MSVC\SPECIAL\INCL\TEST.H ), препроцессор следует пути.
Для включения файлов, указанных как #include «path-spec» , поиск каталогов начинается в каталоге родительского файла, а затем проходит через каталоги любых файлов бабушки и дедушки. То есть поиск начинается относительно каталога, содержащего исходный файл, который обрабатывается. Если нет файла бабушки и дедушки, и файл по-прежнему не найден, поиск продолжается, как если бы имя файла было заключено в угловые скобки.
КОНЕЦ Только для систем Майкрософт
Include c что это
Подключаемый файл это файл, содержащий определения функций и переменных, а также макроопределения вместе с некоторыми исходными файлами. Для использования в программе подключаемых файлов применяется директива препроцессора ‘#include’.
- Системные подключаемые файлы используются для определения интерфейсов к составляющим операционной системы. Они подключаются для предоставления объявлений и определений, требуемых для работы с системными вызовами и библиотеками.
- Подключаемые файлы пользователя содержат определения для интерфейсов между исходными файлами программы.
Обычно подключаемые файлы заканчиваются на ‘.h’ и следует избегать использования других стандартов.
Как файлы пользователя, так и системные файлы включаются в программу с использованием директивы препроцессора ‘#include’. Она имеет три модификации:
'#include '
Эта модификация используется для подключения системных файлов. При ее выполнении производится поиск файла с именем FILE в списке указанных заранее каталогов, а затем в стандартном списке системных каталогов. С помощью опции ‘-I’ указываются каталоги для поиска подключаемых файлов. Опция ‘-nostdinc’ запрещает поиск в стандартных системных каталогах и производит поиск только в указанных каталогах.
Синтаксис такой модификации директивы ‘#include’ довольно специфичен, потому как комментарии внутри ‘<. >‘ не распознаются. Поэтому в строке ‘#include *y>’ последовательность символов ‘*’ не начинает комментарий, а указанная директива включает в программу файл с именем ‘x/*y’.
Аргумент FILE не может содержать символа ‘>’, хотя он может содержать символ ‘
'#include "FILE"'
Эта модификация применяется для подключаемых файлов для программ пользователя. Сначала файл FILE просматривается в текущем каталоге, а затем в каталогах для системных подключаемых файлов. Текущим каталогом является каталог текущего обрабатываемого файла. Он просматривается в первую очередь, так как предполагается, что в нем находятся файлы, имеющие отношение к текущему обрабатываемому файлу. (Если указана опция ‘-I-‘, то текущий каталог не просматривается.)
Аргумент FILE не может содержать символов ‘»‘. Символы backslash интерпретируются как отдельные символы, а не начало escape последовательности. Таким образом, директива ‘#include «x\n\\y»‘ указывает имя файла, содержащего три символа backslash.
'#include ANYTHING ELSE'
Эта модификация называется «вычисляемой директивой #include». Любая директива ‘#include’, не соответствующая ни одной из модификаций, рассмотреных выше, является вычисляемой директивой. Строка ANYTHING ELSE проверяется на наличие соответствующего макроса, значение которого затем заменяет его название. Полученная в результате строка должна уже в точности соответствовать одной из рассмотренных выше модификаций (то есть имя подключаемого файла должно быть заключено в кавычки или угловые скобки).
Эта возможность позволяет определять макросы, что дает возможность изменять имена подключаемых файлов. Эта возможность, например, используется при переносе программ с одной операционной системы на другие, где требуются разные подключаемые файлы.
Директива ‘#include’ указывает С препроцессору обработать указанный файл перед обработкой оставшейся части текущего файла. Информация, выдаваемая препроцессором, содержит уже полученные данные, за которыми следуют данные, получаемые при обработке подключаемого файла, а за которыми, в свою очередь, следуют данные, получаемые при обработке текста, следующего после директивы ‘#include’. Например, дан следующий подключаемый файл ‘header.h’:
char *test ();
и основная программа с именем ‘program.c’, использующая этот файл.
int x; #include «header.h» main ()
Данные, полученные при обработке программы ‘program.c’ будут выглядеть следующим образом:
int x; char *test (); main ()
Для подключаемых файлов нет ограничений на объявления и макроопределения. Любой фрагмент С программы может быть включен в другой файл. Подключаемый файл может даже содержать начало выражения, заканчивающееся в исходном файле или окончание выражения, начало которого находится в исходном файле. Хотя комметарии и строковые константы не могут начинаться подключаемом файле и продолжаться в исходном файле. Не завершенный комментарий, стороковая или символьная константа в подключаемом файле приводят к возникновению ошибки в конце файла.
Подключаемый файл может содержать начало или окончание сиснтаксической конструкции, такой как определение функции.
Срока, следующая за директивой ‘#include’ всегда является пустой и добавляется С препроцессором даже если подключаемый файл не содержит завершающий символ перевода строки.
Часто случается, что подключаемый файл включает в себя другой файл. Это может привести к тому, что отдельный файл будет подключаться неоднократно, что может привести к возникновению ошибок, если файл определяет типы структур или определения типов. Поэтому следует избегать многократного подключения файлов.
Обычно это достигается путем заключения в условие всего содержимого этого файла, как показано ниже:
#ifndef FILE_FOO_SEEN #define FILE_FOO_SEEN Сам файл #endif /* FILE_FOO_SEEN */
Макрос ‘FILE_FOO_SEEN’ указывает на то, что файл уже однажды вкючался. В подключаемых файлах пользователя макрос не должен начинаться с символа ‘_’. В системных подключаемых файлах его имя не должно начинаться с символа ‘__’ во избежание возникновения конфликтов с программами пользователя. Каким бы ни был файл, имя макроса должно содержать имя файла и некоторый дополнительный текст во избежание вознкновения конфликтов с другими подключаемыми файлами.
Препроцессор GNU C построен таким образом, что обработке подключаемого файла он проверяет наличие определенных конструкций и наиболее рационально их обрабатывает. Препроцессор специально отмечает полное вложение файла в условие ‘#ifndef’. Если в подключаемом файле содержится директива ‘#include’, указывающая на обрабатываемый файл, или макрос в директиве ‘#ifndef’ уже определен, то обрабатываемый файл полностью игнорируется.
Существует также специальная директива, указывающая препроцессору, что файл должен быть включен не более одного раза. Эта директива называется ‘#pragma once’. Она использовалась в дополнение к директиве ‘#ifndef’ и в настоящее время она устарела и не должна прменяться.
В объектно ориентированном языке С существует модификация директивы ‘#include’, называемая ‘#import’, которая используется для вкючения файла не более одного раза. При использовании директивы ‘#import’ вместо ‘#include’ не требуется наличия условных оборотов для предотвращения многократной обработки файла.
«Наследование» это то, что происходит, когда какой либо объект или файл образует некоторую часть своего содержимого путем виртуального копирования из другого объекта или файла. В случае подключаемых С файлов наследование означает, что один файл включает другой файл, а затем заменяет или добавляет что-либо.
Если наследуемый подключаемый файл и основной подключаемый файл имеют различные имена, то такое наследование называется прямым. При этом используется конструкция ‘#include «BASE»‘ в наследуемом файле.
Иногда необходимо чтобы у наследуемого и основного подключаемого файла были одинаковые имена.
Например, предположим, что прикладная программа использует системный подключаемый файл ‘sys/signal.h’, но версия файла ‘/usr/include/sys/signal.h’ на данной системе выполняет того, что требуется в прикладной программе. Будет удобнее определить локальную версию, возможно с именем ‘/usr/local/include/sys/signal.h’ для замены или добавления к версии, поставляемой с системой.
Это можно выполнить с применением опции ‘-I.’ при компиляции, а также созданием файла ‘sys/signal.h’ который выполняет требуемые программе функции. Но сделать так, чтобы этот файл включал стандартный файл ‘sys/signal.h’ не так просто. При включении строки ‘#include ‘ в этот файл произойдет подключение новой версии файла, а не стандартной системной версии. Это приведет к рекурсии и ошибке при компиляции.
При использовании директивы `#include ‘ нужный файл будет найден, но этот способ является не эфективным, так как содержит полный путь к системному файлу. Это может отразиться на содержании системы, так как это означает, что любые изменения местоположения системных файлов потребуют дополнительных изменений где-либо еще.
Более эффективным решением этой проблемы является применение директивы ‘#include_next’, которая используется для подключения следующего файла с таким же именем. Эта директива функционирует также как и директива ‘#include’ за исключением поиска требуемого файла. Она начинает поиск списка каталогов подключаемых файлов после каталога, где был найден текущий файл.
Предположим была указана опция ‘-I /usr/local/include’, а список каталогов для поиска включает ‘/usr/include’. Также предположим, что оба каталога содержат файл с именем ‘sys/signal.h’. Директива ‘#include ‘ найдет нужный файл под каталогом ‘/usr/local/include’. Если этот файл содержит строку ‘#include_next ‘, то поиск будет возобновлен после предыдущего каталога и будет найден файл в каталоге ‘/usr/include’.
Что такое include в C++?
Директива #include используется для включения содержимого файла в программу во время компиляции. Это мощный инструмент для организации кода, разделения его на отдельные модули и повторного использования.
Основные моменты:
- Включение заголовочных файлов: Директива #include применяется для включения заголовочных файлов в программу. Заголовочные файлы содержат объявления функций, классов, и другие элементы, которые вы хотите использовать в своем коде.
- Защита от многократного включения: Для избежания проблем с множественным включением одного и того же файла, используется препроцессорная директива #pragma once или стандартный метод с использованием конструкции #ifndef , #define , и #endif .
// Есть файл: MathFunctions.cpp #include "MathFunctions.h" // Реализация функций double add(double a, double b) < return a + b; >double subtract(double a, double b)
include и заголовочный файлы
Заголовочный файл (иногда головной файл, англ. header file), или подключаемый файл — в языках программирования Си и C++ файл, содержащий определения типов данных, структуры, прототипы функций, перечисления, макросы препроцессора. Имеет по умолчанию расширение .h; иногда для заголовочных файлов языка C++ используют расширение .hpp. Заголовочный файл используется путём включения его текста в данный файл директивой препроцессора #include. Заголовочный файл в общем случае может содержать любые конструкции языка программирования, но на практике исполняемый код (за исключением inline-функций в C++) в заголовочные файлы не помещают. Например, идентификаторы, которые должны быть объявлены более чем в одном файле, удобно описать в заголовочном файле, а затем его подключать по мере надобности.
Заголовочные файлы оказываются весьма эффективным средством при модульной разработке крупных программ. Также, в практике программирования на С обычна ситуация, при которой, если в программе используется несколько функций, то удобно тексты этих функций хранить в отдельном файле. При подготовке программы пользователь включает в нее тексты используемых функций с помощью команд #include.
По традиции заголовочные файлы имеют расширение .h, а файлы, содержащие определения функций или данных, расширение .c. Иногда их называют «h-файлы» или «с-файлы» соответственно. Используют и другие расширения для этих файлов: .C, cxx, .cpp и .cc. Принятое расширение вы найдете в своем справочном руководстве.
Для включения файлов из стандартных каталогов (обычно каталоги с именем INCLUDE) надо вместо кавычек использовать угловые скобки < и >. Если имя_файла — в угловых скобках, то препроцессор разыскивает файл в стандартных системных каталогах. Если имя_файла заключено в кавычки, то вначале препроцессор просматривает текущий каталог пользователя и только затем обращается к просмотру стандартных системных каталогов. Например:
#include // включение из стандартного каталога. Имя в угловых скобках. #include "myheader.h" // включение из текущего каталога. Имя в кавычках. #include "..\CommonFiles\CmnHdr.h"
Включение из стандартных каталогов имеет то преимущество, что имена этих каталогов никак не связаны с конкретной программой (обычно вначале включаемые файлы ищутся в каталоге /usr/include/CC, а затем в /usr/include). К сожалению, в этой команде пробелы существенны:
#include < stream.h>// не будет найден
Было бы нелепо, если бы каждый раз перед включением файла требовалась его перетрансляция. Обычно включаемые файлы содержат только описания, а не операторы и определения, требующие существенной трансляторной обработки. Кроме того, система программирования может предварительно оттранслировать заголовочные файлы, если, конечно, она настолько развита, что способна сделать это, не изменяя семантики программы.
Укажем, что может содержать заголовочный файл:
Определения типов struct point < int x, y; >; Шаблоны типов template class V < /* . */ >Описания функций extern int strlen(const char*); Определения inline char get() < return *p++; >функций-подстановок Описания данных extern int a; Определения констант const float pi = 3.141593; Перечисления enum bool < false, true >; Описания имен class Matrix; Команды включения файлов #include Макроопределения #define Case break;case Комментарии /* проверка на конец файла */
Перечисление того, что стоит помещать в заголовочный файл, не является требованием языка, это просто совет по разумному использованию включения файлов. С другой стороны, в заголовочном файле никогда не должно быть:
Определений обычных функций char get() < return *p++; >Определений данных int a; Определений составных const tb[i] = < /* . */ >; констант
Один Заголовочный Файл (.h)
Проще всего решить проблему разбиения программы на несколько файлов поместив функции и определения данных в подходящее число исходных файлов и описав типы, необходимые для их взаимодействия, в одном заголовочном файле, который включается во все остальные файлы. Для программы калькулятора можно использовать четыре .c файла: lex.c, syn.c, table.c и main.c, и заголовочный файл dc.h, содержащий описания всех имен, которые используются более чем в одном .c файле.
Множественные Заголовочные Файлы (.h)
Стиль разбиения программы с одним заголовочным файлом наиболее пригоден в тех случаях, когда программа невелика и ее части не предполагается использовать отдельно. Поэтому то, что невозможно установить, какие описания зачем помещены в заголовочный файл, несущественно. Помочь могут комментарии. Другой способ — сделать так, чтобы каждая часть программы имела свой заголовочный файл, в котором определяются предоставляемые этой частью средства. Тогда каждый .c файл имеет соответствующий .h файл, и каждый .c файл включает свой собственный (специфицирующий то, что в нем задается) .h файл и, возможно, некоторые другие .h файлы (специфицирующие то, что ему нужно).