Vytváření hlavičkových souborů v jazyce C. Přípona souboru H

Podobnou otázku mi nedávno položil kolega, který začíná programovat v C. A myslel jsem si, že je to dobrý důvod, abych se podělil o své chápání této problematiky. Protože ani zkušení programátoři nemají vždy na tuto věc stejný úhel pohledu.

To je částečně věc vkusu, takže kdo by se zajímal o to, jak to dělám, vítejte u kočky.

Navzdory skutečnosti, že „celá pravda“ o souborech h je obsažena v odpovídající části popisu preprocesoru gcc, dovolím si několik vysvětlení a ilustrací.

Takže doslova soubor záhlaví (soubor h) je soubor obsahující deklarace C a definice maker určené pro použití v několika zdrojových souborech (soubory c). Ukažme si to.

Je snadné vidět, že funkce 1 a 2 i makro 2 jsou zmíněny v obou souborech. A protože zahrnutí hlavičkových souborů vytváří stejné výsledky jako kopírování obsahu do každého souboru C, můžeme provést následující:

Jednoduše jsme tedy vybrali společnou část ze dvou souborů a umístili ji do hlavičkového souboru.
Je ale soubor záhlaví v tomto případě rozhraní?

  • Pokud potřebujeme použít funkce, které funkce 1 a 2 implementují jinde, pak Ano
  • Pokud je makro 2 určeno pouze pro použití v souborech Unit1.c a Unit2.c, nemá v souboru rozhraní žádné místo
Kromě toho skutečně potřebujeme mít dva soubory C k implementaci rozhraní definovaného v hlavičkovém souboru? Nebo je dost?
Odpověď na tuto otázku závisí na implementačních detailech funkcí rozhraní a na tom, kde jsou implementovány. Například pokud uděláte diagramy podrobnější, můžete si představit variantu, když jsou funkce rozhraní implementovány v různých souborech:


Tato implementace vede k vysoké soudržnosti kódu, nízké testovatelnosti a obtížnému opětovnému použití těchto modulů.
Abych neměl takové potíže, vždy považuji soubor C a soubor záhlaví za jeden modul. Ve kterém,
  • soubor záhlaví obsahuje pouze ty deklarace funkcí, typů, maker, které jsou součástí rozhraní tohoto modulu.
  • Soubor C zase musí obsahovat implementaci všech funkcí deklarovaných v souboru h, stejně jako soukromé typy, makra a funkce, které jsou potřebné k implementaci rozhraní.
Pokud jsem tedy náhodou implementoval kód, který odpovídá výše uvedenému diagramu, pokusil bych se dosáhnout následujícího (konce _с a _h v názvech souborů jsou přidány kvůli neschopnosti použít období v nástroji, který jsem použil k vytvoření diagramů):


Diagram ukazuje, že ve skutečnosti máme co do činění se dvěma nezávislými moduly, z nichž každý má své vlastní rozhraní ve formě hlavičkového souboru. Díky tomu je možné použít pouze rozhraní, které je v tomto konkrétním případě skutečně nutné, navíc lze tyto moduly testovat nezávisle na sobě.
Čtenář si pravděpodobně všiml, že makro 2 ze souboru záhlaví se znovu vrátilo jako kopie v obou souborech C. To samozřejmě není příliš výhodné udržovat. Ale ani to, že je toto makro součástí rozhraní, není správné.
V takových případech dávám přednost vytvoření samostatného souboru záhlaví obsahujícího typy a makra potřebné pro více souborů C.

Doufejme, že se mi podařilo identifikovat ty entity, které je třeba umístit do hlavičkových souborů. A také ukázat rozdíl mezi rozhraními a soubory obsahujícími deklarace a makra požadovaná několika soubory C.

Děkuji vám za pozornost materiálu.

V jazyce C jsou zdrojové soubory dvou typů:

    záhlaví nebo h-soubory;

    implementační soubory nebo soubory C.

Názvy hlavičkových souborů mají příponu „.h“. Názvy implementačních souborů mají příponu „.c“ a „.cpp“.

Soubory záhlaví obsahovat pouze popisy. Nejprve se jedná o funkční prototypy. Prototyp funkce popisuje název funkce, návratový typ, počet a typy jejích argumentů. Samotný text funkce není obsažen v souboru h. Soubory h také popisují názvy a typy externích proměnných, konstanty, nové typy, struktury atd. Soubory h obecně obsahují pouze rozhraní, tj. informace nezbytné k použití programů již napsaných jinými programátory (nebo stejným programátorem dříve). Soubory záhlaví poskytují pouze informace o jiných programech. Při překladu hlavičkových souborů se zpravidla nevytvářejí žádné objekty. Například v hlavičkovém souboru nemůžete definovat globální proměnná. Popisný řádek

definování celočíselné proměnné x je chyba. Místo toho by měl být použit popis

což znamená, že proměnná x je definována někde v implementačním souboru (což není známo). Pouze slovo externí (externí) sděluje informace o externí proměnné, ale tuto proměnnou nedefinuje.

    tvrdit.hassert je makro, které můžete použít k vytvoření podmínek ve vašich programech.

    ctype.h soubor, který chcete zahrnout, obsahuje definice a prototypy rutin, které

klasifikuje znaky a rutiny ASCII, které provádějí převody znaků:

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

    float.h

definováno provedením vlastností čísel s plovoucí desetinnou čárkou:

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

    limity.h soubor, který chcete zahrnout, definuje explicitní konstanty, které představují

konkrétní limity hodnot uložených v různých datových typech.

    matematika soubor zahrnutí obsahuje prototypy a definice všech rutin pro

provádění matematických výpočtů s plovoucí desetinnou čárkou.

    setjmp.h zahrnutý soubor definuje typ jmp_buf a simuluje setjmp

a longjmp podprogramy.

    stdarg.h soubor, který chcete zahrnout, definuje makra, která odkazují na parametry ve funkcích

se seznamy parametrů s proměnnou délkou.

    stddef.h definovaný soubor kompenzace makro, které můžete použít

offset členů konstrukce.

    stdio.h soubor, který chcete zahrnout, obsahuje prototypy a definice pro streamování I / O

podprogramy. stdlib.h soubor zahrnutí obsahuje prototypy a definice rutin přidělování paměti.

    řetězec.h soubor, který chcete zahrnout, obsahuje prototypy pro další řádek a vyrovnávací paměť

manipulační rutiny.

Implementační souborySoubory C nebo C obsahují funkční texty a definice globálních proměnných. Jednoduše řečeno, soubory C obsahují samotné programy, zatímco soubory h obsahují pouze informace o těchto programech.

Prezentace zdrojových textů ve formě hlavičkových souborů a implementačních souborů je nezbytná pro vytvoření velkých projektů s modulární strukturou. Soubory záhlaví se používají k přenosu informací mezi moduly. Soubory implementace jsou samostatné moduly, které se vyvíjejí a překládají nezávisle na sobě a kombinují se za účelem vytvoření spustitelného programu.

Soubory implementace mohou zahrnovat popisy obsažené v hlavičkových souborech. Samotné soubory záhlaví mohou také používat jiné soubory záhlaví. Soubor záhlaví je zahrnut pomocí direktivy preprocesoru #include. Například řádek obsahuje popis standardních I / O funkcí

#zahrnout

(stdio - ze slov standardní vstup / výstup). Název souboru h je zapsán v lomených závorkách, pokud je tento soubor h součástí standardní knihovny C a je umístěn v jednom ze systémových adresářů. Názvy souborů h vytvořené samotným programátorem v rámci vyvíjeného projektu a umístěné v aktuálním adresáři jsou uvedeny v uvozovkách, například

#include "abcd.h"

Příklady s. soubory:

    calloc.c Přiděluje paměť řadě prvků.

    free.c Uvolněte paměť přidělenou calloc, malloc nebo realloc.

    getkey.c Čeká na přijetí znaku ze sériového portu.

    init_mem.c Inicializuje paměťovou oblast používanou rutinami calloc, malloc a realloc.

    malloc.c Přiděluje blok paměti z paměti fondu.

    putchar.c Odešle znak pomocí sériového portu.

    realloc.c Změní velikost předem přiděleného bloku paměti

CARM Překladač během překladu generuje mnoho souborů. Každý soubor používá to samé název zdrojového souboru ... Každý však má jiné rozšíření.

    Soubory LST obsahují formátovaný zdrojový kód spolu s chybami nalezenými kompilátorem. Seznam souborů může libovolně obsahovat symboly používané a generované kódem sestavení.

    Soubory OBJ jsou objektové moduly, které obsahují přemístitelný objektový kód. Moduly objektů lze propojit s absolutním modulem objektů.

    Soubory SRC jsou generované zdrojové soubory překladu zdrojového textu.

Dnes lze bezpečnostní kamery vidět téměř na každém kroku. Můžete také plánovat instalaci jedné nebo více kamer ve vaší domácnosti. Taková zařízení fungují s video soubory ve formátu .264 nebo H.264. Ale jak sledovat video a jak otevřít soubor, bude pojednáno v článku.

Rozdíly a podobnosti mezi formáty 264 a H.264

Formát.264 Jsou nezpracované základní toky video souborů H.264-ES (nazývané také dočasný video soubor MPEG-4). H.264-ES je zase součástí specifikace formátu H.264. Starší videorekordéry nahrávají video ve formátu .64. Takové video soubory nelze použít pro přímé prohlížení běžnými přehrávači a vyžadují zpracování speciálními programy.

Zmenší video na minimální velikost. Po úplné komprimaci videí je kvalita videa a zvuku stále vysoká. S tímto formátem pracují CCTV kamery a videorekordéry nového typu. Soubory H.264 se také nazývají MPEG-4 část 10 AVC / H.264. Přes dlouhý a děsivý název je velmi snadné najít přehrávač souborů H.264 na internetu.

Chcete-li takové soubory otevřít, musíte použít jednu z následujících metod:

  • používat speciální programy a nástroje;
  • převádět video soubory.

Otevírá se video H.264

Téměř všechny populární programy a převaděče pracují s formátem H.264. Populární jsou:

  1. Lehká slitina.

Práce s formátem.264

Podívejme se blíže na to, jak otevřít soubor .264 z DVR nebo kamery.

Speciální programy

K otevření videa.264 budou užitečné následující programy:

.264 video soubory mohou být sloučeny nebo odděleny. Zvažujeme, jak to udělat dále.

Utility

Chcete-li přehrát soubor .264, musíte jej umístit do formátu kontejneru, který dokáže rozpoznat jakýkoli přehrávač médií. Za tímto účelem doporučujeme použít jeden z následujících nástrojů:

  1. Demuxer - může vytvářet dsm nebo mpc záznamy. Stojí za zmínku, že soubory dsm lze přehrávat pouze v tomto nástroji.
  2. MKVcleaver - s jeho pomocí můžete zkrátit video na .MKV.
  3. Mkvmerge je schopen upravit, vyjmout, sloučit nebo sloučit video soubory. Po zpracování videa se kvalita videa nezhorší, ale formát se změní na .MKV.
  4. Haali Muxer - může pomoci při převodu, sloučení nebo rozdělení video souborů. Po zpracování videa je mu přiřazen formát .MKV.
.h; někdy příponu používají soubory záhlaví C ++ .hpp... Abyste se vyhnuli opětovnému zahrnutí stejného kódu, použijte direktivy #ifndef, #define, #endif. Obecně může soubor záhlaví obsahovat libovolné konstrukce programovacího jazyka, ale v praxi se spustitelný kód (s výjimkou vložených funkcí v C ++) neumisťuje do souborů záhlaví. Například identifikátory, které musí být deklarovány ve více než jednom souboru, jsou pohodlně popsány v hlavičkovém souboru a poté podle potřeby zahrnuty. Modularita funguje stejným způsobem ve většině asemblerů.

Tradičně jsou funkce standardních knihoven C a C ++ deklarovány v hlavičkových souborech.

Jiné jazyky (například Pascal) používají pokročilý systém modulů. Ale v nich mají hlavičkové soubory určitou hodnotu. Faktem je, že dva soubory (hlavní a záhlaví) jsou sloučeny do jedné překladové jednotky, a proto soubor záhlaví může obsahovat směrnice preprocesoru, neúplné konstrukce syntaxe.

Jmenování

V moderních programovacích jazycích jsou programy složeny z modulů, které jsou kompilovány samostatně. To vyvolává otázku: jak označit, že v modulu Y je definován podprogram nebo proměnná X? Existuje několik řešení, v C se to používá.

Jedna z kompilačních jednotek (tj. S -souborem) popisuje funkci, například:

Int add (int a, int b) (návrat a + b;)

Chcete-li odkazovat z jiných kompilačních jednotek, musíte jej deklarovat pomocí prototypu funkce, tj .:

Int add (int, int); int triple (int x) (návrat add (x, add (x, x));)

Taková deklarace však vyžaduje, aby programátor poskytl deklaraci funkce pro přidání na dvou místech - v souboru obsahujícím jeho provedení a v souboru, ve kterém je použit. Pokud se definice funkce změní, programátor musí pamatovat na aktualizaci všech prototypů použitých v programu.

Jedním z řešení tohoto problému je soubor záhlaví. Soubor záhlaví modulu deklaruje každou funkci, objekt a datový typ, jehož je součástí rozhraní pro volání modul - například v tomto případě může soubor záhlaví obsahovat pouze deklaraci funkce přidání. Každý zdrojový soubor, který odkazuje na funkci přidání, musí použít direktivu #include k zahrnutí souboru záhlaví:

/ * Soubor triple.c * / #include "add.h" int triple (int x) (návrat add (x, add (x, x));)

Seznamy inicializovaných konstant v souboru záhlaví jsou vybrány preprocesorem, který je nahradí hodnotou těchto konstant v souboru zahrnutí. Zahrnuté funkce souboru záhlaví jsou orámovány direktivami ochrany makro před prepracováním, aby se zabránilo jejich duplikaci v souboru zahrnutí (tato situace je možná u třídy nebo dědičnosti souborů):

/ * File add.h * / #ifndef ADD_H #define ADD_H int add (int, int); #endif / * ADD_H * /

Kromě konstrukce #ifndef - #endif se někdy používá nestandardní #pragma once:

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

Soubory záhlaví usnadňují údržbu - při změně definice je třeba aktualizovat pouze jednu deklaraci (deklaraci v souboru záhlaví). Zdrojový soubor může také obsahovat záhlaví obsahující definici použitou ve zdroji. To umožňuje kompilátoru zkontrolovat, zda se deklarace v souboru h shoduje s definicí v souboru c:

/ * Soubor add.c * / #include "add.h" int add (int a, int b) (návrat a + b;)

Soubory záhlaví se obvykle používají pouze k jasnější definici rozhraní a obvykle obsahují komentáře vysvětlující, jak používat komponenty deklarované v souboru. Ve výše uvedeném příkladu jsou použité podprogramy rozděleny do samostatných zdrojových souborů, které musí být kompilovány samostatně (výjimkou v C a C ++ jsou vložené funkce, které jsou často zahrnuty v hlavičkovém souboru, protože ve většině případů použití je nemožné správně rozšířit vloženou funkci bez volání k jejich definici v době kompilace).

Porovnání s přímým získáním záhlaví z kompilovaného modulu

Alternativou k hlavičkovým souborům je získání informací o deklarovaných typech, funkcích atd. Přímo z kompilovaného modulu. To dělají Pascal, Java a další.

Výhody

Výhodou hlavičkových souborů je především zjednodušení kompilátoru: bez hlavičkových souborů dělají kompilátor a linker stejnou práci a kontrolují, zda má modul Y kompilovanou funkci X.

Pokud je modul napsán správně, lze pomocí podmíněné kompilace zakázat některé jeho funkce. Například v tomto případě odmítáme propojit obrovskou knihovnu STL s programem:

// unit.h #ifndef __UNIT_H__ #define __UNIT_H__ #ifndef UNIT_STL_UNUSED #include výpis prázdnoty (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;)

Pokud je modul distribuován již zkompilovaný, bude soubor záhlaví zároveň dokumentací pro použití modulu.

Pokud programátor opraví implementaci funkce v souboru c bez dotyku záhlaví, nezpůsobí to kaskádovou rekompilaci všech modulů, které tuto záhlaví používají.

Soubor záhlaví umožňuje určit věci, které nelze nastavit pomocí modulů - substituce pomocí #define, direktivy kompilátoru, neúplná syntaxe ...

nevýhody

Soubory záhlaví jsou mnohem pomalejší - pro kompilaci souborů 10 c, každý s připojeným dlouhým souborem h, bude muset kompilátor 10krát projít záhlaví. K řešení tohoto problému používá mnoho překladačů předkompilované záhlaví.

Soubory záhlaví spolu s některými objekty jazyka C ++ (konstanty, vložené funkce, šablony, statické proměnné) tvoří těžké konstrukce.

Pokud programátor náhle změnil soubor c a zapomněl udělat totéž s souborem h, linker vydá vágní chybovou zprávu bez čísla řádku. To je zvláště patrné v C ++, kde stejná funkce může mít jinou sadu argumentů a kontrola na úrovni kompilátoru nefunguje. Pokud programátor omylem ponechá nedokončenou konstrukci v souboru h, bude chyba v úplně jiném souboru c nebo h.

V některých jazycích (například Java) nemusíte měnit kód na dvou místech najednou.

viz také

  • C Standard Library - popisuje standardní soubory záhlaví C.
  • C ++ Standard Library - popisuje standardní hlavičkové soubory C ++

Odkazy

Literatura

  • Podbelský V.V. Kapitola 8. Zařízení pro předběžné zpracování // C ++ / rec. Dadaev Yu. G. - 4. - M.: Finance and statistics, 2003. - S. 263-280. - 560 s. - ISBN 5-279-02204-7, UDC 004,438Ci (075,8) BBK 32,973,26-018 1я173

Wikimedia Foundation. 2010.