Qual é a diferença entre #include <filename> e #include "filename"?

2357

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

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

Respostas:

1405

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

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

Para #include "filename"as pesquisas pré-processador primeiros no mesmo diretório que o arquivo que contém a directiva, e, em seguida, segue o caminho de pesquisa usado para o #include <filename>formulário. Este 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 nos caminhos de pesquisa .

quest49
fonte
135
A declaração: "o pré-processador pesquisa no mesmo diretório ..." pode ser verdadeira na prática, mas o padrão afirma que o arquivo de origem nomeado é "pesquisado de uma maneira definida pela implementação". Veja a resposta do piCookie.
Richard Corden
60
Embora sua resposta possa parecer "verdadeira", porque é quantas implementações funcionam por convenção, você deve examinar atentamente as respostas de aib e piCookie. Ambos apontam (apoiado pela redação do padrão C) que a distinção real é a inclusão de um "cabeçalho" versus a inclusão de um "arquivo de origem" (e não, isso não significa ".h" vs. ". c "). "Arquivo de origem" neste contexto pode ser (e geralmente é, e quase sempre deve ser) um arquivo ".h". Um cabeçalho não precisa necessariamente ser um arquivo (um compilador pode, por exemplo, incluir um cabeçalho estaticamente codificado, não em um arquivo).
10269 Dan Molding
5
"... o pré-processador pesquisa no mesmo diretório que o arquivo que está sendo compilado para que o arquivo seja incluído." Esta afirmação não está completamente correta. Eu estava interessado nesta pergunta porque estava curioso para saber qual é a resposta real, mas sei que isso não é verdade, porque pelo menos com o gcc quando você especifica um caminho de inclusão adicional com -I, que procurará por arquivos especificados com o nome de arquivo #include ". h "
Gabriel Southern
9
Aqueles que não gostam da resposta, por favor, dê um exemplo prático, onde está errado.
0kcats
1
Com certeza, recentemente misturei essas sintaxes ao incluir cabeçalhos da biblioteca 'mesma' e acabei com erros de redefinição. Se bem entendi, #include <...>usei o pacote instalado no sistema e #include "..."a versão do repositório nas proximidades. Eu posso ter isso ao contrário. De qualquer forma, a proteção de inclusão no cabeçalho empacotado é prefixada com um sublinhado. (Poderia ser uma convenção para pacotes ou talvez uma maneira de deliberadamente evitar a mistura dos dois, embora eliminatórias versão faria mais sentido para mim.)
John P
714

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

Na norma C , a seção 6.10.2, os parágrafos 2 a 4 afirmam:

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

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

    Buscas uma sequência de locais definido pela implementação de um cabeçalho unicamente identificado pela sequência especificada entre o <e >delimitadores, e faz com que a substituição desta directiva por todo o conteúdo 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

    causa a substituição dessa diretiva pelo conteúdo inteiro do arquivo de origem identificado pela sequência especificada entre os "delimitadores. O arquivo de origem nomeado é pesquisado de uma maneira definida pela implementação. Se esta pesquisa não for suportada ou se a pesquisa falhar, a diretiva será 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 uma das duas formas anteriores) é permitido. Os tokens de pré-processamento após includena diretiva são processados ​​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 após todas as substituições deve corresponder a uma das duas formas anteriores. O método pelo qual uma sequência de tokens de pré-processamento entre um par de token de pré <- >processamento e um par de "caracteres é combinada 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 "

piCookie
fonte
108
Relevante: implementação em g ++ e em c ++ visual
Alexander Malakhov 10/10
27
@piCookie <filename> e "filename" pesquisam locais definidos pela implementação. Então qual é a diferença ?
onmyway133
15
@ Stefan, estou apenas citando o padrão que não diz nada sobre o INCLUDE_PATH. Sua implementação pode fazer isso, e a minha não. A pergunta original era genericamente C e não especificamente o gcc (que eu acho que não usa INCLUDE_PATH) ou o Microsoft C (o que eu acho que faz) ou qualquer outra coisa, portanto não pode ser respondida genericamente, mas a documentação de cada implementação deve ser referenciada.
piCookie
12
Como em todas essas situações, exemplos concretos (especialmente de cenários comuns) são muito úteis e igualmente apreciados. Respostas genéricas desnecessariamente obtusas não têm tanto uso prático.
vargonian
132
"Veja como o padrão C pode ser detalhado e não responder à sua pergunta"
anatolyg
287

A sequência de caracteres entre <e> refere-se exclusivamente a um cabeçalho, que não é necessariamente um arquivo. As implementações são praticamente livres para usar a sequência de caracteres como desejarem. (Principalmente, no entanto, apenas trate-o como um nome de arquivo e faça uma pesquisa no caminho de inclusão , como as outras postagens afirmam.)

Se o #include "file"formulário for usado, a implementação procurará primeiro um arquivo com o nome especificado, se suportado. Se não (suportado), ou se a pesquisa falhar, a implementação se comportará como se o outro #include <file>formulário ( ) tivesse sido usado.

Além disso, um terceiro formulário existe e é usado quando a #includediretiva não corresponde a nenhum dos formulários acima. Nesta forma, algum pré-processamento básico (como expansão de macro) é realizado nos "operandos" da #includediretiva e o resultado deve corresponder a uma das duas outras formas.

aib
fonte
50
+1, esta é provavelmente a resposta mais concisa e correta aqui. De acordo com o padrão (do qual piCookie cita em sua resposta), a única diferença real é "cabeçalho" versus "arquivo de origem". O mecanismo de pesquisa é definido pela implementação de qualquer maneira. Usar aspas duplas significa que você pretende incluir um "arquivo de origem", enquanto que colchetes angulares significam que pretende incluir um "cabeçalho" que, como você diz, pode não ser um arquivo.
Dan Moulding
3
Veja o comentário de Dan Moulding na resposta da quest49; os cabeçalhos padrão não precisam estar no formato de arquivo, eles podem ser incorporados.
Aib
10
Eu tenho lido estes "cabeçalhos padrão não precisam estar em formato de arquivo" há uma década. Gostaria de fornecer um exemplo do mundo real?
Maxim Egorushkin
12
@ Maxim Yegorushkin: Também não consigo pensar em exemplos do mundo real; no entanto, nenhum compilador C11 completo pode existir para o MS-DOS, a menos que os cabeçalhos não precisem ser arquivos. Isso ocorre porque alguns dos nomes de cabeçalho C11 não são compatíveis com a limitação de nome de arquivo "8.3" do MS-DOS.
Dan Molding
18
@MaximEgorushkin: O compilador VAX / VMS C manteve todos os cabeçalhos da biblioteca de tempo de execução C em um único arquivo de biblioteca de texto (semelhante a um arquivo unix) e usou a sequência entre <e >como a chave para indexar na biblioteca.
Adrian McCarthy
117

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

De acordo com o The Open Group Base Specifications Issue 7 ,

-I diretório

Altere o algoritmo para procurar cabeçalhos cujos nomes não sejam nomes de caminho absolutos para procurar no diretório nomeado pelo nome do caminho do diretório antes de procurar nos locais habituais. Portanto, cabeçalhos cujos nomes estão entre aspas duplas ("") devem ser pesquisados ​​primeiro no diretório do arquivo com a linha #include , depois nos diretórios nomeados nas opções -I e por último nos locais habituais. 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.chamada de comando c99 .

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

Yann Droneaud
fonte
1
Qual é a fonte exata do texto? É da parte normativa do IEEE Std 1003.1, 2013?
Osgx
7
@osgx: essa expressão (ou algo extremamente similar) é encontrada na especificação POSIX para c99- que é o nome POSIX para o compilador C. (O padrão POSIX 2008 dificilmente poderia se referir a C11; a atualização 2013 para POSIX 2008 não alterou o padrão C que se referia a.)
Jonathan Leffler
1
Este foi o meu primeiro pensamento também. A página de manual do gcc inclui isso, assim como outros. Também existe uma coisa semelhante para bibliotecas - -L.
Pryftan
50

A documentação do GCC diz o seguinte sobre a diferença entre os dois:

Os arquivos de cabeçalho do usuário e do sistema são incluídos usando a diretiva de pré-processamento ‘#include’. Tem duas variantes:

#include <file>

Essa variante é usada para arquivos de cabeçalho do sistema. Ele procura por um arquivo chamado file em uma lista padrão de diretórios do sistema. Você pode anexar diretórios a esta lista com a -Iopção (consulte Invocação ).

#include "file"

Essa variante é usada para arquivos de cabeçalho do seu próprio programa. Ele procura por um arquivo chamado file primeiro no diretório que contém o arquivo atual, depois nos diretórios de cotação e depois nos mesmos diretórios usados <file>. Você pode anexar diretórios à lista de diretórios de cotação com a -iquoteopção O argumento de ‘#include’, delimitado por aspas ou colchetes angulares, se comporta como uma constante de seqüência de caracteres em que os comentários não são reconhecidos e os nomes de macro não são expandidos. Assim, #include <x/*y>especifica a inclusão de um arquivo de cabeçalho do sistema chamado x/*y.

No entanto, se as barras invertidas ocorrerem no arquivo, elas serão consideradas caracteres de texto comuns, não caracteres de escape. Nenhuma das seqüências de escape de caracteres apropriadas para constantes de cadeia de caracteres em C é processada. Assim, #include "x\n\\y"especifica um nome de arquivo contendo três barras invertidas. (Alguns sistemas interpretam '\' como um separador de nome de caminho. Todos esses também interpretam ‘/’da mesma maneira. É mais portátil de usar apenas ‘/’.)

É um erro se houver algo (além de comentários) na linha após o nome do arquivo.

Suraj Jain
fonte
46

Faz:

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

com .sendo o diretório do arquivo onde o #includeestá contido, e / ou o diretório de trabalho atual do compilador, e / ou adefault_include_paths

e

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

Se ./estiver <default_include_paths>, então não faz diferença.

Se mypath/myfileestiver em outro diretório de inclusão, o comportamento é indefinido.

Stefan Steiger
fonte
12
Não, #include "mypath/myfile"não é equivalente a #include "./mypath/myfile". Como a resposta do piCookie diz, aspas duplas dizem ao compilador para pesquisar de uma maneira definida pela implementação - o que inclui a pesquisa nos locais especificados #include <...>. (Na verdade, é provavelmente equivalente, mas apenas porque, por exemplo, /usr/include/mypath/myfilepode ser referida como /usr/include/./mypath/myfile-., Pelo menos, em Unix como sistemas)
Keith Thompson
1
@ Keith Thompson: Está certo, eu estava pensando na minha caixa do Linux. Evidentemente, poderia ser diferente. Embora na prática, o Windows como sistema operacional não-Posix também interprete / como separador de caminho e ./ também exista.
Stefan Steiger
1
a opção -L dirpath adiciona dirpath ao defaultincludepaths, em vez de atribuir outro significado ao .(como mencionado acima). Isto tem a consequência esperada que tanto #include "..."e #include <...>pesquisar em dirpath
Protongun
1
Eu acho que essa resposta está incorreta, pois implica que os cabeçalhos incluídos com aspas duplas são sempre procurados no diretório de trabalho atual. O mecanismo de busca é bem mais detalhado; esta resposta está incompleta. Não estou adicionando este comentário para reclamar ou reclamar, mas porque o sistema me pede para adicionar um comentário para explicar por que votei nessa resposta.
Carlo Wood
39

A <file>inclusão diz ao pré-processador para procurar nos -Idiretórios e nos diretórios predefinidos primeiro , depois no diretório do arquivo .c. A "file"inclusão diz ao pré-processador para procurar primeiro no diretório do arquivo de origem e depois reverter para -Ie predefinido. Todos os destinos são pesquisados ​​de qualquer maneira, apenas a ordem da pesquisa é diferente.

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

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

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

procura uma sequência de locais definidos pela implementação em busca de um cabeçalho identificado exclusivamente pela sequência especificada entre os delimitadores <e> e causa 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

causa a substituição dessa diretiva pelo conteúdo inteiro do arquivo de origem identificado pela sequência especificada entre os "delimitadores. O arquivo de origem nomeado é pesquisado de uma maneira 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 "xxx"formulário é degradado para <xxx>formar se o arquivo não for encontrado. O restante é definido pela implementação.


fonte
4
Você poderia fornecer uma referência para onde, no padrão C, esse -Inegócio está especificado?
Juanchopanza
1
Não vejo referência a -I.
Juanchopanza
2
Essa é a parte "definida pela implementação".
28

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

#include "file"diz ao compilador para procurar o diretório atual (ou seja, o diretório em que o arquivo de origem reside) file.

Você pode usar o -Isinalizador para o GCC para informar que, quando encontrar uma inclusão com colchetes angulares, também deverá procurar cabeçalhos no diretório depois -I. O GCC tratará o diretório após o sinalizador como se fosse o includesdiretório.

Por exemplo, se você tiver um arquivo chamado myheader.hem seu próprio diretório, poderá dizer #include <myheader.h>se chamou o GCC com o sinalizador -I .(indicando que ele deve procurar inclusões no diretório atual).

Sem o -Isinalizador, você precisará usar #include "myheader.h"para incluir o arquivo ou movermyheader.h para o includediretório do seu compilador.

adrian
fonte
22

Pelo padrão - sim, eles são diferentes:

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

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

    Buscas uma sequência de locais definido pela implementação de um cabeçalho unicamente identificado pela sequência especificada entre o <e >delimitadores, e faz com que a substituição desta directiva por todo o conteúdo 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

    causa a substituição dessa diretiva pelo conteúdo inteiro do arquivo de origem identificado pela sequência especificada entre os "delimitadores. O arquivo de origem nomeado é pesquisado de uma maneira definida pela implementação. Se esta pesquisa não for suportada ou se a pesquisa falhar, a diretiva será 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 uma das duas formas anteriores) é permitido. Os tokens de pré-processamento após includena diretiva são processados ​​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 após todas as substituições deve corresponder a uma das duas formas anteriores. O método pelo qual uma sequência de tokens de pré-processamento entre um par de token de pré <- >processamento e um par de "caracteres é combinada 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 "

Observe que o padrão não informa nenhuma relação entre as maneiras definidas pela implementação. O primeiro formulário pesquisa de uma maneira definida pela implementação e o outro de uma maneira (possivelmente outra) definida pela implementação. A norma também especifica que certos arquivos de inclusão devem estar presentes (por exemplo,<stdio.h> ).

Formalmente, você teria que ler o manual do seu compilador; no entanto, normalmente (por tradição) o #include "..."formulário pesquisa o diretório do arquivo no qual o arquivo #includefoi encontrado primeiro e, em seguida, os diretórios #include <...>pesquisados pelo formulário (o caminho de inclusão, por exemplo, cabeçalhos do sistema )

skyking
fonte
2
Este é basicamente o mesmo texto que a resposta de piCookie de sete anos antes.
Kyle Strand
5
@KyleStrand Isso ocorre porque o mesmo texto é uma citação da seção relevante no padrão - esse texto deve ser idêntico. A resposta real não é o mesmo texto e é um pouco diferente - embora reconheça também que será escrito na documentação para a implementação, também observo que há também uma maneira tradicional de interpretar (que a maioria ou todos os compiladores que eu usei respeitam) .
skyking 28/07/16
2
Na IMO, esta é a melhor resposta aqui, porque abrange o que o padrão diz e o que a maioria dos compiladores realmente faz.
Plug
17

Obrigado pelas ótimas respostas, esp. Adam Stelmaszczyk, piCookie e aib.

Como muitos programadores, usei a convenção informal de usar o "myApp.hpp"formulário para arquivos específicos de aplicativos e o <libHeader.hpp>formulário para arquivos de sistema de biblioteca e compilador, ou seja, arquivos especificados em /IeINCLUDE variável de ambiente, por anos pensando que era o padrão.

No entanto, o padrão C afirma que a ordem de pesquisa é específica da implementação, o que pode dificultar a portabilidade. Para piorar a situação, usamos jam, que descobre automaticamente onde estão os arquivos de inclusão. Você pode usar caminhos relativos ou absolutos para seus arquivos de inclusão. ie

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

As versões mais antigas do MSVS exigiam barras invertidas duplas (\\), mas agora isso não é necessário. Não sei quando isso mudou. Basta usar barras para compatibilidade com o 'nix (o Windows aceitará isso).

Se você estiver realmente preocupado com isso, use "./myHeader.h"para um arquivo de inclusão no mesmo diretório que o código-fonte (meu projeto atual, muito grande, possui alguns nomes de arquivo de inclusão duplicados espalhados - realmente um problema de gerenciamento de configuração).

Aqui está a explicação do MSDN copiada aqui para sua conveniência).

Formulário citado

O pré-processador procura arquivos de inclusão nesta ordem:

  1. No mesmo diretório que o arquivo que contém a instrução #include.
  2. Nos diretórios dos arquivos de inclusão abertos no momento, na ordem inversa em que
    foram abertos. A pesquisa começa no diretório do arquivo de inclusão pai e
    continua para cima nos diretórios de qualquer arquivo de inclusão dos avós.
  3. Ao longo do caminho especificado por cada /Iopção do compilador.
  4. Ao longo dos caminhos especificados pela INCLUDEvariável de ambiente.

Formulário de suporte angular

O pré-processador procura arquivos de inclusão nesta ordem:

  1. Ao longo do caminho especificado por cada /Iopção do compilador.
  2. Quando a compilação ocorre na linha de comandos, ao longo dos caminhos especificados pela INCLUDEvariável de ambiente.
riderBill
fonte
16

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

Portanto, se você deseja gerar regras de dependência (usando a opção GCC -M, por exemplo), use o formulário entre aspas para os arquivos que devem ser incluídos na árvore de dependência.

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

Denis Ros
fonte
1
Sim - existem várias maneiras diferentes de gerar dependências. Esse é um deles, mas não é o único.
Pryftan
15

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

Maxim Egorushkin
fonte
1
Não sei por que as pessoas discordam.
Maxim Egorushkin 27/03
Eu suspeito que é porque a maioria das pessoas compila apenas os arquivos em seu CWD. Se você está no diretório foo e está compilando foo / unittest / bar.c, e inclui bar.h, "bar.h" funciona e <bar.h> não.
1
Pessoas @Maxim discordar porque o comportamento que você descreve não é C. padrão
osvein
2
@ Spookbuster Certo, o padrão diz ambos <filename>e "filename"procura por locais definidos pela implementação.
Maxim Egorushkin
14

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

Chayim Friedman
fonte
1
Depois de uma resposta perfeita estar disponível há anos, por que enviar uma, isso é flagrantemente errado? Embora comum, a #includediretiva não está estritamente relacionada a arquivos.
IInspectable #
@ Inspecionável, explique por que não está relacionado a arquivos.
Behrooz Karjoo
11

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

Um #include com aspas procurará apenas um arquivo (e, "de uma maneira dependente da implementação", bleh). O que significa que, em inglês normal, ele tentará aplicar o caminho / nome do arquivo que você lança nele e não precederá um caminho do sistema ou o violará de outra forma.

Além disso, se #include "" falhar, é relido como #include <> pelo padrão.

A documentação do gcc tem uma descrição (específica do compilador) que, embora seja específica do gcc e não do padrão, é muito mais fácil de entender do que a conversa do advogado sobre os padrões ISO.

Damon
fonte
No entanto, o uso de colchetes angulares ou aspas não afeta a maneira como os arquivos são incluídos, é exatamente o mesmo: o pré-processador cria essencialmente um grande arquivo de origem copiando e copiando o código de arquivos de inclusão para o arquivo de origem original antes de fornecer -lo para o compilador (pré-processador faz outra coisa, como sustitution #define, #if avaliação, etc. mas o processamento #include é assim tão fácil)
Loghorn
E os conflitos? por exemplo, digamos que eu tenho zlib.hnos meus caminhos de pesquisa de 'usuário' e existe uma versão diferente no caminho de pesquisa do sistema, então #include <zlib.h>inclui a versão do sistema e a #include "zlib.h"minha?
8118
Aha, respondeu minha própria pergunta: stackoverflow.com/questions/21593/…
the_mandrill
Obrigado por reconhecer que o padrão (s) e as convenções típicas de implementação são relevantes aqui, em vez de simplesmente afirmar que é incognoscível porque não é especificado pelo padrão.
Kyle Strand
10
#include "filename" // User defined header
#include <filename> // Standard library header.

Exemplo:

O nome do arquivo aqui é 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

Na implementação da classe (por exemplo, Seller.cppe em outros arquivos que usarão o arquivo Seller.h), o cabeçalho definido pelo usuário agora deve ser incluído, da seguinte maneira:

#include "Seller.h"
Barbara
fonte
10
  • #include <> é para arquivos de cabeçalho predefinidos

Se o arquivo de cabeçalho for predefinido, você simplesmente escreveria o nome do arquivo de cabeçalho entre parênteses angulares e ficaria assim (supondo que tenhamos um nome de arquivo de cabeçalho predefinido iostream):

#include <iostream>
  • #include " " é para arquivos de cabeçalho que o programador define

Se você (o programador) escreveu seu próprio arquivo de cabeçalho, você deve escrever o nome do arquivo de aspas entre aspas. Portanto, suponha que você tenha escrito um arquivo de cabeçalho chamado myfile.h, este é um exemplo de como você usaria a diretiva de inclusão para incluir esse arquivo:

#include "myfile.h"
VishalSoni
fonte
2
Não tem nada a ver com arquivos de cabeçalho predefinidos. Tem a ver com locais a serem pesquisados.
C Johnson
9

Muitas das respostas aqui se concentram nos caminhos que o compilador pesquisará para encontrar o arquivo. Enquanto isso é o que a maioria dos compiladores faz, é permitido que um compilador em conformidade seja pré-programado com os efeitos dos cabeçalhos padrão e trate, digamos, #include <list>como uma opção, e ele não precisa existir como um arquivo.

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

sp2danny
fonte
9
#include <abc.h>

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

#include "xyz.h"

dirá 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 -Ipastas definidas.

Christy Wald
fonte
7

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

O primeiro é #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 "filename", que informa ao pré-processador para procurar o arquivo no diretório atual primeiro e depois nos locais predefinidos que o usuário configurou.

virat
fonte
7

Formulário 1 - #include <xxx>

Primeiro, procura a presença do arquivo de cabeçalho no diretório atual de onde a diretiva é chamada. Se não for encontrado, ele procurará na lista pré-configurada de diretórios padrão do sistema.

Formulário 2 - #include "xxx"

Isso procura a presença do arquivo de cabeçalho no diretório atual de onde a diretiva é chamada.


A lista exata de diretórios de pesquisa depende do sistema de destino, de como o GCC está configurado e de onde está instalado. Você pode encontrar a lista de diretórios de pesquisa do seu compilador GCC executando-a com a opção -v.

Você pode adicionar diretórios adicionais ao caminho de pesquisa usando - I dir , o que faz com que o diretório seja pesquisado após o diretório atual (para a forma de cotação da diretiva) e antes dos diretórios padrão do sistema.


Basicamente, o formato "xxx" nada mais é do que pesquisar no diretório atual; se não for encontrado caindo de volta o formulário

Darshan L
fonte
3
Se você decidir responder a uma pergunta antiga que tenha respostas bem estabelecidas e corretas, adicionar uma nova resposta no final do dia pode não lhe dar crédito. Se você tiver alguma informação nova e distinta, ou estiver convencido de que as outras respostas estão erradas, adicione uma nova resposta, mas "mais uma resposta" fornecerá a mesma informação básica muito tempo depois que a pergunta for feita normalmente " você ganha muito crédito.
Jonathan Leffler
1
@ Jonathan Leffler Você pode me indicar a resposta "bem estabelecida" que você acha que é tão concisa e precisa quanto a resposta de Darshan?
personal_cloud
1
A descrição do #include "header.h"formulário não é precisa, @personal_cloud. Considero a resposta de piCookie e Yann Droneaud a mais relevante, pois identificam de onde vêm as informações. Também não acho que a resposta mais votada seja totalmente satisfatória.
Jonathan Leffler
Por que essa resposta é exibida na parte superior, enquanto duas respostas mais abaixo há mais de 650 votos? Essa resposta me confundiu, porque não corresponde ao comportamento observado por mim. Pode ser porque a última frase está quebrada devido à falta de colchetes angulares. Não sei ao certo o que isso significa.
Neonit
6

A #include <filename>é usado quando um arquivo de sistema está a ser 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ê deve usar a #include "filename"sintaxe.

srsci
fonte
6

o "<nome do arquivo>" pesquisa nos locais padrão da biblioteca C

enquanto "filename" também pesquisa no diretório atual.

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

jigar karangiya
fonte
4
Que novas informações adicionam essa resposta às outras?
Daniel Langr 28/03/19
5

A regra geral simples é usar colchetes angulares para incluir arquivos de cabeçalho que acompanham o compilador. Use aspas duplas para incluir outros arquivos de cabeçalho. A maioria dos compiladores faz dessa maneira.

1.9 - Os arquivos de cabeçalho explicam com mais detalhes as diretrizes do pré-processador. Se você é um programador iniciante, essa página deve ajudá-lo a entender tudo isso. Eu aprendi a partir daqui, e tenho seguido no trabalho.

Eakan Gopalakrishnan
fonte
4
#include <filename>

é usado quando você deseja usar o arquivo de cabeçalho do sistema C / C ++ ou das bibliotecas do 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 pasta do projeto ou em outro lugar.

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

Hafiz Shehbaz Ali
fonte
3

#include <filename>

  • O pré-processador procura de uma maneira dependente da implementação. Diz ao compilador para procurar o diretório onde os arquivos de cabeçalho do sistema são mantidos.
  • Esse método geralmente usa para encontrar arquivos de cabeçalho padrão.

#include "filename"

  • Isso diz ao compilador para procurar arquivos de cabeçalho onde o programa está sendo executado. Se falhou, ele se comporta como#include <filename> e procura o arquivo de cabeçalho no local onde os arquivos de cabeçalho do sistema estão armazenados.
  • Esse método geralmente usado para identificar arquivos de cabeçalho definidos pelo usuário (arquivos de cabeçalho criados pelo usuário). Lá para não use isso se você quiser chamar a biblioteca padrão, pois leva mais tempo de compilação do que #include <filename>.
Kalana
fonte
2

Para ver a ordem de pesquisa em 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 : posix InstalledDir: Library / Developer / CommandLineTools / usr / bin
"/ Library / Developer / CommandLineTools / usr / bin / clang" -cc1 - triplo x86_64-apple-macosx10.14.0 -Wdeprecated-objc-isa-use -Werror = deprecated-objc-isa-use -E -disable-free - disable-llvm-verifier -discard-value-names -main-file-name null -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 / Usuários / hogstrom -ferror-limit 19 -fmessage-length 80 -stack-protector 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 versão 10.0.0 (clang-1000.10.44.2) destino 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
/ 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 (diretório de estrutura)
Fim da lista de pesquisa.

Hogstrom
fonte
1
#include <file> 

Inclui um arquivo em que o diretório de inclusão padrão é.

#include "file" 

Inclui um arquivo no diretório atual em que foi compilado.

IAmAUser
fonte
-2

Existem duas maneiras de escrever a instrução #include.

#include"filename"
#include<filename>

O significado de cada formulário é

#include"mylib.h"

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

#include<mylib.h>

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

O caminho de pesquisa de inclusão não passa de uma lista de diretórios que seriam pesquisados ​​pelo arquivo que está sendo incluído. Os compiladores C diferentes permitem definir o caminho de pesquisa de maneiras diferentes.

Noshiii
fonte
1
Se você decidir responder a uma pergunta antiga que tenha respostas bem estabelecidas e corretas, adicionar uma nova resposta no final do dia pode não lhe dar crédito. Se você tiver alguma informação nova e distinta, ou estiver convencido de que as outras respostas estão erradas, adicione uma nova resposta, mas "mais uma resposta" fornecerá a mesma informação básica muito tempo depois que a pergunta for feita normalmente " você ganha muito crédito.
Jonathan Leffler