Классификация ввода-вывода
1.6. Приложение II. Формат "заголовочных частей" (файлов "*.h") языков Си/C++
В "заголовочные файлы" программ на языке Си/C++ пишется следующая информация:
- 01. Текст с описанием назначения заголовочного файла;
- 02. Конструкция для предотвращения повторного использования файла;
- 03. Другие заголовочные файлы, содержащие константы и объявления функций, используемых в данном файле. При этом должно быть исключено повторное объявление одних и тех же модулей в заголовочных файлах;
- 04. Вставка необходимых прагма операторов (директив компилятору);
- 05. Определение констант и макроподстановок;
- 06. Объявление структур, объединений и перечисляемых типов;
- 07. Объявление глобальных переменных;
- 08. Объявление функций.
Рассмотрим эти конструкции поподробнее:
Пункт 01
Текст с описанием назначения заголовочного файла
Представляет собой следующий шаблон [1.50]
/********************************************************** * * Файл <имя файла>.H * * НАЗНАЧЕНИЕ: * * ЗАВИСИМОСТИ: * * Copyright (R) * **********************************************************/Листинг 1.50.
В нём обязательно нужно указать название файла, назначение констант, переменных, объявлений типов и функций, использованных в данном заголовочном файле. Это нужно сделать "коротко и ясно". Также желательно указать зависимости данного файла с другими заголовочными файлами, а также правообладателя программы (название организации, либо имя и псевдоним, и обязательно контактные данные). Это может потребоваться при внесении изменений в программу в целом и в этот заголовочный файл в-частности.
Пункт 02
Конструкция для предотвращения повторного использования файла
Представляет собой следующий шаблон [1.51]
#ifndef __"имя файла"_H #define __"имя файла"_H … #endif /* Конец заголовочного файла */Листинг 1.51.
Эта конструкция определяет переменную: "__"имя файла"_H". Именно использование этой переменной в пункте 03 (вернее, проверка на её существование) предотвращает повторную загрузку заголовочного файла из самого себя или другого заголовочного файла.
В конце описания заголовочного файла должно стоять подножие: #endif. Заметим, что использование этих конструкций и правила именования переменных является стандартным приёмом "обхода" такого рода проблем.
Пункт 03
Другие заголовочные файлы
Вставка других заголовочных файлов представляет собой следующий шаблон: [1.52]
/* Включение заголовочных файлов */ #ifndef __"имя файла1"_H #include ""имя файла1"".h #endif #ifndef __"имя файла2"_H #include <"имя файла2">.h #endif …Листинг 1.52.
Обратите внимание, что оператор вставки файла "#include" окружён "условными прагма операторами" "#ifndef" и "#endif". Их использование предотвращает повторную загрузку заголовочных файлов и, таким образом, предотвращает повторное определение или переопределение типов, констант и переменных, указанных в них.
Пункт 04
Вставка необходимых прагма операторов
Эти операторы вставляются в текст только по-необходимости, и часто их включения не требуется.
Пункт 05
Определение констант и макроподстановок
Сюда вставляются определения констант и макроподстановок, определённых через прагма оператор #define. Конечно, его использование может некоторыми авторами рассматриваться как "анахронизм". Однако оцените его удобство и универсальность!
Примечание: константы и макрофункции здесь следует набирать прописными буквами (хотя это не обязательно).
Определение представляет собой следующий шаблон:
/* Определение констант */ #define "ИМЯ_КОНСТАНТЫ" "значение"Листинг 1.53.
/* Определение макроподстановок */
#define "МАКРОФУНКЦИЯ"("ПАРАМЕТРЫ") "текст макроса"
Листинг
1.54.
Пункт 06
Объявление структур, объединений и перечисляемых типов
Объявления представляют собой следующий шаблон:
typedef struct "tagType"
{
"определение типа Type"
}"Type";
Листинг
1.55.
typedef union "tagType"
{
"определение типа Type"
}"Type";
Листинг
1.56.
typedef enum "tagType"
{
"определение типа Type"
}"Type";
Листинг
1.57.
Пункт 07
Объявление глобальных переменных
Иногда необходимо в файле задать переменные, которые будут использоваться сразу несколькими описанными функциями. Эти переменные можно объявить как "глобальные переменные", а не передавать в качестве параметров. Этим может создать более понятные и "компактные" программы. Эти объявления можно описать как в заголовочном файле, так и в начале файлов с описанием (определением) нужных функций.
Объявление представляет собой следующий шаблон:
/* Объявление глобальных переменных */ "тип" "имя"; … …;Листинг 1.58.
Пункт 08
Объявление функций
Перед использованием новых функций на языке Си необходимо прежде их объявить, что и происходит в конце заголовочного файла.
Объявление представляет собой следующий шаблон:
/* Объявление функций: */
"тип возвр. значения" "имя функции1"("имя и тип формальных параметров"…);
"тип возвр. значения" "имя функции2"("имя и тип формальных параметров"…);
…
Листинг
1.59.
Пример шаблона
/**********************************************************
*
* Файл <имя файла>.H
*
* НАЗНАЧЕНИЕ:
*
* ЗАВИСИМОСТИ:
*
* Copyright (R)
*
**********************************************************/
#ifndef __"имя файла"_H
#define __"имя файла"_H
/* Включение заголовочных файлов */
#ifndef __"имя файла1"_H
#include ""имя файла1"".h
#endif
#ifndef __"имя файла2"_H
#include <"имя файла2">.h
#endif
…
/* Указание директив компилятору: */
…
/* Определение констант */
#define "ИМЯ_КОНСТАНТЫ" "значение"
/* Определение макроподстановок */
#define "МАКРОФУНКЦИЯ"("ПАРАМЕТРЫ") "текст макроса"
/* Определение типов */
typedef enum tag"имя типа"
{
"константа 1";
…
"константа n";
}"имя типа";
typedef struct tag"имя типа"
{
"тип" "имя поля";
… …;
}"имя типа";
typedef union tag"имя типа"
{
"тип" "имя поля";
… …;
}"имя типа";
/* Объявление глобальных переменных */
"тип" "имя";
… …;
/* Объявление функций: */
"тип возвр. значения" "имя функции1"("имя и тип формальных параметров"…);
"тип возвр. значения" "имя функции2"("имя и тип формальных параметров"…);
…
#endif
/* Конец заголовочного файла */
Листинг
.