Заголовний файл
У програмуваннізаголовний файл(англ. header file ) абопідключається файл— файл, вміст якого автоматично додається препроцесором у вихідний текст там, де розташовується деяка директива ( в Паскалі, #include у Сі).
У мовах програмування Сі і C++ заголовні файли - основний спосіб підключити до програми типи даних, структури, прототипи функцій, типи, що перерахуються, і макроси, що використовуються в іншому модулі. За промовчанням використовується розширення.h; іноді для файлів заголовків мови C++ використовують розширення.hpp.
Щоб уникнути повторного включення одного й того ж коду, використовуються директиви #ifndef, #define, #endif.
Заголовний файл в загальному випадку може містити будь-які конструкції мови програмування, але на практиці виконуваний код (за винятком inline-функцій C++) в заголовні файли не поміщають. Наприклад, ідентифікатори, які повинні бути оголошені більш ніж в одному файлі, зручно описати в заголовному файлі, а потім підключати його при необхідності. Подібним чином працює модульність і в більшості асемблерів.
За традицією, що склалася, в заголовних файлах оголошують функції стандартної бібліотеки Сі і Сі ++.
В інших мовах (наприклад, Паскалі) застосовується розвинена система модулів. Але й у них заголовні файли мають певну цінність. Справа в тому, що два файли (основний та заголовковий) зливаються в одну одиницю трансляції, і тому заголовковий файл може містити директиви препроцесора, незакінчені синтаксичні конструкції.
Зміст
У сучасних мовах програмування програми складаються з модулів, що компілюються окремо. У зв'язку з цим виникає питання: як вказати, що підпрограма чи змінна Xвизначена в модулі Y? Для цього існує кілька рішень, у Сі застосовано таке.
В одній з одиниць компіляції (тобто з -файлі) описується функція, наприклад:
Щоб її можна було посилатися з інших одиниць компіляції, потрібно оголосити її з допомогою прототипу функції, тобто:
Списки ініціалізованих констант у заголовному файлі вибираються препроцесором для заміни їх значенням цих констант у файлі. Функції заголовного файлу, що включаються, обрамляються директивами макрозахисту препроцесора для уникнення їх дублювання в файлі, що включає (виникнення такої ситуації можливе при класовому або файловому успадкування):
Крім конструкції #ifndef - #endif іноді застосовується нестандартна #pragma once:
Альтернатива заголовним файлам - отримання інформації про оголошені типи, функції і т. д. безпосередньо з відкомпілюваного модуля. Так роблять мови Паскаль, Java та інші.
Переваги
Перевага заголовних файлів в першу чергу у спрощенні компілятора: без заголовних файлів компілятор і компонувальник виконують ту саму роботу, перевіряючи, чи є в модулі Y відкомпільована функція X .
Якщо модуль правильно написаний, за допомогою умовної компіляції можна вимкнути частину його функціональності. Наприклад, в даному випадку ми відмовляємося від компонування до програми величезної бібліотеки STL:
У випадку, якщо модуль поширюється вже відкомпільованим (бібліотека), файл заголовки буде одночасно документацією по користуванню модулем.
Якщо програміст виправив реалізацію функції в c-файлі, не зачепивши заголовка, це не викличе каскадної перекомпіляції всіх модулів, які використовують цей заголовок.
Заголовковий файл дозволяє задати те, що неможливовстановити за допомогою модулів — підстановки за допомогою #define, директиви компілятора, незакінчені синтаксичні конструкції…
Спрощується взаємодія між модулями, написаними різними мовами. Компілятору і компоновщику взагалі байдуже, написаний модуль, що викликається тією ж мовою або іншою. До того ж, різні мови можуть скомпілювати свої модулі в однакові об'єктні файли — у такому випадку виходить один компонувальник на кілька мов. Так само просто зробити бібліотеку, яка на вибір користувача включається в проект у вигляді CPP-файлів, зберігається заздалегідь відкомпільованою і прикомпоновується статично, або прикомпоновується як DLL.
Недоліки
Заголовні файли набагато повільніше - щоб відкомпілювати 10 c-файлів, до кожного з яких підключений довгий h-файл, компілятору доведеться пройти по заголовку 10 разів. Щоб упоратися з цією проблемою, у багатьох компіляторах використовують попередньо відкомпільовані заголовки.
Заголовні файли разом з деякими об'єктами мови C++ (константи, inline-функції, шаблони, static-змінні) утворюють великовагові конструкції.
Програміст повинен синхронно змінювати заголовки функцій у двох місцях. Якщо раптом він змінив c-файл, забувши зробити те ж саме з h-файлом, компонувальник видасть розпливчасте повідомлення про помилку без номера рядка. Особливо це помітно в C++, де та сама функція може мати різний набір аргументів, і перевірка лише на рівні компілятора не спрацьовує. Якщо програміст випадково залишить конструкцію в h-файлі незакінченою, помилка буде зовсім в іншому c-або h-файлі.
Проектам із мов сімейства Сі властиві складні схеми складання проекту. Адже (як мінімум у стандартному C++) треба включити в проект бібліотеку або у вигляді CPP-файлів, або ввідкомпілюваному вигляді. Навіть якщо (наприклад, Visual C++) для цього є директиви препроцесора, бібліотеку все одно доведеться зібрати.