c++ - tutorial - write c header file




Qual é a diferença entre#include<filename> e#include “filename”? (20)

o "<nome do arquivo>" procura em locais da biblioteca C padrão

enquanto que "nome do arquivo" procura no diretório atual também.

Idealmente, você usaria <...> para bibliotecas C padrão e "..." para bibliotecas que você escreve e estão presentes no diretório atual.

Nas linguagens de programação C e C ++, qual é a diferença entre usar colchetes e usar aspas em uma instrução include , como segue?

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

#include <filename>

é usado quando você deseja usar o arquivo de cabeçalho do sistema C / C ++ ou bibliotecas de compilador. Essas bibliotecas podem ser stdio.h, string.h, math.h etc.

#include "path-to-file/filename"

é usado quando você deseja usar seu próprio arquivo de cabeçalho personalizado que está na sua pasta de projeto ou em outro lugar.

Para mais informações sobre pré-processadores e cabeçalho. Leia C - Pré-processadores .


A única maneira de saber é ler a documentação da sua implementação.

No padrão C , seção 6.10.2, os parágrafos 2 a 4 declaram:

  • Uma diretiva de pré-processamento do formulário

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

    pesquisa uma sequência de locais definidos pela implementação para um cabeçalho identificado unicamente pela sequência especificada entre os delimitadores < e > e faz com que a substituição dessa diretiva pelo conteúdo inteiro do cabeçalho. Como os locais são especificados ou o cabeçalho identificado é definido pela implementação.

  • Uma diretiva de pré-processamento do formulário

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

    faz com que a substituição dessa diretiva pelo conteúdo inteiro do arquivo de origem identificado pela seqüência especificada entre os " delimitadores. O arquivo de origem nomeado é procurado em uma forma definida pela implementação. Se essa pesquisa não for suportada ou se a pesquisa falhar , a diretiva é reprocessada como se lesse

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

    com a sequência contida idêntica (incluindo > caracteres, se houver) da diretiva original.

  • Uma diretiva de pré-processamento do formulário

    #include pp-tokens new-line

    (que não corresponde a um dos dois formulários anteriores) é permitido. Os tokens de pré-processamento após a include na diretiva são processados ​​exatamente como no texto normal. (Cada identificador atualmente definido como um nome de macro é substituído por sua lista de substituição de tokens de pré-processamento.) A diretiva resultante de todas as substituições deve corresponder a um dos dois formulários anteriores. O método pelo qual uma sequência de tokens de pré-processamento entre um par de tokens de pré-processamento < e um > ou um par de " caracteres é combinado em um único token de pré-processamento de nome de cabeçalho é definido pela implementação.

Definições:

  • h-char: qualquer membro do conjunto de caracteres de origem, exceto o caractere de nova linha e >

  • q-char: qualquer membro do conjunto de caracteres de origem, exceto o caractere de nova linha e "


A inclusão de <file> informa ao pré-processador para pesquisar nos diretórios -I e nos diretórios predefinidos primeiro e , em seguida, no diretório do arquivo .c. O "file" inclui informa ao pré-processador para pesquisar primeiro o diretório do arquivo de origem e depois reverter para -I e predefinido. Todos os destinos são pesquisados ​​de qualquer forma, apenas a ordem de pesquisa é diferente.

O padrão de 2011 discute principalmente os arquivos de inclusão em "16.2 Inclusão do arquivo de origem".

2 Uma diretiva de pré-processamento do formulário

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

pesquisa uma sequência de locais definidos pela implementação para um cabeçalho identificado unicamente pela sequência especificada entre os delimitadores <e> e faz com que a substituição dessa diretiva pelo conteúdo inteiro do cabeçalho. Como os locais são especificados ou o cabeçalho identificado é definido pela implementação.

3 Uma diretiva de pré-processamento do formulário

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

faz com que a substituição dessa diretiva pelo conteúdo inteiro do arquivo de origem identificado pela seqüência especificada entre os "delimitadores. O arquivo de origem nomeado é procurado em uma forma definida pela implementação. Se essa pesquisa não for suportada ou se a pesquisa falhar , a diretiva é reprocessada como se lesse

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

com a sequência contida idêntica (incluindo> caracteres, se houver) da diretiva original.

Observe que o formulário "xxx" degrada para o formulário <xxx> se o arquivo não for encontrado. O resto é definido pela implementação.


Algumas boas respostas aqui fazem referências ao padrão C, mas esqueceram o padrão POSIX, especialmente o comportamento específico do comando c99 (por exemplo, compilador C) .

De acordo com a Edição 7 do The Open Group Base Specifications ,

-I diretório

Altere o algoritmo para procurar por cabeçalhos cujos nomes não sejam caminhos absolutos para procurar no diretório nomeado pelo nome do caminho do diretório antes de procurar nos locais habituais. Assim, os cabeçalhos cujos nomes estão entre aspas duplas ("") devem ser procurados primeiro no diretório do arquivo com a linha #include , depois nos diretórios nomeados nas opções -I e por último nos locais usuais. Para cabeçalhos cujos nomes estão entre colchetes angulares ("<>"), o cabeçalho deve ser pesquisado apenas nos diretórios nomeados nas opções -I e depois nos locais habituais. Os diretórios nomeados nas opções -I devem ser pesquisados ​​na ordem especificada. As implementações devem suportar pelo menos dez instâncias dessa opção em uma única chamada de comando c99 .

Portanto, em um ambiente compatível com POSIX, com um compilador C compatível com POSIX, #include "file.h" provavelmente irá procurar por ./file.h primeiro, onde . é o diretório onde está o arquivo com a instrução #include , enquanto #include <file.h> , provavelmente irá procurar /usr/include/file.h primeiro, onde /usr/include é o seu sistema definido para os locais habituais cabeçalhos (parece não ser definido pelo POSIX).


Em C ++, inclua um arquivo de duas maneiras:

O primeiro é o #include, que informa ao pré-processador para procurar o arquivo no local padrão predefinido. Esse local geralmente é uma variável de ambiente INCLUDE que indica o caminho para incluir arquivos.

E o segundo tipo é #include "nome_do_arquivo", que informa ao pré-processador para procurar primeiro o arquivo no diretório atual e, em seguida, procurá-lo nos locais predefinidos que o usuário configurou.


Muitas das respostas aqui se concentram nos caminhos que o compilador pesquisará para encontrar o arquivo. Embora isso seja o que a maioria dos compiladores faz, um compilador em conformidade pode ser pré-programado com os efeitos dos cabeçalhos padrão e tratar, por exemplo, #include <list> como um comutador, e não precisa existir como um arquivo.

Isto não é puramente hipotético. Há pelo menos um compilador que funciona dessa maneira. É recomendável usar #include <xxx> somente com cabeçalhos padrão.


Na prática, a diferença está no local onde o pré-processador pesquisa o arquivo incluído.

Para #include <filename> o pré-processador pesquisa de maneira dependente da implementação, normalmente em diretórios de pesquisa pré-designados pelo compilador / IDE. Esse método é normalmente usado para incluir arquivos de cabeçalho de biblioteca padrão.

Para #include "filename" o pré-processador pesquisa primeiro no mesmo diretório que o arquivo que contém a diretiva e segue o caminho de pesquisa usado para o formulário #include <filename> . Esse método é normalmente usado para incluir arquivos de cabeçalho definidos pelo programador.

Uma descrição mais completa está disponível na documentação do GCC sobre caminhos de pesquisa .


Para #include "" um compilador normalmente procura a pasta do arquivo que contém aquela inclusão e depois as outras pastas. Para #include <> o compilador não pesquisa a pasta do arquivo atual.


Pelo menos para a versão do GCC <= 3.0, o formulário de suporte de ângulo não gera uma dependência entre o arquivo incluído e o incluído.

Então, se você quer gerar regras de dependência (usando a opção GCC -M, por exemplo), você deve usar o formulário citado para os arquivos que devem ser incluídos na árvore de dependência.

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


Quando você usa #include <filename>, o pré-processador procura o arquivo no diretório de arquivos de cabeçalho C \ C ++ (stdio.h \ cstdio, string, vetor etc.). Mas, quando você usa #include "nome_do_arquivo": primeiro, o pré-processador procura o arquivo no diretório atual e, se não estiver aqui, ele o procura no diretório de arquivos de cabeçalho C \ C ++.


Um #include com colchetes irá pesquisar uma "lista de locais dependente da implementação" (que é uma maneira muito complicada de dizer "cabeçalhos de sistema") para o arquivo a ser incluído.

Um #include com aspas apenas irá procurar por um arquivo (e, "de uma forma dependente da implementação", bleh). O que significa que, em inglês normal, ele tentará aplicar o caminho / nome de arquivo que você jogou nele e não prefixará um caminho do sistema ou adulterá-lo de outra forma.

Além disso, se #include "" falhar, ele será lido como #include <> pelo padrão.

A g++ tem uma descrição (específica do compilador) que, apesar de ser específica para o gcc e não para o padrão, é muito mais fácil de entender do que o estilo do advogado dos padrões ISO.


#include <file.h> diz ao compilador para procurar o cabeçalho em seu diretório "includes", por exemplo, para o MinGW o compilador procuraria por file.h em C: \ MinGW \ include \ ou onde quer que seu compilador estivesse instalado.

#include "file" diz ao compilador para pesquisar o diretório atual (ou seja, o diretório no qual o arquivo de origem reside) para o file .

Você pode usar o sinalizador -I do GCC para informar que, quando encontrar um include com colchetes angulares, ele também deverá procurar cabeçalhos no diretório depois de -I . O GCC tratará o diretório após o sinalizador como se fosse o diretório includes .

Por exemplo, se você tiver um arquivo chamado myheader.h no seu próprio diretório, você pode dizer #include <myheader.h> se você chamou o GCC com a flag -I . (indicando que deve procurar por includes no diretório atual.)

Sem o sinalizador -I , você terá que usar #include "myheader.h" para incluir o arquivo ou mover myheader.h para o diretório include de sua compilação.


#include <filename>

irá encontrar o arquivo correspondente da biblioteca C ++. isso significa que se você tiver um arquivo chamado hello.h na pasta da biblioteca C ++, #include <hello.h>irá carregá-lo.

Mas,

#include "filename"

irá encontrar o arquivo no mesmo diretório onde está o seu arquivo de origem.

Além do que, além do mais,

#include "path_to_file/filename"

irá encontrar o arquivo no diretório que você digitou path_to_file.


Existem duas maneiras de escrever #include statement.These são:

#include"filename"
#include<filename>

O significado de cada forma é

#include"mylib.h"

Esse comando procuraria o arquivo mylib.hno diretório atual, bem como a lista de diretórios especificada, conforme mencionado no caminho de pesquisa de inclusão que pode ter sido configurado.

#include<mylib.h>

Esse comando procuraria o arquivo apenas mylib.hna lista especificada de diretórios.

O caminho de pesquisa de inclusão não é nada, mas uma lista de diretórios que seriam pesquisados ​​para o arquivo que está sendo incluído. Os compiladores C diferentes permitem que você defina o caminho de pesquisa de maneiras diferentes.


A ordem dos arquivos de cabeçalho de pesquisa é diferente. <XXX.h> prefere pesquisar os cabeçalhos padrão primeiro, enquanto "XXX.h" pesquisa os arquivos de cabeçalho do espaço de trabalho primeiro.


O #include <filename>é usado quando um arquivo de sistema está sendo referido. Esse é um arquivo de cabeçalho que pode ser encontrado em locais padrão do sistema, como /usr/includeou /usr/local/include. Para seus próprios arquivos que precisam ser incluídos em outro programa, você precisa usar a #include "filename"sintaxe.


Para ver a ordem de busca no seu sistema usando o gcc, com base na configuração atual, você pode executar o seguinte comando. Você pode encontrar mais detalhes sobre este comando aqui

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

Apple LLVM versão 10.0.0 (clang-1000.10.44.2)
Destino: x86_64-apple-darwin18.0.0
Modelo de encadeamento : posix InstalledDir: Biblioteca / Desenvolvedor / CommandLineTools / usr / bin
"/ Library / Developer / CommandLineTools /usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.14.0 -Wdeprecated-objc-isa-uso -Werror = depreciado-objc-isa-uso -E-desabilitar-livre - disable-llvm-verifier -discard-value-names -main-file-name null -mrelocation-model pic -apic-level 2 -mthread-model posix -mdisable-fp-elim -fno-strict-return -masm-verbose - munwind-tables -target-cpu penryn -dwarf-column-info -debugger-tuning = lldb -versão-linker-versão 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-compilação-dir / Usuários / hogstrom -ferror-limit 19 -fmensage-length 80 -stack-protector 1 -fblocks -fencode-extended-block-signature -fobjc-runtime = macosx-10.14.0 -fmax-type-align = 16 -diagnostics-show-option -corgnostics -traditional-cpp -o - -xc / dev / null
clang -cc1 versão 10.0.0 (clang-1000.10.44.2) alvo padrão x86_64-apple-darwin18.0.0 ignorando o diretório inexistente "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/local/include" ignorando inexistente diretório "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/Library/Frameworks"
#include "..." a pesquisa começa aqui:
#include <...> a pesquisa começa aqui:
/ usr / local / include
/ Biblioteca / Desenvolvedor / CommandLineTools / usr / lib / clang / 10.0.0 / include
/ Biblioteca / Desenvolvedor / CommandLineTools / usr / include
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include
/ Library / Developer / CommandLineTools / SDKs / MacOSX10.14.sdk / System / Library / Frameworks (diretório de estrutura)
Fim da lista de pesquisa.


#include <abc.h>

é usado para incluir arquivos de biblioteca padrão. Portanto, o compilador verificará os locais onde os cabeçalhos da biblioteca padrão estão residindo.

#include "xyz.h"

irá dizer ao compilador para incluir arquivos de cabeçalho definidos pelo usuário. Portanto, o compilador verificará esses arquivos de cabeçalho na pasta atual ou nas pastas -I definidas.


  #include <filename>   (1)     
  #include "filename"   (2)

#include inclui o arquivo de origem, identificado por nome de arquivo, no arquivo de origem atual na linha imediatamente após a diretiva.

A primeira versão da diretiva pesquisa apenas diretórios de inclusão padrão. A biblioteca C ++ padrão, assim como a biblioteca C padrão, é incluída implicitamente nos diretórios de inclusão padrão. Os diretórios include standard podem ser controlados pelo usuário através de opções de compilador.

A segunda versão procura primeiro o diretório em que o arquivo atual reside e, somente se o arquivo não for encontrado, pesquisa os diretórios de inclusão padrão.

No caso do arquivo não ser encontrado, o programa está mal formado.





c-preprocessor