Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа 4new.rtf
Скачиваний:
4
Добавлен:
09.11.2019
Размер:
282.77 Кб
Скачать

Заголовочные (включаемые) файлы

Типы во всех описаниях одного и того же объекта должны быть согласованными. Один из способов это достичь состоит в обеспечении того, что исходный текст, как он передается на рассмотрение компилятору, или согласован, или содержит информацию, которая позволяет компилятору обнаружить несогласованности. Один несовершенный, но простой способ достичь согласованности состоит во включении заголовочных файлов, содержащих интерфейсную информацию, в исходные файлы, в которых содержится исполняемый код и/или определения данных.

Механизм включения с помощью #include - это чрезвычайно простое средство обработки текста для сборки кусков исходной программы в одну единицу (файл) для ее компиляции. Директива

#include "to_be_included"

замещает строку, в которой встретилось #include, содержимым файла "to_be_included". Его содержимым должен быть исходный текст на С++, поскольку дальше его будет читать компилятор. Часто включение обрабатывается отдельной программой, называемой C препроцессором, которую команда C вызывает для преобразования исходного файла, который дал программист, в файл без директив включения перед тем, как начать собственно компиляцию. В другом варианте эти директивы обрабатывает интерфейсная система компилятора по мере того, как они встречаются в исходном тексте. Для включения файлов из стандартной директории включения вместо кавычек используются угловые скобки < и >.

Например:

#include <stream.h> // из стандартной директории включения

#define "myheader.h" // из текущей директории

Использование <> имеет то преимущество, что в программу фактическое имя директории включения не встраивается (как правило, сначала просматривается include). К сожалению, пробелы в директиве include существенны:

#include < stream.h > // не найдет <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 <signal.h>

 Определения макросов #define case break;case

 Комментарии /* проверка на конец файла */

но никогда

 Определения обычных функций char get() { return *p++; }

 Определения данных int a;

 Определения сложных константных объектов const tbl[] = { /*... */ }

Принято, что заголовочные файлы имеют суффикс (расширение) .h. Файлы, содержащие определение данных или функций, должны иметь суффикс .c. Такие файлы часто называют, соответственно, ".h файлы" и ".c файлы". Следует заметить, что в С++ макросы гораздо менее полезны, чем в C, поскольку С++ имеет такие языковые конструкции, как const для определения констант и inline для исключения расходов на вызов функции.

Причина того, почему в заголовочных файлах допускается определение простых констант, но не допускается определение сложных константных объектов, прагматическая. В принципе, сложность тут только в том, чтобы сделать допустимым дублирование определений переменных (даже определения функций можно было бы дублировать). Однако для компоновщиков старого образца слишком трудно проверять тождественность нетривиальных констант и убирать ненужные повторы. Кроме того, простые случаи гораздо более обиходны и потому более важны для генерации хорошего кода.