headers - make c++ header file




¿Cuál es la diferencia entre#include<filename> y#include “filename”? (20)

las búsquedas "<nombre de archivo>" en las ubicaciones estándar de la biblioteca C

mientras que "nombre de archivo" busca en el directorio actual también.

Lo ideal sería utilizar <...> para las bibliotecas de C estándar y "..." para las bibliotecas que escribe y están presentes en el directorio actual.

En los lenguajes de programación C y C ++, ¿cuál es la diferencia entre usar paréntesis angulares y usar comillas en una declaración de include , de la siguiente manera?

  1. #include <filename>
  2. #include "filename"

#include <filename>

se utiliza cuando se desea utilizar el archivo de encabezado del sistema C / C ++ o las bibliotecas del compilador. Estas bibliotecas pueden ser stdio.h, string.h, math.h, etc.

#include "path-to-file/filename"

se usa cuando desea usar su propio archivo de encabezado personalizado que se encuentra en la carpeta de su proyecto o en otro lugar.

Para más información sobre preprocesadores y cabecera. Leer C - Preprocesadores .


Al menos para la versión GCC <= 3.0, la forma de corchete angular no genera una dependencia entre el archivo incluido y el incluido.

Entonces, si desea generar reglas de dependencia (usando la opción GCC -M por ejemplo), debe usar el formulario entre comillas para los archivos que deben incluirse en el árbol de dependencia.

(Consulte http://gcc.gnu.org/onlinedocs/cpp/Invocation.html )


Algunas respuestas correctas hacen referencia al estándar C, pero olvidaron el estándar POSIX, especialmente el comportamiento específico del comando c99 (por ejemplo, compilador C) .

De acuerdo con las especificaciones de la base de grupo abierto número 7 ,

-I directorio

Cambie el algoritmo para buscar encabezados cuyos nombres no sean rutas de acceso absolutas para buscar en el directorio nombrado por la ruta de acceso del directorio antes de buscar en los lugares habituales. Por lo tanto, los encabezados cuyos nombres están entre comillas dobles ("") se buscarán primero en el directorio del archivo con la línea #include , luego en los directorios nombrados en las opciones -I , y los últimos en los lugares habituales. Para los encabezados cuyos nombres están encerrados entre corchetes angulares ("<>"), el encabezado se buscará solo en los directorios nombrados en opciones -I y luego en los lugares habituales. Los directorios nombrados en las opciones -I se buscarán en el orden especificado. Las implementaciones admitirán al menos diez instancias de esta opción en una sola invocación de comando c99 .

Por lo tanto, en un entorno compatible con POSIX, con un compilador C compatible con POSIX, #include "file.h" probablemente buscará ./file.h primero, donde . es el directorio donde se encuentra el archivo con la instrucción #include , mientras que #include <file.h> , probablemente buscará /usr/include/file.h primero, donde /usr/include es el sistema donde se definen los lugares habituales para encabezados (parece que no está definido por POSIX).


El #include <filename> se utiliza cuando se hace referencia a un archivo del sistema. Este es un archivo de encabezado que se puede encontrar en ubicaciones predeterminadas del sistema como /usr/include o /usr/local/include .Para sus propios archivos que deben incluirse en otro programa, debe utilizar la #include "filename"sintaxis.


En C ++, incluya un archivo de dos maneras:

El primero es #include, que le dice al preprocesador que busque el archivo en la ubicación predeterminada predefinida. Esta ubicación suele ser una variable de entorno INCLUDE que denota la ruta para incluir archivos.

Y el segundo tipo es #include "nombre de archivo", que le dice al preprocesador que busque primero el archivo en el directorio actual, luego lo busque en las ubicaciones predefinidas que el usuario haya configurado.


Gracias por las grandes respuestas, esp. Adam Stelmaszczyk y piCookie, y aib.

Como muchos programadores, he usado la convención informal de usar el "myApp.hpp" para archivos específicos de la aplicación, y el <libHeader.hpp> para los archivos de sistema de compiladores y bibliotecas, es decir, los archivos especificados en /I y la variable de entorno INCLUDE , durante años pensando que era la norma.

Sin embargo, el estándar C establece que el orden de búsqueda es específico de la implementación, lo que puede complicar la portabilidad. Para empeorar las cosas, usamos jam, que se da cuenta automáticamente de dónde están los archivos de inclusión. Puede usar rutas relativas o absolutas para sus archivos de inclusión. es decir

#include "../../MyProgDir/SourceDir1/someFile.hpp"

Las versiones anteriores de MSVS requerían una doble barra diagonal inversa (\\), pero ahora eso no es necesario. No sé cuándo cambió. Simplemente use barras diagonales para compatibilidad con 'nix (Windows aceptará eso).

Si está realmente preocupado por eso, use "./myHeader.h" para un archivo de inclusión en el mismo directorio que el código fuente (mi proyecto actual, muy grande, tiene algunos nombres de archivo de inclusión duplicados, realmente un problema de administración de la configuración ).

Aquí está la explicación de MSDN copiada aquí para su conveniencia).

Forma citada

El preprocesador busca archivos de inclusión en este orden:

  1. En el mismo directorio que el archivo que contiene la instrucción #include.
  2. En los directorios de los archivos incluidos actualmente abiertos, en el orden inverso en que
    fueron abiertos. La búsqueda comienza en el directorio del archivo de inclusión padre y
    continúa hacia arriba a través de los directorios de cualquier abuelo incluye archivos.
  3. A lo largo de la ruta especificada por cada opción del compilador /I
  4. A lo largo de las rutas especificadas por la variable de entorno INCLUDE .

Forma de soporte en ángulo

El preprocesador busca archivos de inclusión en este orden:

  1. A lo largo de la ruta especificada por cada opción del compilador /I
  2. Cuando se realiza la compilación en la línea de comandos, a lo largo de las rutas especificadas por la variable de entorno INCLUDE .

La única forma de saberlo es leer la documentación de su implementación.

En la norma C , sección 6.10.2, los párrafos 2 a 4 establecen:

  • Una directiva de preprocesamiento de la forma.

    #include <h-char-sequence> new-line
    

    busca una secuencia de lugares definidos por la implementación para un encabezado identificado de forma única por la secuencia especificada entre los delimitadores < y > , y provoca el reemplazo de esa directiva por todo el contenido del encabezado. La forma en que se especifican los lugares o el encabezado identificado se define por la implementación.

  • Una directiva de preprocesamiento de la forma.

    #include "q-char-sequence" new-line
    

    provoca la sustitución de esa directiva por todo el contenido del archivo fuente identificado por la secuencia especificada entre los delimitadores. El archivo fuente nombrado se busca de una manera definida por la implementación. Si esta búsqueda no es compatible o si la búsqueda falla , la directiva es reprocesada como si leyera

    #include <h-char-sequence> new-line
    

    con la secuencia contenida idéntica (incluidos > caracteres, si corresponde) de la directiva original.

  • Una directiva de preprocesamiento de la forma.

    #include pp-tokens new-line
    

    (que no coincida con uno de los dos formularios anteriores) está permitido. Los tokens de preprocesamiento después de include en la directiva se procesan igual que en el texto normal. (Cada identificador actualmente definido como un nombre de macro se reemplaza por su lista de reemplazo de tokens de preprocesamiento). La directiva resultante después de todos los reemplazos deberá coincidir con uno de los dos formularios anteriores. El método mediante el cual una secuencia de tokens de preprocesamiento entre un par de token de preproceso < y un > o un par de " caracteres se combina en un token de preprocesamiento de nombre de encabezado único se define por implementación.

Definiciones:

  • h-char: cualquier miembro del conjunto de caracteres fuente excepto el carácter de nueva línea y >

  • q-char: cualquier miembro del conjunto de caracteres fuente excepto el carácter de nueva línea y "


La secuencia de caracteres entre <y> se refiere únicamente a un encabezado, que no es necesariamente un archivo. Las implementaciones son bastante libres de usar la secuencia de caracteres como deseen. (En su mayoría, sin embargo, solo trátelo como un nombre de archivo y haga una búsqueda en la ruta de inclusión , como lo indican las otras publicaciones).

Si se utiliza el formulario #include "file" , la implementación primero busca un archivo con el nombre dado, si es compatible. Si no (compatible), o si la búsqueda falla, la implementación se comporta como si se hubiera utilizado el otro #include <file> ( #include <file> ).

Además, existe un tercer formulario y se utiliza cuando la directiva #include no coincide con ninguno de los formularios anteriores. En esta forma, se realiza algún preprocesamiento básico (como la expansión de macros) en los "operandos" de la directiva #include , y se espera que el resultado coincida con una de las otras dos formas.


Lo hace:

"mypath/myfile" is short for ./mypath/myfile

con . ya sea el directorio del archivo en el que se incluye el #include y / o el directorio de trabajo actual del compilador, y / o el default_include_paths

y

<mypath/myfile> is short for <defaultincludepaths>/mypath/myfile

Si ./ está en <default_include_paths> , entonces no hay diferencia.

Si mypath/myfile está en otro directorio de inclusión, el comportamiento no está definido.


Para #include "" un compilador normalmente busca en la carpeta del archivo que contiene esa inclusión y luego las otras carpetas. Para #include <> el compilador no busca en la carpeta del archivo actual.


Por la norma - sí, son diferentes:

  • Una directiva de preprocesamiento de la forma.

    #include <h-char-sequence> new-line
    

    busca una secuencia de lugares definidos por la implementación para un encabezado identificado de forma única por la secuencia especificada entre los delimitadores < y > , y provoca el reemplazo de esa directiva por todo el contenido del encabezado. La forma en que se especifican los lugares o el encabezado identificado se define por la implementación.

  • Una directiva de preprocesamiento de la forma.

    #include "q-char-sequence" new-line
    

    provoca la sustitución de esa directiva por todo el contenido del archivo fuente identificado por la secuencia especificada entre los delimitadores. El archivo fuente nombrado se busca de una manera definida por la implementación. Si esta búsqueda no es compatible o si la búsqueda falla , la directiva es reprocesada como si leyera

    #include <h-char-sequence> new-line
    

    con la secuencia contenida idéntica (incluidos > caracteres, si corresponde) de la directiva original.

  • Una directiva de preprocesamiento de la forma.

    #include pp-tokens new-line
    

    (que no coincida con uno de los dos formularios anteriores) está permitido. Los tokens de preprocesamiento después de include en la directiva se procesan igual que en el texto normal. (Cada identificador actualmente definido como un nombre de macro se reemplaza por su lista de reemplazo de tokens de preprocesamiento). La directiva resultante después de todos los reemplazos deberá coincidir con uno de los dos formularios anteriores. El método mediante el cual una secuencia de tokens de preprocesamiento entre un par de token de preproceso < y un > o un par de " caracteres se combina en un token de preprocesamiento de nombre de encabezado único se define por implementación.

Definiciones:

  • h-char: cualquier miembro del conjunto de caracteres fuente excepto el carácter de nueva línea y >

  • q-char: cualquier miembro del conjunto de caracteres fuente excepto el carácter de nueva línea y "

Tenga en cuenta que el estándar no indica ninguna relación entre los modales definidos por la implementación. La primera forma busca en una forma definida por la implementación, y la otra en una forma (posiblemente otra) definida por la implementación. El estándar también especifica que ciertos archivos de inclusión estarán presentes (por ejemplo, <stdio.h> ).

Formalmente, tendría que leer el manual de su compilador, sin embargo, normalmente (por tradición) el formulario #include "..." busca el directorio del archivo en el que se encontró primero el #include , y luego los directorios que el #include <...> búsquedas de formulario (la ruta de inclusión, por ejemplo, encabezados del sistema).


La documentación de GCC dice lo siguiente acerca de la diferencia entre los dos:

Los archivos de encabezado del usuario y del sistema se incluyen utilizando la directiva de preprocesamiento '#include' . Tiene dos variantes:

#include <file>

Esta variante se utiliza para los archivos de encabezado del sistema. Busca un archivo denominado archivo en una lista estándar de directorios del sistema. Puede anteponer directorios a esta lista con la opción -I (consulte Invocation ).

#include "file"

Esta variante se utiliza para los archivos de cabecera de su propio programa. Busca un archivo llamado file primero en el directorio que contiene el archivo actual, luego en los directorios de citas y luego en los mismos directorios utilizados para <file> . Puede anteponer directorios a la lista de directorios de cotización con la opción -iquote . El argumento de '#include' , ya sea delimitado con comillas o corchetes angulares, se comporta como una constante de cadena en que los comentarios no se reconocen, y los nombres de macro no se expanden. Por lo tanto, #include <x/*y> especifica la inclusión de un archivo de encabezado del sistema llamado x/*y .

Sin embargo, si se producen barras diagonales inversas dentro del archivo, se consideran caracteres de texto ordinarios, no caracteres de escape. Ninguna de las secuencias de escape de caracteres adecuadas para las constantes de cadena en C se procesa. Por lo tanto, #include "x\n\\y" especifica un nombre de archivo que contiene tres barras invertidas. (Algunos sistemas interpretan '\' como un separador de ruta de acceso. Todos estos también interpretan '/' la misma manera. Es más portátil usar solo '/' .)

Es un error si hay algo (aparte de comentarios) en la línea después del nombre del archivo.


#include <file.h> le dice al compilador que busque el encabezado en su directorio "incluye", por ejemplo, para MinGW el compilador buscará el file.h en C: \ MinGW \ include \ o donde sea que esté instalado su compilador.

#include "file" le dice al compilador que busque el directorio actual (es decir, el directorio en el que reside el archivo de origen) para el file .

Puede usar el indicador -I para que GCC le diga que, cuando encuentra una inclusión con corchetes angulares, también debe buscar encabezados en el directorio después de -I . GCC tratará el directorio después de la bandera como si fuera el directorio de includes .

Por ejemplo, si tiene un archivo llamado myheader.h en su propio directorio, podría decir #include <myheader.h> si llamó a GCC con la bandera -I . (lo que indica que debe buscar incluye en el directorio actual.)

Sin la -I , deberá usar #include "myheader.h" para incluir el archivo, o mover myheader.h al directorio de include de su compilación.


Creo que los encabezados incluidos en comillas dobles se buscarán en las mismas rutas de sistema que las inclusiones entre corchetes angulares si no se encuentran en el directorio actual.


Existen dos formas de escribir la instrucción #include. Estas son:

#include"filename"
#include<filename>

El significado de cada forma es

#include"mylib.h"

Este comando buscará el archivo mylib.hen el directorio actual así como la lista especificada de directorios como se menciona en la ruta de búsqueda de inclusión que podría haberse configurado.

#include<mylib.h>

Este comando buscaría el archivo solo mylib.hen la lista especificada de directorios.

La ruta de búsqueda de inclusión no es más que una lista de directorios en los que se buscaría el archivo que se incluye. Los diferentes compiladores de C permiten establecer la ruta de búsqueda de diferentes maneras.


La regla general simple es usar corchetes angulares para incluir archivos de encabezado que vienen con el compilador. Use comillas dobles para incluir cualquier otro archivo de encabezado. La mayoría de los compiladores lo hacen de esta manera.

1.9 - Los archivos de encabezado explican con más detalle las directivas de preprocesador. Si eres un programador novato, esa página te ayudará a entender todo eso. Lo aprendí de aquí, y lo he estado siguiendo en el trabajo.


Para ver el orden de búsqueda en su sistema usando gcc, según la configuración actual, puede ejecutar el siguiente comando. Puedes encontrar más detalles sobre este comando aquí.

cpp -v /dev/null -o /dev/null

Apple LLVM versión 10.0.0 (clang-1000.10.44.2)
Objetivo: x86_64-apple-darwin18.0.0
Modelo de hilo: posixDirección instalada: Biblioteca / Desarrollador / CommandLineTools / usr / bin
"/ Library / Developer / CommandLineTools / usr / bin / clang" -cc1 -triple x86_64-apple-macosx10.14.0 -Wdeprecated-objc-isa-use -Werror = deprecated-objc-isa-usage -E -disable-free - disable-llvm-verifier -discard-value-names -main-file-name nulo -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -fno-strict-return -masm-verbose - munwind-tables -target-cpu penryn -dwarf-column-info -debugger-tuning = lldb -target-linker-version 409.12 -v -resource-dir /Library/Developer/CommandLineTools/usr/lib/clang/10.0.0 - isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk -I / usr / local / include -fdebug-compilation-dir / Users / hogstrom -ferror-limit 19 -fmessage-length 1 -fblocks -fencode-extended-block-signature -fobjc-runtime = macosx-10.14.0 -fmax-type-align = 16 -fdiagnostics-show-option -fcolor-diagnostics -traditional-cpp -o - -xc / dev / null
clang -cc1 versión 10.0.0 (clang-1000.10.44.2) destino predeterminado x86_64-apple-darwin18.0.0 ignorando el directorio inexistente "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/local/include" que ignora la falta directorio "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/Library/Frameworks"
#include "..." la búsqueda comienza aquí:
#include <...> la búsqueda comienza aquí:
/ usr / local / include
/ Library / Developer / CommandLineTools / usr / lib / clang / 10.0.0 / include
/ Library / Developer / CommandLineTools / usr / include
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include
/ Library / Developer / CommandLineTools / SDKs / MacOSX10.14.sdk / System / Library / Frameworks (directorio marco)
Fin de la lista de búsqueda.


#include "filename" // User defined header
#include <filename> // Standard library header.

Ejemplo:

El nombre de archivo aquí es Seller.h :

#ifndef SELLER_H     // Header guard
#define SELLER_H     // Header guard

#include <string>
#include <iostream>
#include <iomanip>

class Seller
{
    private:
        char name[31];
        double sales_total;

    public:
        Seller();
        Seller(char[], double);
        char*getName();

#endif

En la implementación de la clase (por ejemplo, Seller.cpp , y en otros archivos que usarán el archivo Seller.h ), ahora se debe incluir el encabezado definido por el usuario, de la siguiente manera:

#include "Seller.h"

#include <abc.h>

Se utiliza para incluir archivos de biblioteca estándar. Así que el compilador verificará las ubicaciones donde residen los encabezados de las bibliotecas estándar.

#include "xyz.h"

le dirá al compilador que incluya archivos de encabezado definidos por el usuario. Por lo tanto, el compilador buscará estos archivos de encabezado en la carpeta actual o en las carpetas definidas.







c-preprocessor