为什么有些人需要.h而其他人不需要?

时间:2010-12-10 01:02:51

标签: c++ include

为什么地图导入为#include <map>,但导入的stdio为#include <stdio.h>

3 个答案:

答案 0 :(得分:29)

所有标准C ++标头最终都不希望.h。我在某个地方读到这个概念是他们不需要是实际的文件,即使我从未见过实现以另一种方式执行 编辑: < / strong> 实际上编译器内在函数应该考虑包含的头但不实际包含它们作为文件;请参阅 @Yttrill 的评论

对于stdio.h,在C ++应用程序中,您不应包含<stdio.h>,而应包括<cstdio>。一般情况下,您不应该包含“普通”C标头,但是他们的C ++化对应设备(最终没有.h)前面有c并且将其中定义的所有符号放在std命名空间中。因此,<math.h>变为<cmath><stdlib.h>变为<cstdlib>,依此类推。

一般情况下,你应该使用C ++版本的C头文件来避免污染全局命名空间(假设你不是那些把using namespace std;放在任何地方的人)而是为了一些C ++的好处对标准C头的改进(例如,为某些数学函数添加了重载)。

<小时/> 通常,只需在编译器查找头文件的目录中使这些文件没有扩展名即可完成整个过程的实现。例如,在我的g ++ 4.4安装中,您有:

matteo@teoubuntu:/usr/include/c++/4.4$ ls
algorithm           cstdarg              functional        sstream
array               cstdatomic           initializer_list  stack
backward            cstdbool             iomanip           stdatomic.h
bits                cstddef              ios               stdexcept
bitset              cstdint              iosfwd            streambuf
c++0x_warning.h     cstdio               iostream          string
cassert             cstdlib              istream           system_error
ccomplex            cstring              iterator          tgmath.h
cctype              ctgmath              limits            thread
cerrno              ctime                list              tr1
cfenv               cwchar               locale            tr1_impl
cfloat              cwctype              map               tuple
chrono              cxxabi-forced.h      memory            typeinfo
cinttypes           cxxabi.h             mutex             type_traits
ciso646             debug                new               unordered_map
climits             deque                numeric           unordered_set
clocale             exception            ostream           utility
cmath               exception_defines.h  parallel          valarray
complex             exception_ptr.h      queue             vector
complex.h           ext                  random            x86_64-linux-gnu
condition_variable  fenv.h               ratio
csetjmp             forward_list         regex
csignal             fstream              set

理论上的C ++化的C头 可能只是一个

namespace std
{
#include <original_C_header.h>
};

但总的来说,处理特定于实现的问题(特别是关于宏)以及添加与C ++相关的功能(参见例如<cmath>中添加的重载的前一个示例)会更复杂。

<小时/> 顺便说一句,C ++标准(§D.5)并没有说<c***>标题应该表现得好像它们在<***.h>指令中包含namespace std标题,而是相反:

  

为了与标准C库兼容,C ++标准库提供了18个C头[...]   名称格式为name.h的每个C头的行为就好像每个由相应的cname头放置在标准库命名空间中的名称也放在名称空间std的命名空间范围内,然后显式使用 - 声明(7.3.3)

请注意,此类标头被视为已弃用(§C.2.1),因此这是您不应使用它们的主要原因:

  

C.2.1对标题的修改   为了与标准C库兼容,C ++标准库提供了18个C头(D.5),   但它们的使用在C ++中已被弃用。

答案 1 :(得分:2)

它只是磁盘上实际文件的名称。标准包含目录中可能(可能)没有名为map.hstdio的文件。

C ++标准库从先前使用.h的方式转移到文件名末尾没有.h。这可能可能与使语法看起来更像模板有关:

#include<vector>

vector<int> v;

(抢先评论:是的,我知道上面需要构建std::,但这只是一个例子。)

答案 2 :(得分:2)

这正是它由C ++标准定义的方式 - 实际上,mapstdio.h甚至不必是真实文件。

作为旁注,stdio.h是最初从C标准库导入C ++的标头 - C ++版本为cstdio。实际上,这通常意味着当您包含cstdio时,您可以从stdio.h获取内容,但它位于名称空间标准中。

只是为了澄清:你在C ++中包含的stdio.h是最初是C头的C ++版本。但C ++编写包含的方式是cstdio