c++ include用法




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

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

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

the " < filename > " searches in standard C library locations

whereas "filename" searches in the current directory as well.

Ideally, you would use <...> for standard C libraries and "..." for libraries that you write and are present in the current directory.


#include <filename>

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

#include "path-to-file/filename"

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

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


GCC文件说明了以下两者之间的区别:

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

#include <file>

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

#include "file"

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

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

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


#include <file> tells the compiler to search for the header in its includes directory, eg for MinGW the compiler would search for file in C:\MinGW\include\ or wherever your compiler is installed.

#include "file" tells the compiler to search the current directory (ie the directory in which the source file resides) for 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 . 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 -I . (indicating that it should search for includes in the current directory.)


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

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

2表单的预处理指令

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

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

3表单的预处理指令

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

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

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

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

请注意,如果未找到文件,则"xxx"格式会降级为<xxx>格式。 其余的是实现定义的。


The order of search header files is different. <XXX.h> prefer to search the standard headers first while "XXX.h" searches the workspace's header files first.


When you use #include <filename>, the pre-processor looking for the file in directtory of C\C++ header files (stdio.h\cstdio, string, vector, etc.). But, when you use #include "filename": first, the pre-processor looking for the file in the current directory, and if it doesn't here - he looking for it in the directory of C\C++ header files.


包含尖括号的#include将搜索要包含的文件的“依赖于实现的位置列表”(这是一种非常复杂的方式来表示“系统标题”)。

带引号的#include将只搜索一个文件(和,“以与实现相关的方式”,bleh)。 这意味着,在正常的英语中,它会尝试应用您在其上折腾的路径/文件名,并且不会预先添加系统路径或以其他方式篡改系统路径。

另外,如果#include“”失败,它将被标准重新读为#include <>。

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


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


它确实:

"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预处理程序以实现相关的方式进行搜索,通常在由编译器/ IDE预先指定的搜索目录中进行搜索。 此方法通常用于包含标准库头文件。


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


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

  • 表单的预处理指令

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

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

  • 表单的预处理指令

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

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

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

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

  • 表单的预处理指令

    #include pp-tokens new-line
    

    (不符合前两种形式之一)是允许的。 include在指令中的预处理标记与正常文本中的处理方式相同。 (当前被定义为一个宏名称的每个标识符被替换为预处理标记的替换列表所取代。)所有替换之后产生的指示应与前两个表单中的一个匹配。 一个<和一个预处理标记对或一对"字符之间的预处理标记序列组合为单个标头名称预处理标记的方法是实现定义的。

定义:

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

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

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

形式上,你必须阅读你的编译器的手册,但是通常(通过传统) #include "..."形式搜索首先找到#include的文件的目录,然后搜索#include <...>表单搜索(包含路径,例如系统标题)。


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

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


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

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

  • 表单的预处理指令

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

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

  • 表单的预处理指令

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

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

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

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

  • 表单的预处理指令

    #include pp-tokens new-line
    

    (不符合前两种形式之一)是允许的。 include在指令中的预处理标记与正常文本中的处理方式相同。 (当前被定义为一个宏名称的每个标识符被替换为预处理标记的替换列表所取代。)所有替换之后产生的指示应与前两个表单中的一个匹配。 一个<和一个预处理标记对或一对"字符之间的预处理标记序列组合为一个标头名称预处理标记的方法是实现定义的。

定义:

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

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


谢谢你的出色答案,尤其是 Adam Stelmaszczyk和piCookie,以及aib。

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

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

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

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

如果你真的担心它,使用"./myHeader.h"作为包含文件与源代码位于同一目录中(我当前的非常大的项目有一些重复的包含文件名 - 这实际上是一个配置管理问题)。

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

引用表格

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

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

角支架形式

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

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

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

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


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

#include包含由文件名标识的源文件,该文件紧接在该指令之后的行中的当前源文件中。

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

第二个版本首先搜索当前文件所在的目录,并且仅在找不到文件时才搜索标准包含目录。

在没有找到该文件的情况下,该程序不合格。


#include <abc.h>

用于包含标准库文件。 所以编译器会检查标准库标题所在的位置。

#include "xyz.h"

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


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

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

#include <iostream>
  • #include " "用于程序员定义的头文件

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

#include "myfile.h"




c-preprocessor