En programación, un archivo de encabezado ( en inglés header file ) o un archivo incluido es un archivo cuyo contenido es agregado automáticamente por el preprocesador al texto fuente en el lugar donde se encuentra alguna directiva ( {$I file.inc}en Pascal , #include <file.h>en C).
En los lenguajes de programación C y C++ , los archivos de encabezado son la forma principal de incluir tipos de datos , estructuras, prototipos de funciones , tipos enumerados y macros utilizados en otro módulo en un programa. La extensión predeterminada es .h ; a veces , la extensión .hpp se usa para los archivos de encabezado de C++ .
Para evitar la reinclusión del mismo código, se utilizan directivas #ifndef, #define, #endif.
El archivo de encabezado generalmente puede contener cualquier construcción de lenguaje de programación , pero en la práctica, el código ejecutable (con la excepción de las funciones en línea en C++ ) no se coloca en los archivos de encabezado. Por ejemplo, los identificadores que deben declararse en más de un archivo pueden describirse convenientemente en un archivo de encabezado y luego incluirse según sea necesario. La modularidad funciona de la misma manera en la mayoría de los ensambladores .
Tradicionalmente, los archivos de encabezado declaran funciones de biblioteca estándar de C y C++ .
En otros lenguajes (por ejemplo, en Pascal ), se utiliza un sistema de módulos desarrollado. Pero incluso en ellos, los archivos de encabezado tienen un cierto valor. El hecho es que dos archivos (principal y de encabezado) se fusionan en una unidad de traducción y, por lo tanto, el archivo de encabezado puede contener directivas de preprocesador , construcciones sintácticas sin terminar.
En los lenguajes de programación modernos, los programas se componen de módulos que se compilan por separado. Al respecto, surge la pregunta: ¿cómo indicar que una subrutina o una variable X está definida en un módulo Y? Hay varias soluciones para esto, en C se aplica.
En una de las unidades de compilación (es decir, с-archivo) se describe una función, por ejemplo:
suma int ( int a , int b ) { devuelve a + b ; }Para poder hacer referencia a él desde otras unidades de compilación, se requiere declararlo usando una función prototipo , es decir:
suma int ( int , int ); int triple ( int x ) { return sumar ( x , sumar ( x , x )); }Sin embargo, dicha declaración requiere que el programador proporcione una declaración de la función adden dos lugares: en el archivo que contiene su implementación y en el archivo en el que se usa. Si la definición de una función cambia, el programador debe recordar actualizar todos los prototipos utilizados en el programa.
El archivo de encabezado es una solución a este problema. El archivo de encabezado de un módulo declara cada función , objeto y tipo de datos que forma parte de la interfaz de invocación del módulo; por ejemplo, en este caso, el archivo de encabezado solo puede contener una declaración de función add. Cada archivo fuente que hace referencia a una función adddebe usar una directiva #includepara incluir un archivo de encabezado:
/* Archivo triple.c */ #include "añadir.h" int triple ( int x ) { return sumar ( x , sumar ( x , x )); }El preprocesador elige las listas de constantes inicializadas en el archivo de encabezado para reemplazarlas por el valor de esas constantes en el archivo incluido. Las funciones del archivo de encabezado incluido están enmarcadas por directivas de macroprotección del preprocesador para evitar su duplicación en el archivo incluido (tal situación puede ocurrir con la herencia de clase o archivo ):
/* Archivo add.h */ #ifndef ADD_H #define ADD_H int add ( int , int ); #endif /* ADD_H */Además del diseño #ifndef - #endif, a veces se usa uno no estándar #pragma once:
/* Archivo add.h */ #pragma una vez suma int ( int , int );Los archivos de encabezado facilitan el mantenimiento: cuando cambia una definición, solo se debe actualizar una declaración (la del archivo de encabezado) . También puede incluir un archivo de encabezado que contenga las definiciones utilizadas en los archivos de origen en el archivo de origen. Esto permite que el compilador verifique si la declaración en el harchivo coincide con la definición en el carchivo:
/* Archivo add.c */ #include "añadir.h" suma int ( int a , int b ) { devuelve a + b ; }Por lo general, los archivos de encabezado se usan solo para definir la interfaz con mayor claridad y, por lo general, contienen comentarios que explican cómo se pueden usar los componentes declarados en el archivo. En el ejemplo anterior, las subrutinas utilizadas se separan en archivos fuente separados que deben compilarse por separado (una excepción en los lenguajes C y C++ son las funciones en línea , que a menudo se incluyen en el archivo de encabezado debido al hecho de que en la mayoría de los casos casos, no es posible expandir correctamente la función en línea sin llamadas a su definición en tiempo de compilación ).
Una alternativa a los archivos de encabezado es obtener información sobre tipos declarados, funciones, etc. directamente desde el módulo compilado. Pascal , Java y otros hacen esto .
El beneficio de los archivos de encabezado es principalmente simplificar el compilador: sin archivos de encabezado , el compilador y el enlazador hacen el mismo trabajo de verificar si un módulo contiene una Yfunción compilada X.
Si un módulo está escrito correctamente, la compilación condicional puede deshabilitar algunas de sus funciones. Por ejemplo, en este caso, nos negamos a vincular una gran biblioteca STL al programa :
// unidad.h #ifndef __UNIT_H__ #define __UNIT_H__ #ifndef UNIT_STL_UNUSED #incluir < iostream> volcado vacío ( std :: ostream & os ); volcado vacío () { volcado ( std :: cout ); } #terminara si ejecución nula (); #terminara si // principal.cpp #define UNIT_STL_UNUSED #incluye "unidad.h" int principal () { ejecutar (); devolver 0 ; }Si el módulo se distribuye ya compilado (biblioteca), el archivo de cabecera será al mismo tiempo documentación sobre el uso del módulo.
Si el programador corrige la implementación de una función en un carchivo sin tocar el encabezado, esto no provocará una recompilación en cascada de todos los módulos que usan ese encabezado.
El archivo de encabezado le permite especificar algo que no se puede especificar usando módulos: sustituciones con #define, directivas del compilador , construcciones sintácticas sin terminar...
Simplifica la interacción entre módulos escritos en diferentes idiomas. Al compilador y al enlazador no les importa en absoluto si el módulo llamado está escrito en el mismo idioma o en otro. Además, diferentes idiomas pueden compilar sus módulos en los mismos archivos de objetos; en este caso, obtiene un enlazador para varios idiomas. Del mismo modo, es fácil crear una biblioteca que el usuario elija incluir en un proyecto como archivos CPP, almacenados precompilados y vinculados estáticamente o vinculados como DLL .
Los archivos de encabezado son mucho más lentos: para compilar 10 carchivos, cada uno con un archivo largo adjunto , el hcompilador tiene que pasar por el encabezado 10 veces. Para lidiar con este problema, muchos compiladores usan archivos .
Los archivos de encabezado junto con algunos objetos del lenguaje C++ ( constantes , inline-funciones, plantillas , static-variables) forman construcciones pesadas.
El programador debe cambiar sincrónicamente los encabezados de función en dos lugares. Si cambió cel archivo y se olvidó de hacer lo mismo con el harchivo, el enlazador dará un mensaje de error vago sin un número de línea. Esto es especialmente notable en C++ , donde la misma función puede tener un conjunto diferente de argumentos y la verificación a nivel del compilador no funciona. Si un programador accidentalmente dejó una construcción en un harchivo sin terminar, el error estaría en un archivo completamente cdiferente h.
Los proyectos de lenguajes de la familia C se caracterizan por esquemas de ensamblaje de proyectos complejos. Después de todo (al menos en C ++ estándar), debe incluir una biblioteca en el proyecto, ya sea en forma de archivos CPP o en forma compilada. Incluso si (por ejemplo, en Visual C++) hay directivas de preprocesador para esto, la biblioteca aún tendrá que construirse.
lenguaje de programación c | |
---|---|
compiladores |
|
bibliotecas | |
Peculiaridades | |
algunos descendientes | |
C y otros lenguajes |
|
Categoría:Lenguaje de programación C |