16

出于这个问题的目的,我只对符合标准的 C++ 感兴趣,而不是 C 或 C++0x,也不对任何特定于实现的细节感兴趣。

#include ""关于和之间的区别的问题不时出现#include <>。该论点通常归结为两个差异:

  1. 具体实现往往会为这两种形式搜索不同的路径。这是特定于平台的,不在此问题的范围内。
  2. 该标准说#include <>是针对“标题”,而#include ""针对“源文件”。以下是相关参考:

ISO/IEC 14882:2003(E)

16.2 源文件包含[cpp.include]

1 #include 指令应标识可由实现处理的头文件或源文件。

2形式的预处理指令

# include  < h-char-sequence > new-line
在一系列实现定义的位置中搜索由 < 和 > 分隔符之间的指定序列唯一标识的标头,并用标头的全部内容替换该指令。如何指定位置或标识的标头是实现定义的。

3形式的预处理指令

# include "q-char-sequence" new-line
导致将该指令替换为由 " 分隔符之间的指定序列标识的源文件的全部内容。以实现定义的方式搜索命名的源文件。如果不支持此搜索,或者搜索失败, 该指令被重新处理,就好像它读取
# include  < h-char-sequence > new-line
具有与原始指令相同的包含序列(包括 > 字符,如果有的话)。

(上面引用的重点是我的。)这种差异的含义似乎是标准打算区分“标题”和“源文件”,但文档没有定义这些术语或它们之间的区别.

很少有其他地方甚至提到头文件或源文件。一些:

158)标题不一定是源文件,由标题名称分隔的序列也不一定是有效的源文件名(16.2)。

似乎暗示头文件可能不驻留在文件系统中,但它也没有说源文件存在。

2 词汇约定 [lex]

1程序文本保存在本国际标准中称为源文件的单元中。源文件连同通过预处理指令包含的所有头文件 (17.4.1.2) 和源文件 (16.2) #include,减去由任何条件包含 (16.1) 预处理指令跳过的任何源代码行,称为翻译单元。[注意:一个 C++ 程序不需要同时翻译。]

这是我能找到的最接近定义的,它似乎暗示标题不是“程序的文本”。但是如果你#include是一个标题,它不会成为程序文本的一部分吗?这有点误导。

那么什么是标头?什么是源文件?

4

5 回答 5

8

我的阅读是,使用尖括号包含的标准头<>文件不必是文件系统上的实际文件;例如,一个实现可以自由地启用一组“内置”操作,提供iostream当它看到时的功能#include <iostream>

另一方面,包含的“源文件”#include "xxx.h"旨在成为驻留在文件系统上的文字文件,以某种依赖于实现的方式进行搜索。

编辑:为了回答您的具体问题,我相信“标题”仅限#include于标准中指定的那些功能:iostreamvector朋友——或作为标准扩展的实现。“源文件”是程序员可以编写或使用的任何非标准工具(如.h文件等)。

于 2010-08-12T16:06:00.563 回答
4

这不是说头文件可以实现为源文件,但又可能没有?至于“什么是源文件”,考虑到“文件”的实现方式有很多种,标准不将其详细说明似乎是非常明智的。

于 2010-08-12T16:02:54.217 回答
2

正如您的报价所说:标头是<>使用"". 这些内容的确切来源以及可用的非标准标头取决于实现。如果您包含标准标题,则标准指定的所有内容都是定义的。

按照惯例,标头通常是系统范围的东西,源文件通常是项目的本地文件(对于项目的某些定义),但标准明智地不会陷入与项目组织有关的任何事情;它只是给出了与此类约定兼容的非常一般的定义,将细节留给实现和/或用户。

几乎所有标准都在预处理程序后处理程序,此时没有源文件或标题之类的东西,只有您最后引用定义的翻译单元。

于 2010-08-12T16:21:02.833 回答
2

标准标头(字符串、iostream)不一定是具有这些名称的文件,甚至根本不是文件。只要你说

#include <iostream>

一定的声明列表进入范围,标准得到满足。究竟是如何产生的,是一个实现细节。(在编写标准时,DOS 只能处理 8.3 文件名,但一些标准头文件名比那个长)

于 2010-08-12T16:07:21.787 回答
0

嗯……

我的随意理解是 <> 包含和 "" 包含之间的区别是从 c 继承的,并且(尽管标准没有定义)事实上的含义是 <> 搜索系统和编译器提供的头文件的路径,并且 "" 也搜索本地和用户指定的路径。

上面的定义似乎在某种意义上与该用法一致,但将“头”的使用限制为编译器或系统提供的东西,包括用户提供的代码,即使它们具有传统的“接口进入头”形式。

总之,非常有趣。

于 2010-08-12T16:15:58.290 回答