C++ #include <filename> 和 #include "filename" 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21593/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between #include <filename> and #include "filename"?
提问by quest49
In the C and C++ programming languages, what is the difference between using angle brackets and using quotes in an include
statement, as follows?
在 C 和 C++ 编程语言中,在include
语句中使用尖括号和使用引号有什么区别,如下所示?
#include <filename>
#include "filename"
#include <filename>
#include "filename"
回答by quest49
In practice, the difference is in the location where the preprocessor searches for the included file.
实际上,区别在于预处理器搜索包含文件的位置。
For #include <filename>
the preprocessor searches in an implementation dependent manner, normally in search directories pre-designated by the compiler/IDE. This method is normally used to include standard library header files.
对于#include <filename>
预处理器以依赖于实现的方式搜索,通常在编译器/IDE 预先指定的搜索目录中。此方法通常用于包含标准库头文件。
For #include "filename"
the preprocessor searches first in the same directory as the file containing the directive, and then follows the search path used for the #include <filename>
form. This method is normally used to include programmer-defined header files.
对于#include "filename"
预处理器,首先在与包含指令的文件相同的目录中搜索,然后按照用于#include <filename>
表单的搜索路径进行搜索。此方法通常用于包含程序员定义的头文件。
A more complete description is available in the GCC documentation on search paths.
回答by piCookie
The only way to know is to read your implementation's documentation.
知道的唯一方法是阅读您的实现文档。
In the C standard, section 6.10.2, paragraphs 2 to 4 state:
在C 标准中,第 6.10.2 节的第 2 至 4 段指出:
A preprocessing directive of the form
#include <h-char-sequence> new-line
searches a sequence of implementation-defined places for a headeridentified uniquely by the specified sequence between the
<
and>
delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined.A preprocessing directive of the form
#include "q-char-sequence" new-line
causes the replacement of that directive by the entire contents of the source fileidentified by the specified sequence between the
"
delimiters. The named source fileis searched for in an implementation-defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read#include <h-char-sequence> new-line
with the identical contained sequence (including
>
characters, if any) from the original directive.A preprocessing directive of the form
#include pp-tokens new-line
(that does not match one of the two previous forms) is permitted. The preprocessing tokens after
include
in the directive are processed just as in normal text. (Each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens.) The directive resulting after all replacements shall match one of the two previous forms. The method by which a sequence of preprocessing tokens between a<
and a>
preprocessing token pair or a pair of"
characters is combined into a single header name preprocessing token is implementation-defined.Definitions:
h-char: any member of the source character set except the new-line character and
>
q-char: any member of the source character set except the new-line character and
"
形式的预处理指令
#include <h-char-sequence> new-line
在实现定义的位置序列中搜索由和分隔符之间的指定序列唯一标识的标头,并导致该指令被标头的全部内容替换。如何指定位置或标识的标头是实现定义的。
<
>
形式的预处理指令
#include "q-char-sequence" new-line
导致用分隔符之间的指定序列标识的源文件的全部内容替换该指令
"
。以实现定义的方式搜索命名的源文件。如果不支持此搜索,或者如果搜索失败,则重新处理指令,就好像它读取#include <h-char-sequence> new-line
具有与
>
原始指令相同的包含序列(包括字符,如果有)。形式的预处理指令
#include pp-tokens new-line
(与前两种形式之一不匹配)是允许的。
include
指令中的预处理标记就像在普通文本中一样处理。(当前定义为宏名称的每个标识符都由其预处理标记的替换列表替换。)所有替换后产生的指令应匹配前两种形式之一。将 a<
和>
预处理标记对或一对"
字符之间的预处理标记序列组合成单个标头名称预处理标记的方法是实现定义的。定义:
h-char:源字符集的任何成员,除了换行符和
>
q-char:源字符集的任何成员,除了换行符和
"
回答by aib
The sequence of characters between < and > uniquely refer to a header, which isn't necessarily a file. Implementations are pretty much free to use the character sequence as they wish. (Mostly, however, just treat it as a file name and do a search in the include path, as the other posts state.)
< 和 > 之间的字符序列唯一地引用一个标题,它不一定是一个文件。实现可以随意使用字符序列。(但是,大多数情况下,只需将其视为文件名并在包含路径中进行搜索,就像其他帖子所述。)
If the #include "file"
form is used, the implementation first looks for a file of the given name, if supported. If not (supported), or if the search fails, the implementation behaves as though the other (#include <file>
) form was used.
如果使用#include "file"
表单,则实现首先查找给定名称的文件(如果支持)。如果不支持(支持),或者如果搜索失败,则实现的行为就像使用了其他 ( #include <file>
) 形式。
Also, a third form exists and is used when the #include
directive doesn't match either of the forms above. In this form, some basic preprocessing (such as macro expansion) is done on the "operands" of the #include
directive, and the result is expected to match one of the two other forms.
此外,存在第三种形式,当#include
指令与上述任何一种形式都不匹配时使用。在这种形式中,对#include
指令的“操作数”进行了一些基本的预处理(例如宏扩展),并且预期结果与其他两种形式之一匹配。
回答by Yann Droneaud
Some good answers here make references to the C standard but forgot the POSIX standard, especially the specific behavior of the c99 (e.g. C compiler)command.
这里的一些好的答案引用了 C 标准,但忘记了 POSIX 标准,尤其是c99(例如 C 编译器)命令的特定行为。
According to The Open Group Base Specifications Issue 7,
根据The Open Group Base Specification Issue 7,
-Idirectory
Change the algorithm for searching for headers whose names are not absolute pathnames to look in the directory named by the directorypathname before looking in the usual places. Thus, headers whose names are enclosed in double-quotes ( "" ) shall be searched for first in the directory of the file with the #includeline, then in directories named in -Ioptions, and last in the usual places. For headers whose names are enclosed in angle brackets ( "<>" ), the header shall be searched for only in directories named in -Ioptions and then in the usual places. Directories named in -Ioptions shall be searched in the order specified. Implementations shall support at least ten instances of this option in a single c99command invocation.
-I目录
更改搜索名称不是绝对路径名的标头的算法,以便在查找通常位置之前先查找由目录路径名命名的目录。因此,名称用双引号 ( "" ) 括起来的标题应首先在带有#include行的文件目录中搜索,然后在-I选项中命名的目录中,最后在通常的位置中搜索。对于名称括在尖括号 ( "<>" ) 中的标题,应仅在-I选项中命名的目录中搜索标题,然后在通常的位置搜索。-I选项中命名的目录应按指定的顺序进行搜索。c99命令调用。
So, in a POSIX compliant environment, with a POSIX compliant C compiler, #include "file.h"
is likely going to search for ./file.h
first, where .
is the directory where is the file with the #include
statement, while #include <file.h>
, is likely going to search for /usr/include/file.h
first, where /usr/include
is your system defined usual placesfor headers (it's seems not defined by POSIX).
因此,在符合 POSIX 的环境中,使用符合 POSIX 的 C 编译器,#include "file.h"
很可能会首先搜索带有语句的文件./file.h
所在.
的目录#include
,而#include <file.h>
, 可能会首先搜索/usr/include/file.h
,/usr/include
您的系统在哪里定义标题的常用位置(似乎不是由 POSIX 定义的)。
回答by Suraj Jain
GCC documentation saysthe following about the difference between the two:
GCC 文档说明了以下两者之间的区别:
Both user and system header files are included using the preprocessing directive
‘#include'
. It has two variants:
#include <file>
This variant is used for system header files. It searches for a file named file in a standard list of system directories. You can prepend directories to this list with the
-I
option (see Invocation).
#include "file"
This variant is used for header files of your own program. It searches for a file named file first in the directory containing the current file, then in the quote directories and then the same directories used for
<file>
. You can prepend directories to the list of quote directories with the-iquote
option. The argument of‘#include'
, whether delimited with quote marks or angle brackets, behaves like a string constant in that comments are not recognized, and macro names are not expanded. Thus,#include <x/*y>
specifies inclusion of a system header file namedx/*y
.However, if backslashes occur within file, they are considered ordinary text characters, not escape characters. None of the character escape sequences appropriate to string constants in C are processed. Thus,
#include "x\n\\y"
specifies a filename containing three backslashes. (Some systems interpret ‘\' as a pathname separator. All of these also interpret‘/'
the same way. It is most portable to use only‘/'
.)It is an error if there is anything (other than comments) on the line after the file name.
使用预处理指令包含用户和系统头文件
‘#include'
。它有两种变体:
#include <file>
此变体用于系统头文件。它在系统目录的标准列表中搜索名为 file 的文件。您可以使用
-I
选项将目录添加到此列表中(请参阅Invocation)。
#include "file"
此变体用于您自己程序的头文件。它首先在包含当前文件的目录中搜索名为 file 的文件,然后在引用目录中搜索,然后在用于
<file>
. 您可以使用该-iquote
选项将目录添加到引用目录列表中。的参数‘#include'
,无论是用引号还是尖括号分隔,其行为都类似于字符串常量,因为无法识别注释,并且不会扩展宏名称。因此,#include <x/*y>
指定包含名为x/*y
.但是,如果文件中出现反斜杠,则它们被视为普通文本字符,而不是转义字符。不处理适用于 C 中字符串常量的字符转义序列。因此,
#include "x\n\\y"
指定包含三个反斜杠的文件名。(某些系统将 '\' 解释为路径名分隔符。所有这些也以‘/'
相同的方式解释。仅使用 最便携‘/'
。)如果文件名后的行中有任何内容(注释除外),则这是一个错误。
回答by Stefan Steiger
It does:
它确实:
"mypath/myfile" is short for ./mypath/myfile
with .
being either the directory of the file where the #include
is contained in, and/or the current working directory of the compiler, and/or the default_include_paths
用.
是其中所述文件的任一目录#include
被包含在,和/或编译器的当前工作目录,和/或default_include_paths
and
和
<mypath/myfile> is short for <defaultincludepaths>/mypath/myfile
If ./
is in <default_include_paths>
, then it doesn't make a difference.
如果./
是 in <default_include_paths>
,那么它没有区别。
If mypath/myfile
is in another include directory, the behavior is undefined.
如果mypath/myfile
在另一个包含目录中,则行为未定义。
回答by Stefan Steiger
The <file>
include tells the preprocessor to search in -I
directories and in predefined directories first, then in the .c file's directory. The "file"
include tells the preprocessor to search the source file's directory first, and then revert to -I
and predefined. All destinations are searched anyway, only the order of search is different.
在<file>
包括告诉预处理到搜索-I
目录和在预定义的目录第一,然后在.c文件的目录。在"file"
包括告诉预处理器搜索源文件的目录第一,然后恢复到-I
和预定义的。无论如何搜索所有目的地,只是搜索顺序不同。
The 2011 standard mostly discusses the include files in "16.2 Source file inclusion".
2011标准主要讨论了“16.2源文件包含”中的包含文件。
2 A preprocessing directive of the form
# include <h-char-sequence> new-line
searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the < and > delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined.
3 A preprocessing directive of the form
# include "q-char-sequence" new-line
causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " delimiters. The named source file is searched for in an implementation-defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read
# include <h-char-sequence> new-line
with the identical contained sequence (including > characters, if any) from the original directive.
2 形式的预处理指令
# include <h-char-sequence> new-line
在实现定义的位置序列中搜索由 < 和 > 分隔符之间的指定序列唯一标识的标头,并导致该指令被标头的全部内容替换。如何指定位置或标识的标头是实现定义的。
3 形式的预处理指令
# include "q-char-sequence" new-line
导致用 " 分隔符之间的指定序列标识的源文件的全部内容替换该指令。以实现定义的方式搜索指定的源文件。如果不支持此搜索,或者搜索失败,指令被重新处理,就好像它读取
# include <h-char-sequence> new-line
具有与原始指令相同的包含序列(包括 > 字符,如果有)。
Note that "xxx"
form degrades to <xxx>
form if the file is not found. The rest is implementation-defined.
请注意,如果找不到文件,则"xxx"
表单会降级为<xxx>
表单。其余的是实现定义的。
回答by adrian
#include <file.h>
tells the compiler to search for the header in its "includes" directory, e.g. for MinGW the compiler would search for file.h
in C:\MinGW\include\ or wherever your compiler is installed.
#include <file.h>
告诉编译器在其“includes”目录中搜索头文件,例如,对于 MinGW,编译器将file.h
在 C:\MinGW\include\ 或编译器安装的任何位置搜索。
#include "file"
tells the compiler to search the current directory (i.e. the directory in which the source file resides) for file
.
#include "file"
告诉编译器在当前目录(即源文件所在的目录)中搜索file
.
You can use the -I
flag for GCC to tell it that, when it encounters an include with angled brackets, it should also search for headers in the directory after -I
. GCC will treat the directory after the flag as if it were the includes
directory.
您可以使用-I
GCC的标志来告诉它,当它遇到带尖括号的包含时,它还应该在-I
. GCC 会将标志后的目录视为includes
目录。
For instance, if you have a file called myheader.h
in your own directory, you could say #include <myheader.h>
if you called GCC with the flag -I .
(indicating that it should search for includes in the current directory.)
例如,如果您myheader.h
在自己的目录中调用了一个文件,您可以说#include <myheader.h>
是否使用标志调用了 GCC -I .
(表明它应该在当前目录中搜索包含。)
Without the -I
flag, you will have to use #include "myheader.h"
to include the file, or move myheader.h
to the include
directory of your compiler.
如果没有-I
标志,您将不得不使用#include "myheader.h"
包含文件,或移动myheader.h
到include
编译器的目录。
回答by skyking
By the standard - yes, they are different:
按照标准 - 是的,它们是不同的:
A preprocessing directive of the form
#include <h-char-sequence> new-line
searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the
<
and>
delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined.A preprocessing directive of the form
#include "q-char-sequence" new-line
causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the
"
delimiters. The named source file is searched for in an implementation-defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read#include <h-char-sequence> new-line
with the identical contained sequence (including
>
characters, if any) from the original directive.A preprocessing directive of the form
#include pp-tokens new-line
(that does not match one of the two previous forms) is permitted. The preprocessing tokens after
include
in the directive are processed just as in normal text. (Each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens.) The directive resulting after all replacements shall match one of the two previous forms. The method by which a sequence of preprocessing tokens between a<
and a>
preprocessing token pair or a pair of"
characters is combined into a single header name preprocessing token is implementation-defined.Definitions:
h-char: any member of the source character set except the new-line character and
>
q-char: any member of the source character set except the new-line character and
"
形式的预处理指令
#include <h-char-sequence> new-line
在实现定义的位置序列中搜索由
<
和>
分隔符之间的指定序列唯一标识的标头,并导致该指令被标头的全部内容替换。如何指定位置或标识的标头是实现定义的。形式的预处理指令
#include "q-char-sequence" new-line
导致用
"
分隔符之间的指定序列标识的源文件的全部内容替换该指令。以实现定义的方式搜索命名的源文件。如果不支持此搜索,或者如果搜索失败,则重新处理指令,就好像它读取#include <h-char-sequence> new-line
具有与
>
原始指令相同的包含序列(包括字符,如果有)。形式的预处理指令
#include pp-tokens new-line
(与前两种形式之一不匹配)是允许的。
include
指令中的预处理标记就像在普通文本中一样处理。(当前定义为宏名称的每个标识符都由其预处理标记的替换列表替换。)所有替换后产生的指令应匹配前两种形式之一。将 a<
和>
预处理标记对或一对"
字符之间的预处理标记序列组合成单个标头名称预处理标记的方法是实现定义的。定义:
h-char:源字符集的任何成员,除了换行符和
>
q-char:源字符集的任何成员,除了换行符和
"
Note that the standard does not tell any relation between the implementation-defined manners. The first form searches in one implementation-defined way, and the other in a (possibly other) implementation-defined way. The standard also specifies that certain include files shall be present (for example, <stdio.h>
).
请注意,该标准没有说明实现定义的方式之间的任何关系。第一种形式以一种实现定义的方式搜索,另一种以(可能是其他)实现定义的方式搜索。该标准还规定应存在某些包含文件(例如,<stdio.h>
)。
Formally you'd have to read the manual for your compiler, however normally (by tradition) the #include "..."
form searches the directory of the file in which the #include
was found first, and then the directories that the #include <...>
form searches (the include path, eg system headers).
正式地,您必须阅读编译器的手册,但是通常(根据传统)#include "..."
表单搜索#include
首先找到的文件的目录,然后#include <...>
搜索表单搜索的目录(包含路径,例如系统头文件) )。
回答by riderBill
Thanks for the great answers, esp. Adam Stelmaszczyk and piCookie, and aib.
感谢您的出色回答,尤其是。Adam Stelmaszczyk 和 piCookie,以及 aib。
Like many programmers, I have used the informal convention of using the "myApp.hpp"
form for application specific files, and the <libHeader.hpp>
form for library and compiler system files, i.e. files specified in /I
and the INCLUDE
environment variable, for years thinking that was the standard.
像许多程序员一样,多年来我一直使用非正式约定,将"myApp.hpp"
表单用于特定于应用程序的文件,以及<libHeader.hpp>
用于库和编译器系统文件的表单,即在/I
和INCLUDE
环境变量中指定的文件,多年来一直认为这是标准。
However, the C standard states that the search order is implementation specific, which can make portability complicated. To make matters worse, we use jam, which automagically figures out where the include files are. You can use relative or absolute paths for your include files. i.e.
但是,C 标准声明搜索顺序是特定于实现的,这会使可移植性变得复杂。更糟糕的是,我们使用 jam,它会自动找出包含文件的位置。您可以为包含文件使用相对或绝对路径。IE
#include "../../MyProgDir/SourceDir1/someFile.hpp"
Older versions of MSVS required double backslashes (\\), but now that's not required. I don't know when it changed. Just use forward slashes for compatibility with 'nix (Windows will accept that).
旧版本的 MSVS 需要双反斜杠 (\\),但现在不需要了。不知道什么时候变了 只需使用正斜杠与 'nix 兼容(Windows 会接受)。
If you are reallyworried about it, use "./myHeader.h"
for an include file in the same directory as the source code (my current, very large project has some duplicate include file names scattered about--really a configuration management problem).
如果您真的很担心,请使用"./myHeader.h"
与源代码位于同一目录中的包含文件(我当前的非常大的项目有一些重复的包含文件名散布在周围——这确实是一个配置管理问题)。
Here's the MSDN explanationcopied here for your convenience).
为方便起见,此处复制了MSDN 说明)。
Quoted form
The preprocessor searches for include files in this order:
- In the same directory as the file that contains the #include statement.
- In the directories of the currently opened include files, in the reverse order in which
they were opened. The search begins in the directory of the parent include file and
continues upward through the directories of any grandparent include files.- Along the path that's specified by each
/I
compiler option.- Along the paths that are specified by the
INCLUDE
environment variable.Angle-bracket form
The preprocessor searches for include files in this order:
- Along the path that's specified by each
/I
compiler option.- When compiling occurs on the command line, along the paths that are specified by the
INCLUDE
environment variable.
引用形式
预处理器按以下顺序搜索包含文件:
- 与包含#include 语句的文件位于同一目录中。
- 在当前打开的包含文件的目录中,按照打开
它们的相反顺序。搜索从父包含文件的目录开始,并
继续向上遍历任何祖父包含文件的目录。- 沿着每个
/I
编译器选项指定的路径。- 沿着由
INCLUDE
环境变量指定的路径。角括号形式
预处理器按以下顺序搜索包含文件:
- 沿着每个
/I
编译器选项指定的路径。- 当编译发生在命令行上时,沿着
INCLUDE
环境变量指定的路径。