Заголовочные файлы
Типы во всех описаниях одного и того же объекта должны быть согласованными. Один из способов достижения этого, мог бы состоять в обеспечении средств проверки типов в компоновщике, но большинство компоновщиков - образца 1950-х, и их нельзя изменить по практическим соображениям. Другой подход состоит в согласовании исходного текста, передаваемого компилятору, или в наличии данных, позволяющих компилятору обнаружить несогласованности. Один несовершенный, но простой способ достичь согласованности состоит во включении заголовочных файлов, содержащих интерфейсную информацию, в исходные файлы, в которых содержится исполняемый код и/или определения данных.
Механизм включения с помощью #include - это чрезвычайно простое средство обработки текста для сборки фрагментов исходной программы в одну единицу (файл) для ее компиляции. Директива
#include "to_be_included"
замещает строку, в которой встретилось #include, содержимым файла "to_be_included". Его содержимым должен быть исходный текст на C++, поскольку дальше его будет читать компилятор. Включения обрабатывается отдельной программой, называемой C препроцессором, которую компилятор вызывает для преобразования исходного файла, поступившего от программиста, в файл без директив включения перед тем, как начать собственно компиляцию.
Для включения файлов из стандартной директории включения вместо кавычек используются угловые скобки. Например:
#include <myheader.h> // из стандартной директории включения #include "myheader.h" // из текущей директории
Использование < > имеет то преимущество, что в программу фактическое имя директории включения не встраивается (как правило, сначала просматривается /usr/include/CC, а потом usr/include). К сожалению, пробелы внутри скобок в директиве include существенны:
#include < stream.h > // не найдет
Может показаться, что перекомпилировать файл заново каждый раз, когда он куда-либо включается, расточительно, но время компиляции такого файла обычно слабо отличается от времени, которое необходимо для чтения его некоторой заранее откомпилированной формы. Причина в том, что текст программы является довольно компактным представлением программы, и в том, что включаемые файлы обычно содержат только описания и не содержат программ, требующих от компилятора значительного анализа.
Следующее эмпирическое правило относительно того, что следует, а что не следует помещать в заголовочные файлы, является не требованием языка, а просто предложением по разумному использованию аппарата #include.
В заголовочном файле могут содержаться:
Определения типов |
struct point { int x, y; } |
Описания функций |
extern int strlen(const char*); |
Определения inline-функций |
inline char get() { return *p++; } |
Описания данных |
extern int a; |
Определения констант |
const float pi = 3.141593 |
Перечисления |
enum bool { false, true }; |
Директивы include |
#include |
Определения макросов |
#define Case break;case |
Комментарии |
/* проверка на конец файла */ |
но никогда
Определения обычных функций |
char get() { return *p++; } |
Определения данных |
int a; |
Определения сложных константных объектов |
const tbl[] = { /* ... */ } |
В среде С принято, что заголовочные файлы имеют суффикс (расширение) .h. Файлы, содержащие определение данных или функций, должны иметь суффикс .c. Такие файлы часто называют, соответственно, ".h файлы" и ".c файлы".
