我应该在C ++程序中包含<xxxx.h>还是<cxxxx>?
- 我应该包含在C ++程序中,
stdio.h
或cstdio
? 为什么? - 为什么两个头文件提供相同的function?
- 标准对此有何评论?
- 我应该怎么去包括其他这样的标题,我是否应该遵循一个基本的规则?
考虑以下程序:
样品1:
#include<stdio.h> int main() { printf("Hello World"); return 0; }
样品2:
#include<cstdio> int main() { printf("Hello World"); return 0; }
两者都按预期工作。 那么哪个用法更合适? 答案是: 既不! 惊讶吗? 阅读。
C ++标准库提供了所有标准的C头文件以实现兼容性原因,而C ++作为一种语言也提供了所有的等效头文件。 作为惯例,
- 没有C ++标准库头文件(除了包括C兼容性)有任何文件扩展名和
- C标头的所有C ++等价物都以
cxxxxx
。
C ++标准在附件D(规范性)兼容性特性中提到了这一点:
§2提到了重要的区分点。 这个规则适用于上面的例子意味着:
- 包括cstdio将符号名称导入std命名空间,并可能导入Global命名空间。
- 包括stdio.h在全局命名空间和可能在std命名空间中导入符号名称。
让我们将这个规则应用于我们的示例代码,并衡量利弊:
示例1:这将全局名称空间中来自stdio.h的所有符号。 好处是你可以在没有任何限制的情况下使用这些符号,因为它们是在全局命名空间中导入的。 缺点是你最终会用许多你永远不会使用的符号名来污染全局命名空间。 这可能会导致符号名称冲突。 在C ++中,总是将全局名称空间视为雷区,尽可能避免它。
示例2:这是一个非常糟糕的做法,因为不能保证实现将符号放在全局名称空间中,标准根本不要求这样做。 我们只是依靠一个特定的编译器实现的行为。 我们不能也不应该假设所有的编译器都这么做。 所以严格来说这个程序不是标准认可的,这个用法在所有的实现中都是不可移植的。
那么正确的用法是什么?
正确的用法是使用cstdio
并完全限定符号名称,或者using
声明将其引入到范围中。 这保证了我们使用的所有符号都出现在std
名字空间中,而且我们不会污染全局名字空间。 正确使用的例子:
样品3:
#include<cstdio> using std::printf; int main() { printf(“Hello World”); return 0; }
请注意,该命令using namespace std;
特别是在头文件中,不是一个好的select ,你应该总是使用声明。
请注意,我们认为stdio.h
和cstdio
只是一个示例用例,实际上它适用于所有大多数cxxxx
和xxxx.h
头文件, 除了<math.h>
和<cmath>
。
由于这篇文章有点老,我想分享以下内容:
看代码:
Using Xh // Compatible with C language standard --------------- #include <Xh> int main() { // Invoke X's corresponding function return 0; } Using X // Not compatible with C language standard -------------- #include <X> int main() { // Invoke X's corresponding function return 0; }
他们都编译和执行好!
C ++中哪一个更好?
关于C ++ 11和C ++ 17的规范:
C.5.1 (C ++ 17文档部分)
修改标题[diff.mods.to.headers]
为了与C标准库兼容,C ++标准库提供了在D.5中枚举的C头文件,但是在C ++中不推荐使用它们。
C头文件
<stdatomic.h>
,<stdnoreturn.h>
和<threads.h>
<stdnoreturn.h>
没有C ++头文件,C头文件本身也不是C ++的一部分。C ++头文件
<ccomplex>
(D.4.1)和<ctgmath>
(D.4.4)以及相应的C头文件<complex.h>
和<tgmath.h>
不包含任何来自C标准库,而只是包含来自C ++标准库的其他头文件。
D.5 C标准库头[depr.c.headers] 1.为了与C标准库兼容,C ++标准库提供了如表141所示的C头。
C ++ 11和C ++ 17标准规范文档都声明<Xh>
的使用仍然与C标准兼容,尽pipe它们的使用被认为是不合时宜的 。
关于C ++ 20标准的build议
他们正在评论C ++ 20中使用C库头文件的“不赞成” 。 以绿色突出显示<Xh>
。 到目前为止,C ++ 11和C ++ 17的弃用被认为是“弱推荐” ,保留“ C标准库头(c.headers) ”的“调整”显示如下:
“基本的C库头文件是一个基本的兼容性function,并且不会很快到任何地方。” (来自C ++ 20评论文档 )
D.5 C标准
库头[depr.c.headers]弱推荐:除上述之外,还要从C ++标准中删除相应的C头文件,就像我们没有相应的
<stdatomic.h>
,<stdnoreturn.h>
或<threads.h>
<stdnoreturn.h>
头文件一样。 如上所述,但有以下的调整:20.5.5.2.1 C标准库头[c.headers]为了与C标准库兼容,C ++标准库提供了表141所示的C标头。表141 – C标头
<assert.h> <inttypes.h> <signal.h> <stdio.h> <wchar.h> <complex.h> <iso646.h> <stdalign.h> <stdlib.h> <wctype.h> <ctype.h> <limits.h> <stdarg.h> <string.h> <errno.h> <locale.h> <stdbool.h> <tgmath.h> <fenv.h> <math.h> <stddef.h> <time.h> <float.h> <setjmp.h> <stdint.h> <uchar.h>
头文件
<complex.h>
行为就好像它只是包含头文件一样。 头<tgmath.h>
行为就好像它只包含头<complex>
和<cmath>
。
Bjarne Stroustrupbuild议通过尽可能地 减less不兼容性来最大化 C和C ++语言之间的互操作性 。 其他人则认为,因为它使事情变得复杂。
所以,似乎<Xh>
没有去任何地方 。 最终,你可以使用两者。 就我个人而言,我会决定使用哪一个,让代码向后兼容C代码 。