#include <文件名>和#include“文件名”有什么区别?


2353

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

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



对于Visual Studio的行为,请检查:docs.microsoft.com/en-us/cpp/preprocessor/...
smwikipedia

Answers:


1403

实际上,区别在于预处理器搜索包含文件的位置。

对于#include <filename>预处理器,以依赖于实现的方式进行搜索,通常在由编译器/ IDE预先指定的搜索目录中进行。此方法通常用于包括标准库头文件。

对于#include "filename"预处理程序,首先在与包含指令的文件相同的目录中搜索,然后遵循用于#include <filename>表单的搜索路径。此方法通常用于包括程序员定义的头文件。

有关搜索路径的GCC 文档中提供了更完整的描述。


135
语句:“预处理程序在同一目录中搜索...”在实践中可能是正确的,但标准指出“以实现定义的方式搜索命名的源文件”。请参阅piCookie的答案。
理查德·科登,

60
尽管您的答案似乎是“正确的”,但由于这是按惯例工作的实现方式,因此您应该仔细查看aib和piCookie的答案。他们都指出(以C标准的措词为后盾),真正的区别是包含“标头”与包含“源文件”(不,这并不意味着“ .h”与“。”。 C”)。在这种情况下,“源文件”可以(通常是,并且几乎总是应该)是“ .h”文件。标头不必一定是文件(例如,编译器可以包含静态编码的标头,而不是文件中的标头)。
丹莫丁

5
“ ...预处理器在与要编译的文件相同的目录中搜索要包含的文件。” 这句话并不完全正确。我对这个问题很感兴趣,因为我很好奇实际的答案是什么,但是我知道这是不对的,因为至少当使用-I指定附加包含路径时,它将使用gcc来搜索用#include“ filename指定的文件”。 h”
加布里埃尔南部的

9
请那些不喜欢答案的人举一个实际的例子,说明错误的地方。
0kcats

1
可以肯定的是,我最近在包含“相同”库中的标头时混合了这些语法,并最终导致了重新定义错误。如果我理解正确,请#include <...>使用系统上安装的软件包并#include "..."使用附近的存储库版本。我可能会倒退。无论哪种方式,打包标头中的include防护都带有下划线前缀。(这可能是软件包的约定,或者是一种有意避免两者混用的方法,尽管版本限定符对我而言更有意义。)
John P

714

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

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:源字符集的任何成员,除了换行符和 "



27
@piCookie <filename>和“ filename”都搜索实现定义的位置。那么区别是什么呢 ?
onmyway133

15
@Stefan,我只是引用标准,该标准未提及INCLUDE_PATH。您的实现可能会这样做,而我的可能不会。最初的问题通常是C,而不是专门用于gcc(我不认为使用INCLUDE_PATH)或Microsoft C(我认为确实是)或任何其他问题,因此无法一般性地回答,而必须引用每个实现的文档。
piCookie 2013年

12
与所有这些情况一样,具体示例(尤其是常见情况)非常有用,同样值得赞赏。不必要地钝化通用答案并没有太多实际用途。
vargonian

132
“这是C标准冗长而又无法回答您的问题的方式”
anatolyg 2015年

287

<和>之间的字符序列唯一地指的是标头,不一定是文件。实现几乎可以随意使用它们的字符序列。(但是,大多数情况下,只需将其视为文件名,然后在包含路径中进行搜索即可在其他帖子中声明。)

如果使用了#include "file"表单,则实现将首先查找具有给定名称的文件(如果支持)。如果(不受支持)或搜索失败,则该实现的行为就像另一个(#include <file>)形式。

另外,存在第三种形式,当#include指令与以上两种形式都不匹配时,将使用第三种形式。在这种形式中,对#include指令的“操作数”进行了一些基本的预处理(例如宏扩展),并且预期结果将与其他两种形式之一匹配。


50
+1,这可能是这里最简洁,最正确的答案。根据标准(piCookie在其答案中引用了该标准),唯一真正的区别是“标头”与“源文件”。搜索机制是实现定义的任一种方式。使用双引号意味着您打算包含一个“源文件”,而尖括号意味着您打算包含一个“标头”,正如您所说,该标头可能根本不是文件。
Dan Moulding)2009年

3
请参阅Dan Moulding对quest49答案的评论;标准标头不必采用文件形式,它们可以是内置的。
aib 2011年

10
十年来,我一直在阅读“标准标头不必以文件形式”。愿意提供一个真实的例子吗?
Maxim Egorushkin 2011年

12
@Maxim Yegorushkin:我也想不出任何现有的现实世界的例子。但是,除非标头不必是文件,否则没有完整的C11编译器可用于MS-DOS。这是因为某些C11标头名称与“ 8.3” MS-DOS文件名限制不兼容。
Dan Moulding 2012年

18
@MaximEgorushkin:该VAX / VMS C编译器保持所有C运行时库头在单个文本库文件(类似Unix的记录),以及所使用的之间的串<>作为键来索引到库中。
阿德里安·麦卡锡

117

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

根据开放团体基本规范第7期

-I 目录

更改搜索名称不是绝对路径名的标头的算法,以在查找普通位置之前先查找由目录路径名命名的目录。因此,应首先在文件目录中的#include行中搜索其名称包含在双引号(“”)中的标题,然后在-I选项命名的目录中进行搜索,最后在通常的位置中进行搜索。对于名称括在尖括号(“ <>”)中的标头,应仅在-I选项中命名的目录中然后在通常的位置中搜索标头。-I选项中命名的目录应按指定顺序搜索。 c99命令调用中。

因此,在符合POSIX的环境中,使用符合POSIX的C编译器,#include "file.h"可能会首先搜索./file.h,其中.#include语句的文件在哪里,而#include <file.h>,可能会首先搜索/usr/include/file.h/usr/include系统在哪里定义标头的通常位置(POSIX似乎未定义)。


1
文本的确切来源是什么?它来自2013年IEEE Std 1003.1的规范部分吗?
osgx

7
@osgx:可以在POSIX规范中找到该措辞(或非常相似的东西),c99这是C编译器的POSIX名称。(POSIX 2008标准几乎无法引用C11; 2013年对POSIX 2008的更新并未更改其引用的C标准。)
Jonathan Leffler

1
这也是我的第一个想法。gcc的手册页包括此内容,其他手册也包括此内容。库也有类似的东西- -L
Pryftan

50

GCC文档对两者之间的区别了以下几点:

使用预处理指令包括用户和系统头文件‘#include’。它有两个变体:

#include <file>

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

#include "file"

此变体用于您自己程序的头文件。它首先在包含当前文件的目录中搜索一个名为file的文件,然后在引号目录中搜索,然后在中使用相同的目录<file>。您可以使用-iquote选项将目录放在报价目录列表的前面。的论点‘#include’用引号或尖括号分隔)的行为类似于字符串常量,因为注释无法识别,宏名称也不会扩展。因此,#include <x/*y>指定包含名为的系统头文件x/*y

但是,如果文件中出现反斜杠,则将其视为普通文本字符,而不是转义字符。没有适合于C中字符串常量的字符转义序列被处理。从而,#include "x\n\\y"指定一个包含三个反斜杠的文件名。(某些系统将'\'解释为路径名分隔符。所有这些也以‘/’相同的方式解释。仅可移植使用‘/’。)

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


46

它确实:

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

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

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

如果./在中<default_include_paths>,则没有任何区别。

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


12
不,#include "mypath/myfile"不等于#include "./mypath/myfile"。就像piCookie的回答所说,双引号告诉编译器以实现定义的方式进行搜索-包括在为指定的位置进行搜索#include <...>。(实际上,它可能是等效的,但仅是因为,例如,至少在类似Unix的系统上,它/usr/include/mypath/myfile可以被称为/usr/include/./mypath/myfile。)
Keith Thompson

1
@Keith Thompson:是的,我在考虑我的Linux系统。显然,情况可能有所不同。尽管实际上,Windows作为非Posix操作系统也确实将/解释为路径分隔符,并且./也存在。
Stefan Steiger 2014年

1
然后-L dirpath选项将dirpath添加到defaultincludepaths,而不是给赋予了另一种含义.(如上所述)。这样做的后果预期这两个#include "..."#include <...>在搜索dirpath
Protongun

1
我认为这个答案是不正确的,因为这意味着总是在当前工作目录中查找包含双引号的标头。搜索机制更加详细;这个答案是不完整的。我没有在抱怨或抱怨中添加此评论,而是因为系统要求我添加评论以解释为什么我对此答案投了反对票。
卡罗·伍德

39

<file>包括告诉预处理到搜索-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>窗体。其余的是实现定义的。


4
您能否提供在C标准-I中指定此业务的位置的参考?
juanchopanza

1
我看不到参考-I
juanchopanza

2
那是“实现定义的”部分。

27

#include <file.h>告诉编译器在其“包含”目录中搜索标头,例如,对于MinGW,编译器将file.h在C:\ MinGW \ include \或安装了编译器的任何位置进行搜索。

#include "file"告诉编译器在当前目录(即源文件所在的目录)中搜索file

您可以使用-IGCC 的标志来告知它,当遇到带有尖括号的include时,它还应该在目录之后的标头中搜索-I。GCC会将标志后的目录视为includes目录。

例如,如果您myheader.h在自己的目录中有一个名为的文件,则可以说#include <myheader.h>是否使用带有标志的GCC来调用-I .(表明该文件应在当前目录中搜索包含)。

如果没有该-I标志,则必须使用它#include "myheader.h"来包含文件,或移动myheader.hinclude编译器的目录。


22

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

  • 形式的预处理指令

    #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 <...>搜索该表单搜索的目录(包括路径,例如系统头) )。


2
这与piCookie 七年前的回答大致相同。
凯尔·斯特兰德

5
@KyleStrand那是因为相同的文本是标准中相关部分的引用-该文本应该相同。实际答案不是相同的文本,而是有所不同-虽然我也意识到它会写在实现文档中,但我也注意到,还有一种传统的解释方法(我使用的大多数或所有编译器都尊重) 。
2016年

2
IMO在这里是最好的答案,因为它涵盖了标准所说的内容和大多数编译器实际所做的事情。
plugwash

17

特别是感谢您的出色回答。Adam Stelmaszczyk和piCookie,以及aib。

像许多程序员一样,我使用了非正式的约定,即将"myApp.hpp"表单用于特定于应用程序的文件,并且<libHeader.hpp>,即将表单用于库和编译器系统文件,即在中指定的文件/IINCLUDE环境变量,多年来一直认为这是标准。

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

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

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

如果您真的很担心,请使用"./myHeader.h"在与源代码相同的目录中一个包含文件(我当前的大型项目中有些重复的包含文件名分散存在,这确实是一个配置管理问题)。

为了方便起见,这里是MSDN解释复制在这里。

引用形式

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

  1. 与包含#include语句的文件位于同一目录中。
  2. 在当前打开的目录中,包含文件的顺序与
    打开时相反。搜索从父包含文件的目录开始,然后
    向上搜索所有祖父母包含文件的目录。
  3. 沿着每个/I编译器选项指定的路径。
  4. 沿INCLUDE环境变量指定的路径。

角括号形式

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

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

16

至少对于GCC版本<= 3.0,尖括号形式不会在包含的文件和包含的文件之间生成依赖关系。

因此,如果要生成依赖关系规则(例如,使用GCC -M选项),则必须对应包含在依赖关系树中的文件使用加引号的形式。

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


1
是的-有几种不同的方式来生成依赖关系。那是其中之一,但不是唯一的。
Pryftan

15

对于#include ""编译器,通常先搜索包含以下内容的文件的文件夹,然后再搜索其他文件夹。对于#include <>编译器,不搜索当前文件的文件夹。


1
不知道为什么人们不同意。
Maxim Egorushkin 2012年

我怀疑这是因为大多数人只编译其CWD中的文件。如果您在目录foo中,并且正在编译foo / unittest / bar.c,并且其中包含bar.h,则“ bar.h”有效,而<bar.h>无效。

1
@Maxim人持反对意见,因为你描述的行为不规范C.
osvein

2
@Spookbuster对,标准同时指出了两者<filename>"filename"搜索实现定义的位置。
Maxim Egorushkin

14

当您使用#include <filename>时,预处理器会在C \ C ++头文件的目录(stdio.h \ cstdio,字符串,向量等)中查找文件。但是,当您使用#include“ filename”时:首先,预处理器在当前目录中查找文件,如果不在此处,则在C \ C ++头文件目录中查找该文件。


1
经过多年的完美回答,为什么要提交一个答案,这显然是错误的?即使很常见,该#include指令也与文件完全不相关。
IInspectable

@IInspectable请解释为什么它与文件根本不相关。
Behrooz Karjoo

11

带尖括号的#include将搜索“与实现相关的位置列表”(这是说“系统标题”的非常复杂的方式),以查找要包含的文件。

带引号的#include只会搜索文件(并且,“以与实现相关的方式”,等等)。这意味着,用普通的英语,它将尝试应用您扔给它的路径/文件名,并且不会在系统路径前添加或篡改它。

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

海湾合作委员会的文件有一个(编译器特定的)描述,虽然是专门针对gcc和不标准,是一个更容易比的ISO标准的律师式的交谈,了解。


但是,使用尖括号或引号不会影响文件的包含方式,这是完全相同的:预处理器通过在复制文件之前将代码从包含文件粘贴到原始源文件中,从而将代码从粘贴文件中复制并粘贴,从而创建了一个大型源文件。它交给编译器(预处理器做其他事情,例如#define sustitution,#if评估等,但是#include处理就这么简单)
Loghorn

那冲突呢?例如,说我zlib.h在“用户”搜索路径中,并且系统搜索路径中存在其他版本,那么是否#include <zlib.h>包括系统版本并#include "zlib.h"包括我自己的版本?
the_mandrill 2011年

啊哈,回答我的问题:stackoverflow.com/questions/21593/...
the_mandrill

感谢您承认标准典型的实现约定在这里都是相关的,而不是简单地指出它是不可知的,因为它不是标准指定的。
凯尔·斯特兰德

10
#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和在将使用file的其他文件中Seller.h),现在应包括用户定义的标头,如下所示:

#include "Seller.h"

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

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

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

如果您(程序员)编写了自己的头文件,则应在头文件名中用引号引起来。因此,假设您编写了一个名为的头文件myfile.h,那么这是一个如何使用include指令包括该文件的示例:

#include "myfile.h"

2
它与预定义的头文件完全无关。它与要搜索的位置有关。
C约翰逊

9

此处的许多答案都集中在编译器将搜索以查找文件的路径上。尽管这是大多数编译器的工作方式,但是允许对符合标准的编译器进行预编程,使其具有标准标头的效果,并且可以将其#include <list>视为开关,并且根本不需要作为文件存在。

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


9
#include <abc.h>

用于包含标准库文件。因此,编译器将检查标准库头所在的位置。

#include "xyz.h"

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


7

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

第一个是#include,它告诉预处理器在预定义的默认位置中查找文件。此位置通常是一个INCLUDE环境变量,它指示包含文件的路径。

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


7

表格1-#include <xxx>

首先,在调用伪指令的当前目录中查找头文件的存在。如果找不到,它将在标准系统目录的预配置列表中搜索。

表格2-#include“ xxx”

这将在调用伪指令的当前目录中查找头文件的存在。


确切的搜索目录列表取决于目标系统,GCC的配置方式以及安装位置。您可以通过-v选项运行GCC编译器的搜索目录列表。

您可以使用-I dir将其他目录添加到搜索路径,这将导致在当前目录之后(对于指令的引号形式)在标准系统目录之前搜索dir。


基本上,“ xxx”的形式只不过是在当前目录中搜索;如果找不到,则退回表格


3
如果您决定回答一个已经建立并正确答案的较旧问题,那么一天中晚添加新答案可能不会给您任何功劳。如果您有一些与众不同的新信息,或者您确信其他答案都是错误的,则一定要添加一个新答案,但是“又一个答案”在问了很长时间后给出相同的基本信息通常是不会的。不能赚很多钱。
乔纳森·莱夫勒

1
@Jonathan Leffler您能指出我认为与Darshan答案一样简洁准确的“成熟”答案吗?
personal_cloud

1
#include "header.h"表格描述不正确,@ personal_cloud。我认为piCookieYann Droneaud的答案最为相关,因为他们确定了信息的来源。我也不认为最受好评的答案也完全令人满意。
乔纳森·莱夫勒

为什么此答案显示在顶部,而后面的两个答案却有650+票?这个答案使我感到困惑,因为它与我观察到的行为不符。这可能是因为最后一句由于未转义尖括号而被打断了。我不确定这是什么意思。
Neonit

6

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


6

“ <filename>”在标准C库位置中搜索

而“文件名”也在当前目录中搜索。

理想情况下,对于标准C库,您可以使用<...>,对于您编写并存在于当前目录中的库,可以使用“ ...”。


4
哪些新信息将此答案添加到其他答案中?
Daniel Langr

5

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

1.9 —头文件更详细地说明了预处理程序指令。如果您是新手程序员,那么该页面应该可以帮助您理解所有内容。我从这里学到了它,并且在工作中一直在关注它。


4
#include <filename>

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

#include "path-to-file/filename"

当您要使用自己的自定义头文件时,该文件位于项目文件夹或其他位置。

有关预处理器和标头的更多信息。阅读C预处理程序


3

#include <filename>

  • 预处理器以实现相关的方式进行搜索。它告诉编译器搜索保存系统头文件的目录。
  • 此方法通常用于查找标准头文件。

#include "filename"

  • 这告诉编译器在程序正在运行的位置搜索头文件。如果失败,则其行为类似于#include <filename>并在存储系统头文件的位置搜索该头文件。
  • 此方法通常用于标识用户定义的头文件(由用户创建的头文件)。如果要调用标准库,请不要使用它,因为它比花费更多的编译时间#include <filename>

2

要基于当前配置,使用gcc查看系统上的搜索顺序,可以执行以下命令。您可以在此处找到有关此命令的更多详细信息

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

Apple LLVM版本10.0.0(clang-1000.10.44.2)
目标:x86_64-apple-darwin18.0.0
线程模型:posix InstalledDir:库/开发人员/ CommandLineTools / usr / bin
“ / Library / Developer / CommandLineTools / usr / bin / clang” -cc1-三联x86_64-apple-macosx10.14.0 -Wdeprecated-objc-isa-usage -Werror = deprecated-objc-isa-usage -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 /库/开发人员/CommandLineTools/SDKs/MacOSX10.14.sdk -I / usr / local / include -fdebug-compilation-dir / Users / 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版本10.0.0(clang-1000.10.44.2)默认目标x86_64-apple-darwin18.0.0忽略不存在的目录“ /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/local/include”忽略不存在目录“ /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/Library/Frameworks”
#include“ ...”搜索从此处开始:
#include <...>搜索从此处开始:
/ usr / local / include
/库/开发人员/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(框架目录)
搜索列表的结尾。


1
#include <file> 

包含默认包含目录所在的文件。

#include "file" 

在当前文件的编译目录中包含一个文件。


-2

有两种写#include语句的方法,它们是:

#include"filename"
#include<filename>

每种形式的含义是

#include"mylib.h"

此命令将mylib.h在可能已设置的包含搜索路径中查找当前目录以及指定目录列表中的文件。

#include<mylib.h>

该命令将查找文件 mylib.h仅在指定的目录列表中。

include搜索路径只不过是要搜索要包含的文件的目录列表。不同的C编译器允许您以不同的方式设置搜索路径。


1
如果您决定回答一个已经建立并正确答案的较早的问题,那么在当天晚些时候添加一个新答案可能不会给您任何功劳。如果您有一些与众不同的新信息,或者您确信其他答案都是错误的,则一定要添加一个新答案,但是“又一个答案”在问了很长时间后给出相同的基本信息通常是不会的。不能赚很多钱。
乔纳森·莱夫勒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.