在 C++ 中包含头文件时,...之间有什么区别?
1) 在将 .h 包装在 < > 符号中时,包括 .h 还是不包括 .h?
#include <iostream> vs. #include <iostream.h>
2)将标题名称用双引号括起来还是用 < > 符号括起来?
#include <iostream.h> vs. #include "iostream.h"
提前致谢!
简而言之:
iostream.h
已弃用——它是原始的 Stroustrup 版本。iostream
是标准委员会的版本。通常,编译器将它们都指向同一事物,但一些较旧的编译器不会具有较旧的编译器。在某些奇怪的情况下,它们既存在又不同(以支持遗留代码),然后您必须具体。
""
与<>
简单地意味着在进入库之前检查头文件的本地目录(在大多数编译器中)。
这是一篇不错的链接文章。
总结一下,给出的理由:
标准委员会生成的 iostream 库版本与 CFront 实现有很大不同。{剪辑}
为了简化转换,C++ 标准委员会声明包含标准 C++ 头文件的代码将使用缺少扩展的包含指令。这允许编译器供应商提供带有 .h 扩展名的旧式 C++ 库头文件和不带 .h 扩展名的新式头文件。
不使用 .h 版本的优点:
应该使用无扩展名版本的头文件而不是 .h 形式来编写新代码有几个原因。首先是在现代编译器上编译时此类代码的不可预测性。如前所述,使用 .h 标头的结果是特定于实现的。随着时间的推移,给定编译器使用旧样式库的机会会减少。
作为标准委员会 (X3J16) 中提议取消 .h 的人,我的初衷是解决关于 .h、.H、.hpp、.hxx 或 .h++ 文件扩展名的争论;或者某些人希望标准中没有暗示这是磁盘上文件的名称,以便允许 IDE 将预编译的标头信息从内部某个地方(如资源文件)甚至是编译器。
虽然 Unix 认为文件名是单个字符串并且实际上并没有识别扩展名的概念,但 DEC 操作系统有将名称与扩展名分开的传统,如果在特定上下文中省略它,则提供“默认扩展名”。这就是我想到将它留给实现使用实现想要使用的任何扩展的想法的地方,它允许实现甚至没有这个文件在磁盘上。(当时我是委员会的 DEC 代表。)
区分标准和准标准头是一个额外的好处。
<iostream> 是标准方式(也是唯一一种保证有效的方式)。在 gcc 上,<iostream.h>(可能需要包含在 <backward/iostream.h> 中)将相关声明拉到全局命名空间(因此您不需要 std:: 命名空间前缀)。
“iostream.h”将首先从包含您的源代码的目录中尝试,因为“”用于您项目的标头。<> 应始终用于系统标头,而 "" 应始终用于您自己的标头。
通常 <> 用于系统或标准库文件,而 "" 用于项目文件。如果您的编译器在本地搜索并且找不到它,我不会感到惊讶,它默认为标准库版本。
至于.h,我认为如果你使用C实际上并不重要。在C++中,我模糊地记得有一个新版本和一个旧版本,没有h它应该是新版本,但我什至不确定旧版本是否仍然存在。
第一个答案的简单答案是 iostream.h 不存在,至少在 GCC 实现中是这样。如果您在 *nix 上,请输入
% 定位 iostream.h
/usr/include/c++/3.4.3/backward/iostream.h
和
% 定位 iostream
/usr/include/c++/3.4.3/iostream
/usr/include/c++/3.4.3/backward/iostream.h
正如 Zee 的文章所说,iostream.h 是为了向后兼容。
这确实是两个不同的问题。
具有相同名称的 .h 和无扩展名标头之间的区别是历史性的。带有 .h 扩展名的那些来自最初的 C++ 标准,它没有一些现代特性,例如命名空间和模板。新标准更简单地将相同的功能放在新的头文件中,以便能够使用这些新功能并保留旧 (.h) 文件以向后兼容遗留代码。
#include <...> 和#include "..." 格式之间的区别在于编译器查找文件的顺序。这通常取决于实现,但想法是 <> 格式首先在系统包含目录中查找,而 "" 与 #include 的源文件首先查找相同的目录。
关于标准 C++ 头文件的名称,在 X3J16 的早期(前 2 年),我们面临着关于标准 C++ 头文件的扩展名应该是什么的争论。当时被各种供应商使用(并且受到某些操作系统对文件名的限制的影响)我相信有.h、.H、.h++、.hpp、.HXX,可能还有其他。在图书馆小组会议上,我建议我们关闭扩展名,并让实现提供默认文件扩展名(如果包含行中没有),或者使用名称作为数据库中的键如果需要,预编译头文件。[虽然类 Unix 系统将文件名和“扩展名”视为单个字符串,但我在委员会中代表 DEC,许多 DEC 操作系统将扩展名存储在目录中,作为与名称分开的字段。因此,DEC 操作系统有一个强大的传统,即根据什么程序出于什么目的访问文件来应用默认扩展名。告诉汇编程序“X,Y=Z”可能会导致读取输入文件 Z.MAC(宏)并写入输出文件 X.OBJ 和 Y.LST。] 无论如何,它避免了一场长期的、没有胜利的辩论,所以小组同意它,安迪·科尼格(Andy Koenig)将小组对此(以及其他)的结论提交给接受它的整个委员会。我觉得有些有趣的是,实现忽略了他们可以应用他们选择的默认扩展名的全部要点(我认为这对编辑器和其他工具很有用)并且只是将扩展名从文件名中删除。因此,DEC 操作系统有一个强大的传统,即根据什么程序出于什么目的访问文件来应用默认扩展名。告诉汇编程序“X,Y=Z”可能会导致读取输入文件 Z.MAC(宏)并写入输出文件 X.OBJ 和 Y.LST。] 无论如何,它避免了一场长期的、没有胜利的辩论,所以小组同意它,安迪·科尼格(Andy Koenig)将小组对此(以及其他)的结论提交给接受它的整个委员会。我觉得有些有趣的是,实现忽略了他们可以应用他们选择的默认扩展名的全部要点(我认为这对编辑器和其他工具很有用)并且只是将扩展名从文件名中删除。因此,DEC 操作系统有一个强大的传统,即根据什么程序出于什么目的访问文件来应用默认扩展名。告诉汇编程序“X,Y=Z”可能会导致读取输入文件 Z.MAC(宏)并写入输出文件 X.OBJ 和 Y.LST。] 无论如何,它避免了一场长期的、没有胜利的辩论,所以小组同意它,安迪·科尼格(Andy Koenig)将小组对此(以及其他)的结论提交给接受它的整个委员会。我觉得有些有趣的是,实现忽略了他们可以应用他们选择的默认扩展名的全部要点(我认为这对编辑器和其他工具很有用)并且只是将扩展名从文件名中删除。告诉汇编程序“X,Y=Z”可能会导致读取输入文件 Z.MAC(宏)并写入输出文件 X.OBJ 和 Y.LST。] 无论如何,它避免了一场长期的、没有胜利的辩论,所以小组同意它,安迪·科尼格(Andy Koenig)将小组对此(以及其他)的结论提交给接受它的整个委员会。我觉得有些有趣的是,实现忽略了他们可以应用他们选择的默认扩展名的全部要点(我认为这对编辑器和其他工具很有用)并且只是将扩展名从文件名中删除。告诉汇编程序“X,Y=Z”可能会导致读取输入文件 Z.MAC(宏)并写入输出文件 X.OBJ 和 Y.LST。] 无论如何,它避免了一场长期的、没有胜利的辩论,所以小组同意它,安迪·科尼格(Andy Koenig)将小组对此(以及其他)的结论提交给接受它的整个委员会。我觉得有些有趣的是,实现忽略了他们可以应用他们选择的默认扩展名的全部要点(我认为这对编辑器和其他工具很有用)并且只是将扩展名从文件名中删除。s 对此(除其他外)的结论给接受它的整个委员会。我觉得有些有趣的是,实现忽略了他们可以应用他们选择的默认扩展名的全部要点(我认为这对编辑器和其他工具很有用)并且只是将扩展名从文件名中删除。s 对此(除其他外)的结论给接受它的整个委员会。我觉得有些有趣的是,实现忽略了他们可以应用他们选择的默认扩展名的全部要点(我认为这对编辑器和其他工具很有用)并且只是将扩展名从文件名中删除。