#include <filename>和#include“filename”有什么区别?

在C和C ++编程语言中,在括号中使用尖括号和使用引号之间有什么区别,如下所示?

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

区别在于预处理程序search包含文件的位置。

对于#include "filename" ,预处理程序在与包含指令的文件相同的目录中search,然后像#include <filename> 。 此方法通常用于包含程序员定义的头文件。

对于#include <filename> ,预处理器以实现相关的方式search,通常在由编译器/ IDE预先指定的search目录中search。 此方法通常用于包含标准库头文件。

要知道的唯一方法是阅读你的实现的文档。

在C标准中 ,第6.10.2节第2至4款规定:

  • 表单的预处理指令

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

    search一系列实现定义的位置,以寻找由<>分隔符之间的指定序列唯一标识的头部,并使该指令replace头部的全部内容。 如何指定位置或标识的是实现定义的。

  • 表单的预处理指令

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

    将导致用指定序列标识的源文件的全部内容替代该指令,该指定序列在"分隔符"之间,以实现定义的方式search指定的源文件,如果不支持该search,或者search失败,该指令被重新处理,就像它读取

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

    与原指令相同的包含序列(包括>字符,如果有的话)。

  • 表单的预处理指令

     #include pp-tokens new-line 

    (不符合前面两个表格之一)是允许的。 include在指令中的预处理标记与普通文本一样处理。 (当前被定义为macros名称的每个标识符被其预处理令牌的replace列表所取代。)在所有replace之后产生的指令应与前两个forms中的一个匹配。 预处理令牌对和一对"字符之间的预处理令牌序列组合为单个头名称预处理令牌的方法是实现定义的。

定义:

  • h-char:源字符集中除换行符和>以外的任何成员

  • q-char:源字符集的任何成员,除了换行符和"

<和>之间的字符序列唯一地指代一个头,而不一定是一个文件。 他们希望使用字符序列的实现非常自由。 (但是,大多数情况下,只要将其视为文件名,并在包含path中进行search,就像其他post所述)。

如果使用#include "file"forms,则实现将首先查找给定名称的文件(如果支持)。 如果没有(支持),或者如果search失败,那么实现就像其他( #include <file> )表单被使用一样。

另外,还有第三种forms存在,当#include指令不符合上述任何一种forms时,就会使用这种forms。 在这种forms下,一些基本的预处理(比如macros扩展)是在#include指令的“操作数”上完成的,结果可能与其他两种forms中的一种匹配。

这里有一些很好的答案引用了C标准,但忘记了POSIX标准,特别是c99(例如C编译器)命令的具体行为。

根据“开放组织基本规范”第7期 ,

-I 目录

在查找通常位置之前,更改search名称不是绝对path名的标题的algorithm以查找由目录path名指定的目录 。 因此,名称用双引号(“”)括起来的标题首先应在文件目录中用#include行search,然后在-I选项中指定的目录中search,最后在通常的地方search。 对于名称用尖括号(“<>”)括起来的标题,只能在-I选项中指定的目录中search标题,然后在通常的地方search标题。 以-I选项命名的目录应按指定的顺序进行search。 实现应该在一个c99命令调用中支持至less十个这个选项的实例。

因此,在符合POSIX的环境中,使用符合POSIX标准的C编译器, #include "file.h"可能首先search./file.h . 是包含#include语句的文件所在的目录,而#include <file.h>可能首先search/usr/include/file.h ,其中/usr/include是系统定义的常用位置标题(它似乎没有被POSIX定义)。

它确实:

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

. 是包含#include的文件的目录,和/或编译器的当前工作目录,和/或default_include_paths

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

如果./<default_include_paths> ,那么它没有区别。

如果mypath/myfile位于另一个包含目录中,则行为是未定义的。

海湾合作委员会文件说明了以下两者之间的区别:

用户和系统头文件都包含在预处理指令'#include' 。 它有两个变种:

#include <file>

这个变体用于系统头文件。 它在系统目录的标准列表中search名为file的文件。 您可以使用-I选项将目录添加到此列表中(请参阅调用 )。

#include "file"

这个变体用于你自己程序的头文件。 它在包含当前文件的目录中首先search名为file的文件,然后在quote目录中search用于<file>的相同目录。 您可以使用-iquote选项将目录预先添加到引用目录列表中。 '#include'的参数,无论是用引号还是尖括号分隔,都像string常量一样,注释不被识别,macros名称不被扩展。 因此, #include <x/*y>指定包含名为x/*y的系统头文件。

但是,如果在文件内出现反斜杠,它们将被视为普通文本字符,而不是转义字符。 处理C中不适合string常量的字符转义序列。 因此, #include "x\n\\y"指定一个包含三个反斜杠的文件名。 (有些系统将'\'解释为一个path名分隔符,所有这些也都以同样的方式解释'/' ,只能使用'/'

如果文件名后面有任何内容(注释除外),则是错误的。

<file> include指示预处理器先在-I目录中search,然后在预定义的目录中search,然后在.c文件的目录中search。 "file"包含告诉预处理器首先search源文件的目录,然后恢复到-I和预定义。 无论如何,所有的目的地都被search,只有search的顺序是不同的。

2011标准主要讨论“16.2源文件包含”中的包含文件。

2表单的预处理指令

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

search一系列实现定义的位置,以寻找由<和>分隔符之间的指定序列唯一标识的头部,并使该指令replace头部的全部内容。 如何指定位置或标识的是实现定义的。

3表单的预处理指令

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

导致用指定序列标识的源文件的全部内容替代该指令,该指定序列在“分隔符”之间,以实现定义的方式search指定的源文件,如果不支持该search,或者search失败,该指令被重新处理,就像它读取

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

与原指令相同的包含序列(包括>字符,如果有的话)。

请注意,如果文件未find,则"xxx"forms将降级为<xxx>forms。 其余的是实现定义的。

按照标准 – 是的,它们是不同的:

  • 表单的预处理指令

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

    search一系列实现定义的位置,以寻找由<>分隔符之间的指定序列唯一标识的头部,并使该指令replace头部的全部内容。 如何指定位置或标识的是实现定义的。

  • 表单的预处理指令

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

    将导致用指定序列标识的源文件的全部内容替代该指令,该指定序列在"分隔符"之间,以实现定义的方式search指定的源文件,如果不支持该search,或者search失败,该指令被重新处理,就像它读取

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

    与原指令相同的包含序列(包括>字符,如果有的话)。

  • 表单的预处理指令

     #include pp-tokens new-line 

    (不符合前面两个表格之一)是允许的。 include在指令中的预处理标记与普通文本一样处理。 (当前被定义为macros名称的每个标识符被其预处理令牌的replace列表所取代。)在所有replace之后产生的指令应与前两个forms中的一个匹配。 预处理令牌对和一对"字符之间的预处理令牌序列组合为单个头名称预处理令牌的方法是实现定义的。

定义:

  • h-char:源字符集中除换行符和>以外的任何成员

  • q-char:源字符集的任何成员,除了换行符和"

请注意,标准没有说明实现定义的方式之间的任何关系。 第一种forms是以一种实现定义的方式search,另一种以(可能是其他)实现定义的方式search。 该标准还指定了某些包含文件(例如, <stdio.h> )。

在forms上,你必须阅读你的编译器的手册,但通常(通过传统) #include "..."formssearch文件的目录,其中#include <...>首先被发现,然后#include <...>表单search(包括path,例如系统标题)。

至less对于GCC版本<= 3.0,angular括号表单不会在包含文件和包含文件之间生成依赖关系。

所以,如果你想生成依赖关系规则(例如使用GCC -M选项),则必须使用引用forms来表示依赖关系树中应包含的文件。

(请参阅http://gcc.gnu.org/onlinedocs/cpp/Invocation.html

感谢您的好评,特别是 Adam Stelmaszczyk和piCookie,以及aib。

和许多程序员一样,我使用了"myApp.hpp"forms的应用程序特定文件的非正式惯例,以及库和编译器系统文件的<libHeader.hpp>forms,即在/IINCLUDE环境variables中指定的文件多年来认为这是标准。

然而,C标准规定search顺序是特定于实现的,这使得可移植性变得复杂。 更糟糕的是,我们使用jam,它会自动计算出包含文件的位置。 您可以使用相对或绝对path作为包含文件。 即

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

较旧版本的MSVS需要双反斜杠(\\),但现在不需要。 我不知道什么时候改变了。 只要使用正斜杠与'nix(Windows将接受)的兼容性。

如果你真的担心,使用"./myHeader.h"作为包含文件在与源代码相同的目录(我目前,非常大的项目有一些重复的包含文件名散落 – 真正的configurationpipe理问题)。

这里是为了您的方便复制在这里的MSDN解释 )。

引用表格

预处理器按以下顺序search包含文件:

  1. 在与包含#include语句的文件相同的目录中。
  2. 在当前打开的包含文件的目录中,按照与其相反的顺序
    他们被打开了。 search从父包含文件的目录开始
    继续向上通过任何祖父母包括文件的目录。
  3. 沿着每个/I编译器选项指定的path。
  4. 沿着由INCLUDE环境variables指定的path。

angular支架forms

预处理器按以下顺序search包含文件:

  1. 沿着每个/I编译器选项指定的path。
  2. 在命令行上进行编译时,沿着由INCLUDE环境variables指定的path进行编译。

对于#include ""编译器通常会search包含该文件的文件夹,然后search其他文件夹。 对于#include <>编译器不search当前文件的文件夹。

带有尖括号的#include将search要包含的文件的“实现相关的位置列表”(这是一个非常复杂的方式来表示“系统头文件”)。

带引号的#include将只search一个文件(和,“以实现相关的方式”,bleh)。 这意味着,在普通的英语中,它会尝试应用您所掷骰的path/文件名,而不会预先添加系统path或以其他方式篡改系统path。

另外,如果#include“”失败,则按标准重新读取为#include <>。

gcc文档有一个(特定于编译器的)描述,尽pipe它是特定于gcc而不是标准的,但是比ISO标准的律师风格的讨论更容易理解。

#include <>用于预定义的头文件

如果头文件是预定义的,那么你只需将头文件名写在尖括号中,它看起来像这样(假设我们有一个预定义的头文件名iostream):

#include < iostream>

#include“”是程序员定义的头文件

如果你(程序员)编写了你自己的头文件,那么你会用引号将头文件名写出来。 所以,假设你写了一个名为myfile.h的头文件,那么这是一个如何使用include指令来包含这个文件的例子:

#include“myfile.h

 #include "filename" // user defined header #include <filename> // standard library header. 

例如:这里的文件名是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 

在类实现中(例如Seller.cpp和其他将使用文件Seller.h的文件),现在应该包含用户定义的头文件,如下所示:

 #include "Seller.h" 

这里的许多答案都集中在编译器为了find文件而search的path上。 虽然这是大多数编译器所做的事情,但是符合的编译器可以使用标准头文件的效果进行预编程,并将#include <list>当作交换机来处理,而且根本不需要作为文件存在。

这不是纯粹的假设。 至less有一个编译器可以这样工作。 build议仅在标准头文件中使用#include <xxx>

在C ++中,以两种方式包含文件:

第一个是#include,它告诉预处理器在预定义的默认位置查找文件。 这个位置通常是INCLUDE环境variables,表示包含文件的path。

第二种是#include“filename”,它告诉预处理器首先在当前目录中查找文件,然后在用户设置的预定义位置查找它。

在引用系统文件时使用#include <filename> 。 这是一个头文件,可以在系统默认位置(如/usr/include/usr/local/include 。 对于需要包含在另一个程序中的自己的文件,您必须使用#include "filename"语法。

简单的通用规则是使用斜angular括号来包含编译器附带的头文件。 使用双引号来包含任何其他头文件。 大多数编译器都是这样做的。

1.9 – 头文件更详细地解释了预处理器指令。 如果你是一个新手程序员,该页面应该可以帮助你理解这一切。 我从这里学到了东西,我一直在工作。

 #include<abc.h> 

用于包含标准库文件。 所以他们将检查标准库标题所在的位置。

 #include "xyz.h" 

会告诉编译器包含用户定义的头文件。 因此,编译器将检查当前文件夹或-I定义的文件夹中的这些头文件

#include <filename>

当您要使用C / C ++系统或编译器库的头文件时使用。 这些库可以是stdio.h,string.h,math.h等

#include "path-to-file/filename"

当你想使用你自己的自定义头文件在你的项目文件夹或其他地方使用。

有关预处理器和标题的更多信息。 阅读C – 预处理器

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

#include包括由文件名标识的源文件到紧跟在该指令之后的行的当前源文件中。

指令的第一个版本只search标准的包含目录。 标准C ++库以及标准C库隐式包含在标准包含目录中。 标准include目录可以由用户通过编译器选项来控制。

第二个版本首先search当前文件所在的目录,只有当找不到该文件时,才search标准包含目录。

在没有find该文件的情况下,该程序是格式不正确的。

我相信,如果在当前目录中找不到包含在双引号中的标题,那么将在相同的系统path中查找包含angular括号的标题。

search头文件的顺序是不同的。 <XXX.h>倾向于首先search标准头,而“XXX.h”首先search工作空间的头文件。

#include <filename>

将从C ++库中find相应的文件。 这意味着如果在C ++库文件夹中有一个名为hello.h的文件, #include <hello.h>将加载它。

但,

#include "filename"

将在与源文件相同的目录中find该文件。

此外,

#include "path_to_file/filename"

将在您在path_to_file键入的目录中find该文件。

To include a predefined library header file , #include<filename> is used whereas to include user defined header file, #include "filename" is relevant.