Заголовочный файлВ программировании заголовочный файл (англ. header file) или подключаемый файл — файл, содержимое которого автоматически добавляется препроцессором в исходный текст в том месте, где располагается некоторая директива ( В языках программирования Си и C++ заголовочные файлы — основной способ подключить к программе типы данных, структуры, прототипы функций, перечисляемые типы и макросы, используемые в другом модуле. По умолчанию используется расширение .h; иногда для заголовочных файлов языка C++ используют расширение .hpp. Чтобы избежать повторного включения одного и того же кода, используются директивы Заголовочный файл в общем случае может содержать любые конструкции языка программирования, но на практике исполняемый код (за исключением inline-функций в C++) в заголовочные файлы не помещают. Например, идентификаторы, которые должны быть объявлены более чем в одном файле, удобно описать в заголовочном файле, а затем его подключать по мере надобности. Подобным же образом работает модульность и в большинстве ассемблеров. По сложившейся традиции, в заголовочных файлах объявляют функции стандартной библиотеки Си и Си++. В других языках (например, в Паскале) применяется развитая система модулей. Но и в них заголовочные файлы имеют определённую ценность. Дело в том, что два файла (основной и заголовочный) сливаются в одну единицу трансляции, и поэтому заголовочный файл может содержать директивы препроцессора, незаконченные синтаксические конструкции. НазначениеВ современных языках программирования программы составляются из модулей, компилируемых по отдельности. В связи с этим возникает вопрос: как указать, что подпрограмма или переменная В одной из единиц компиляции (то есть int add(int a, int b)
{
return a + b;
}
Чтобы на неё можно было ссылаться из других единиц компиляции, требуется объявить её при помощи прототипа функции, то есть: int add(int, int);
int triple(int x)
{
return add(x, add(x, x));
}
Тем не менее, такое объявление требует, чтобы программист обеспечил объявление функции для Заголовочный файл является одним из решений этой проблемы. В заголовочном файле модуля объявляется каждая функция, объект и тип данных, являющиеся частью интерфейса вызова модуля — например, в этом случае заголовочный файл может содержать только объявление функции /* File triple.c */
#include "add.h"
int triple(int x)
{
return add(x, add(x, x));
}
Списки инициализированных констант в заголовочном файле выбираются препроцессором для замены их значением этих констант во включаемом файле. Включаемые функции заголовочного файла обрамляются директивами макрозащиты препроцессора для избежания их дублирования во включающем файле (возникновение такой ситуации возможно при классовом или файловом наследовании): /* File add.h */
#ifndef ADD_H
#define ADD_H
int add(int, int);
#endif /* ADD_H */
Кроме конструкции /* File add.h */
#pragma once
int add(int, int);
Заголовочные файлы облегчают поддержку — при изменении определения должно быть обновлено лишь одно объявление (то, которое находится в заголовочном файле). К исходному файлу также можно подключать заголовочный файл, содержащий определения, используемые в исходниках. Это позволяет компилятору сверять, совпадает ли объявление в /* File add.c */
#include "add.h"
int add(int a, int b)
{
return a + b;
}
Обычно заголовочные файлы применяются только для более чёткого определения интерфейса и обычно содержат комментарии, поясняющие способы использования компонентов, объявленных в файле. В приведённом примере использованные подпрограммы выделены в отдельные исходные файлы, которые должны компилироваться отдельно (исключением в языках C и C++ являются встраиваемые функции, которые зачастую включаются в заголовочный файл из-за того, что в большинстве случаев использования не получается правильно раскрыть встраиваемую функцию без обращений к их определению во время компиляции). Сравнение с прямым получением заголовков из откомпилированного модуляАльтернатива заголовочным файлам — получение информации об объявленных типах, функциях и т. д. напрямую из откомпилированного модуля. Так поступают языки Паскаль, Java и другие. ПреимуществаПреимущество заголовочных файлов в первую очередь в упрощении компилятора: без заголовочных файлов компилятор и компоновщик делают одну и ту же работу, проверяя, есть ли в модуле Если модуль правильно написан, с помощью условной компиляции можно отключить часть его функциональности. Например, в данном случае мы отказываемся от прикомпоновывания к программе огромной библиотеки STL: // unit.h
#ifndef __UNIT_H__
#define __UNIT_H__
#ifndef UNIT_STL_UNUSED
#include <iostream>
void dump(std::ostream& os);
void dump() { dump(std::cout); }
#endif
void run();
#endif
// main.cpp
#define UNIT_STL_UNUSED
#include "unit.h"
int main()
{
run();
return 0;
}
В случае, если модуль распространяется уже откомпилированным (библиотека), заголовочный файл будет одновременно документацией по пользованию модулем. Если программист исправил реализацию функции в Заголовочный файл позволяет задать то, что невозможно задать с помощью модулей — подстановки с помощью Упрощается взаимодействие между модулями, написанными на разных языках. Компилятору и компоновщику вообще безразлично, написан вызываемый модуль на том же языке или на другом. К тому же разные языки могут скомпилировать свои модули в одинаковые объектные файлы — в таком случае получается один компоновщик на несколько языков. Точно так же просто сделать библиотеку, которая по выбору пользователя включается в проект в виде CPP-файлов, хранится заранее откомпилированной и прикомпоновывается статически, или прикомпоновывается как DLL. НедостаткиЗаголовочные файлы намного медленнее — чтобы откомпилировать 10 Заголовочные файлы вместе с некоторыми объектами языка C++ (константы, Программист должен синхронно менять заголовки функций в двух местах. Если вдруг он изменил Проектам из языков семейства Си свойственны сложные схемы сборки проекта. Ведь (как минимум в стандартном C++) надо включить в проект библиотеку — либо в виде CPP-файлов, либо в откомпилированном виде. Даже если (например, в Visual C++) для этого есть директивы препроцессора, библиотеку всё равно придётся собрать. См. также
Ссылки
Литература
|