Заголовочный файл. Программы для воспроизведения видеозаписи.264 и H.264 Открыть h

В языке Си исходные файлы бывают двух типов:

    заголовочные, или h-файлы;

    файлы реализации, или Cи-файлы.

Имена заголовочных файлов имеют расширение ".h". Имена файлов реализации имеют расширения ".c" и ".cpp".

Заголовочные файлы содержат только описания. Прежде всего, это прототипы функций. Прототип функции описывает имя функции, тип возвращаемого значения, число и типы ее аргументов. Сам текст функции в h-файле не содержится. Также в h-файлах описываются имена и типы внешних переменных, константы, новые типы, структуры и т.п. В общем, h-файлы содержат лишь интерфейсы , т.е. информацию, необходимую для использования программ, уже написанных другими программистами (или тем же программистом раньше). Заголовочные файлы лишь сообщают информацию о других программах. При трансляции заголовочных файлов, как правило, никакие объекты не создаются. Например, в заголовочном файле нельзя определить глобальную переменную. Строка описания

определяющая целочисленную переменную x, является ошибкой. Вместо этого следует использовать описание

означающее, что переменная x определена где-то в файле реализации (в каком - неизвестно). Слово extern (внешняя) лишь сообщает информацию о внешней переменной, но не определяет эту переменную.

    assert.h assert макрокоманду, которую Вы можете использовать, чтобы создать условия в ваших программах.

    ctype.h файл для включения содержит определения и прототипы для подпрограмм которые

классифицируют символы ASCII и подпрограммы, которые исполняют символьные преобразования:

setjmp, longjmp, isalnum, isalpha, iscntrl, isprint, ispunct, isspace, toint, tolower, _tolower

    float.h

определенные выполнением свойства чисел с плавающей запятой:

isdigit, isgraph, islower, isupper, isxdigit, toascii, toupper, _toupper

    limits.h файл для включения определяет явные константы, которые представляют

определенные пределы на значениях, сохраненных в различных типах данных.

    math.h файл для включения содержит прототипы и определения для всех подпрограмм для

исполнения математических вычислений с плавающей запятой.

    setjmp.h файл для включения определяет тип jmp_buf и моделирует setjmp

и longjmp подпрограммы.

    stdarg.h файл для включения определяет макросы, которые обращаются к параметрам в функциях

со списками параметров переменной длины.

    stddef.h файл для включения определяет offsetof макрокоманду, к которой Вы можете использовать

смещение членов структуры.

    stdio.h файл для включения содержит прототипы и определения для потокового ввода - вывода

подпрограммы. stdlib.h файл для включения содержит прототипы и определения для подпрограмм распределения памяти.

    string.h файл для включения содержит прототипы для следующей строки и буфера

подпрограммы манипуляции.

Файлы реализации , или Cи-файлы, содержат тексты функций и определения глобальных переменных. Говоря упрощенно, Си-файлы содержат сами программы, а h-файлы - лишь информацию о программах.

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

Файлы реализации могут подключать описания, содержащиеся в заголовочных файлах. Сами заголовочные файлы также могут использовать другие заголовочные файлы. Заголовочный файл подключается с помощью директивы препроцессора #include. Например, описания стандартых функций ввода-вывода включаются с помощью строки

#include

(stdio - от слов standard input/output). Имя h-файла записывается в угловых скобках, если этот h-файл является частью стандартной Си-библиотеки и расположен в одном из системных каталогов. Имена h-файлов, созданных самим программистом в рамках разрабатываемого проекта и расположенных в текущем каталоге, указываются в двойных кавычках, например,

#include "abcd.h"

Примеры с. файлов:

    calloc.c Распределяет память для массива элементов.

    free.c Выпускает память, распределенную сcalloc, malloc, илиrealloc.

    getkey.c Ждет символа, который будет получен от последовательного порта.

    init_mem.c Инициализирует пул памяти, используемый calloc, malloc, и подпрограммамиrealloc.

    malloc.c Распределяет блок памяти от памяти пула.

    putchar.c Передает символ, используя последовательный порт.

    realloc.c Изменяет размер предварительно распределенного блока памяти

CARM Компилятор генерирует множество файлов в течение трансляции. Каждый файл использует то же имя исходного файла . Однако, каждый имеет различное расширение.

    LST Файлы содержат отформатированный исходный текст наряду с любыми ошибками, обнаруженными компилятором. Листинг файлов может произвольно содержать символы используемые и сгенерированные ассемблерным кодом.

    OBJ Файлы - объектные модули, которые содержат перемещаемый объектный код. Объектные модули могут быть связаны с абсолютным объектным модулем.

    SRC Файлы - сгенерированные исходные файлы трансляции вашего исходного текста.


Майкл Барр

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

Один из таких навыков относится к созданию заголовочных файлов. Что нужно (или не нужно) размещать в заголовочном Си файле.h? Когда нужно создавать заголовочный файл? И почему?

На перечисленные вопросы у меня есть свой список ответов.

Создавайте один заголовочный файл.h для каждого “модуля” системы. Модуль может содержать один или несколько компилируемых файлов (например, .с или.asm), но он должен реализовывать только один аспект системы. Примерами хорошо подобранных модулей являются: драйвер для АЦП; коммуникационный протокол, такой как FTP; менеджер аварий, который ведет журнал ошибок и предупреждает о них пользователя.

Включайте в заголовочный файл.h все прототипы функций, которые составляют внешний интерфейс модуля. Например, заголовочный файл adc.h мог бы содержать прототипы функций adc_init(), adc_select_input(), adc_read().

Не включайте в заголовочный файл функции и макросы, которые предназначены для использования внутри модуля. Желательно скрыть этих внутренних “помощников”, если они не используются в других модулях. (Если ваш модуль состоит из нескольких компилируемых файлов, которые используют эти внутренние функции, тогда создайте отдельный заголовочный файл для этих целей.) Модуль А должен вызывать модуль B только через открытый интерфейс, определенный в заголовочном файле moduleb.h

Не включайте в заголовочный файл исполняемый код, а также объявления переменных. Но обратите внимание, что для встраиваемых (inline) функций придется сделать исключение.

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

Не раскрывайте внутренний формат специфических структур данных, используемых интерфейсными функциями модуля. Другими словами, в заголовочном файле не должно быть никаких struct{…}foo. Если у вас есть тип данных, который нужно передать в или из модуля, определите типы данных в заголовочном файле через typedef. Например, так “typedef struct foo moduleb_type”. Клиентские модули не должны знать внутренний формат структур.

Несмотря на то, что эти советы не являются специфичными для встраиваемого программного обеспечения, я надеюсь, что они окажутся для вас полезными.

.h ; иногда для заголовочных файлов языка C++ используют расширение .hpp . Чтобы избежать повторного включения одного и того же кода, используются директивы #ifndef, #define, #endif . Заголовочный файл в общем случае может содержать любые конструкции языка программирования, но на практике исполняемый код (за исключением inline-функций в C++) в заголовочные файлы не помещают. Например, идентификаторы, которые должны быть объявлены более чем в одном файле, удобно описать в заголовочном файле, а затем его подключать по мере надобности. Подобным же образом работает модульность и в большинстве ассемблеров .

По сложившейся традиции, в заголовочных файлах объявляют функции стандартной библиотеки Си и Си++.

В других языках (например, в Паскале) применяется развитая система модулей. Но и в них заголовочные файлы имеют определённую ценность. Дело в том, что два файла (основной и заголовочный) сливаются в одну единицу трансляции , и поэтому заголовочный файл может содержать директивы препроцессора, незаконченные синтаксические конструкции.

Назначение

В современных языках программирования программы составляются из модулей, компилируемых по отдельности. В связи с этим возникает вопрос: как указать, что подпрограмма или переменная X определена в модуле Y ? Для этого существует несколько решений, в Си применено такое.

В одной из единиц компиляции (то есть с -файле) описывается функция, например:

Int add(int a, int b) { return a + b; }

Чтобы на неё можно было ссылаться из других единиц компиляции, требуется объявить её при помощи прототипа функции , то есть:

Int add(int , int ) ; int triple(int x) { return add(x, add(x, x) ) ; }

Тем не менее, такое объявление требует, чтобы программист обеспечил объявление функции для add в двух местах - в файле, содержащем её выполнение, и в файле, в котором она используется. В случае изменения определения функции программист должен не забыть обновить все прототипы, использованные в программе.

Заголовочный файл является одним из решений этой проблемы. В заголовочном файле модуля объявляется каждая функция , объект и тип данных , являющиеся частью интерфейса вызова модуля - например, в этом случае заголовочный файл может содержать только объявление функции add . Каждый исходный файл, ссылающийся на функцию add , должен использовать директиву #include для подключения заголовочного файла:

/* 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 */

Кроме конструкции #ifndef - #endif иногда применяется нестандартная #pragma once :

/* File add.h */ #pragma once int add(int , int ) ;

Заголовочные файлы облегчают поддержку - при изменении определения должно быть обновлено лишь одно объявление (то, которое находится в заголовочном файле). К исходному файлу также можно подключать заголовочный файл, содержащий определение, используемые в исходниках. Это позволяет компилятору сверять, совпадает ли объявление в h -файле с определением в c -файле:

/* File add.c */ #include "add.h" int add(int a, int b) { return a + b; }

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

Сравнение с прямым получением заголовков из откомпилированного модуля

Альтернатива заголовочным файлам - получение информации об объявленных типах, функциях и т. д. напрямую из откомпилированного модуля. Так поступают языки Паскаль , Java и другие.

Преимущества

Преимущество заголовочных файлов в первую очередь в упрощении компилятора: без заголовочных файлов компилятор и компоновщик делают одну и ту же работу, проверяя, есть ли в модуле Y откомпилированная функция X .

Если модуль правильно написан, с помощью условной компиляции можно отключить часть его функциональности. Например, в данном случае мы отказываемся от прикомпоновывания к программе огромной библиотеки STL :

// unit.h #ifndef __UNIT_H__ #define __UNIT_H__ #ifndef UNIT_STL_UNUSED #include 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 ; }

В случае, если модуль распространяется уже откомпилированным, заголовочный файл будет одновременно документацией по пользованию модулем.

Если программист исправил реализацию функции в c -файле, не тронув заголовка, это не вызовет каскадной перекомпиляции всех модулей, которые используют данный заголовок.

Заголовочный файл позволяет задать то, что невозможно задать с помощью модулей - подстановки с помощью #define , директивы компилятора, незаконченные синтаксические конструкции…

Недостатки

Заголовочные файлы намного медленнее - чтобы откомпилировать 10 c -файлов, к каждому из которых подключён длинный h -файл, компилятору придётся пройти по заголовку 10 раз. Чтобы справиться с этой проблемой, во многих компиляторах используют предварительно откомпилированные заголовки .

Заголовочные файлы вместе с некоторыми объектами языка C++ (константы , inline -функции, шаблоны , static -переменные) образуют тяжеловесные конструкции.

Если вдруг программист изменил c -файл, забыв сделать то же с h -файлом, компоновщик выдаст расплывчатое сообщение об ошибке без номера строки. Особенно это заметно в C++ , где одна и та же функция может иметь разный набор аргументов , и проверка на уровне компилятора не срабатывает. Если программист случайно оставит конструкцию в h -файле незаконченной, ошибка будет совсем в другом c - или h -файле.

В некоторых языках (например, Java) вообще не требуется изменять код одновременно в двух местах.

См. также

  • Стандартная библиотека языка Си - описывает стандартные заголовочные файлы языка Си
  • Стандартная библиотека языка C++ - описывает стандартные заголовочные файлы языка Си++

Ссылки

Литература

  • Подбельский В. В. Глава 8. Препроцессорные средства // Язык Си++ / рец. Дадаев Ю. Г.. - 4. - М .: Финансы и статистика , 2003. - С. 263-280. - 560 с. - ISBN 5-279-02204-7 , УДК 004.438Си(075.8) ББК 32.973.26-018 1я173

Wikimedia Foundation . 2010 .

Подобного рода вопрос мне недавно задал один коллега, начинающий программировать на языке Си. И я подумал, что это хороший повод поделится своим пониманием данного вопроса. Потому, что даже опытные программисты не всегда имеют схожие точки зрения на этот счет.

Отчасти это дело вкуса, поэтому, кому интересно как это делаю я, добро пожаловать под кат.

Несмотря на то, что «вся правда» о h-файлах содержится в соответствующем разделе описания препроцессора gcc, позволю себе некоторые пояснения и иллюстрации.

Итак, если дословно, заголовочный файл (h-файл) - файл содержащий Си декларации и макро определения, предназначенные для использования в нескольких исходных файлах (с-файлах). Проиллюстрируем это.

Легко заметить, что функции 1 и 2, а так же макрос 2, упомянуты в обоих файлах. И, поскольку, включение заголовочных файлов приводит к таким же результатам, как и копирование содержимого в каждый си-файл, мы можем сделать следующее:

Таким образом мы просто выделили общую часть из двух файлов и поместили ее в заголовочный файл.
Но является ли заголовочный файл интерфейсом в данном случае?

  • Если нам нужно использовать функциональность, которую реализуют функции 1 и 2 где то еще, то Да
  • Если макрос 2, предназначен только для использования в файлах Unit1.c и Unit2.c, то ему не место в интерфейсном файле
Более того, действительно ли нам необходимо иметь два си-файла для реализации интерфейса, определенного в заголовочном файле? Или достаточно одного?
Ответ на этот вопрос зависит от деталей реализации интерфейсных функций и от их места реализации. Например, если сделать диаграммы более подробными, можно представить вариант, когда интерфейсные функции реализованы в разных файлах:


Такой вариант реализации приводит к высокой связности кода, низкой тестируемости и к сложности повторного использования таких модулей.
Для того, что бы не иметь таких трудностей, я всегда рассматриваю си-файл и заголовочный файл как один модуль. В котором,
  • заголовочный файл содержит только те декларации функций, типов, макросов, которые являются частью интерфейса данного модуля.
  • Си-файл, в свою очередь, должен содержать реализацию всех функций, декларированных в h- файле, а также приватные типы, макросы и функции, которые нужны для реализации интерфейса.
Таким образом, если бы мне довелось реализовывать код, которому соответствует диаграмма приведенная выше, я бы постарался, добиться следующего (окончания _с и _h в именах файлов добавлены по причине невозможности использовать точку в инструменте , которым я пользовался для создания диаграмм):


Из диаграммы видно, что на самом деле мы имеем дело с двумя независимыми модулями, у каждого из которых имеется свой интерфейс в виде заголовочного файла. Это дает возможность использовать только тот интерфейс, который действительно необходим в данном конкретном случае.Более того, эти модули могут быть протестированы независимо друг от друга.
Читатель, наверное, заметил, что макрос 2 из заголовочного файла снова вернулся в виде копии в оба си-файла. Конечно, это не очень удобно поддерживать. Но и делать данный макрос частью интерфейса не правильно.
В таких случаях, я предпочитаю делать отдельный заголовочный файл содержащий типы и макросы, необходимые нескольким си-файлам.

Надеюсь, мне удалось обозначить те сущности, которые нуждаются в том, что бы быть помещенными в заголовочные файлы. А так же, показать разницу между интерфейсам и файлами, содержащими декларации и макросы, необходимые нескольким си-файлам.

Спасибо за внимание к материалу.

Сегодня камеры наблюдения можно увидеть практически на каждом шагу. Возможно, вы также планируете установить одну или несколько камер у себя дома. Такие устройства работают с видеофайлами форматов.264 или H.264. Но как посмотреть видео и чем открыть файл рассмотрим в статье.

Различия и сходства форматов 264 и H.264

Формат.264 – это необработанные элементарные потоки видеофайлов H.264-ES (еще называют временным видео-файлом MPEG-4). В свою очередь H.264-ES является частью спецификации формата H.264. Старые модели видеорегистраторов записывают видео в формате.264. Такие видеофайлы не могут использоваться для прямого просмотра обычными проигрывателями и требуют обработки специальными программами.

Позволяет уменьшить видеозапись до минимального размера. После того, как видеозаписи проходят полное сжатие, качество видео и аудио по-прежнему остается на высоком уровне. С этим форматом работают камеры видеонаблюдения и видеорегистраторы нового образца. Файлы H.264 еще называются MPEG-4 Part 10 AVC/H.264. Несмотря на длинное и страшное название в сети очень легко найти проигрыватель файлов H.264.

Для открытия таких файлов необходимо воспользоваться одним из нижеперечисленных способов:

  • использовать специальные программы и утилиты;
  • выполнить конвертацию видеофайлов.

Открытие видео H.264

Практически все популярные программы и конвертеры работают с форматом H.264, Популярными являются:

  1. Light Alloy.

Работа с форматом.264

Давайте рассмотрим более подробно, чем открыть файл.264 с видеорегистратора или камеры наблюдения.

Специальные программы

Для открытия видео.264 станут полезными следующие программы:

Видеофайлы.264 можно объединить или разъединить. Как это сделать мы рассмотрим дальше.

Утилиты

Чтобы воспроизвести файл.264, необходимо поместить его в контейнерный формат, который сможет распознать любой медиа-проигрыватель. Для этой цели рекомендуем воспользоваться одной из следующих утилит:

  1. Demuxer – умеет создавать записи dsm или mpc. Стоит отметить, что файлы dsm можно воспроизвести только в этой утилите.
  2. MKVcleaver – с ее помощью вы сможете вырезать видео в.MKV.
  3. Mkvmerge – способна изменить, вырезать, объединить или разъединить видеофайлы. После обработки видео качество видео не ухудшается, а формат меняется на.MKV.
  4. Haali Muxer – может помочь в преобразовании, объединении или разъединить видеофайлов. После обработки видео ему присваивается формат.MKV.