2010-03-28 31 views
3

这工作:何时.h不需要包含头文件?

#include <iostream> 
using namespace std; 

但这种失败:当不需要

#include <stdio> 

.h

关于命名空间的问题,我没有找到cstdio这样的逻辑:

#pragma once 
#ifndef _CSTDIO_ 
#define _CSTDIO_ 
#include <yvals.h> 

#ifdef _STD_USING 
#undef _STD_USING 
    #include <stdio.h> 
#define _STD_USING 

#else /* _STD_USING */ 
#include <stdio.h> 
#endif /* _STD_USING */ 

// undef common macro overrides 
#undef clearerr 
#undef feof 
#undef ferror 
#undef getc 
#undef getchar 
#undef putc 
#undef putchar 

#define _HAS_CONVENTIONAL_CLIB 1 
#define _IOBASE _base 
#define _IOPTR _ptr 
#define _IOCNT _cnt 

#ifndef _FPOSOFF 
    #define _FPOSOFF(fp) ((long)(fp)) 
#endif /* _FPOSOFF */ 

typedef FILE _Filet; 

#ifndef RC_INVOKED 
#if _GLOBAL_USING 
_STD_BEGIN 
using ::_Filet; 

using ::size_t; using ::fpos_t; using ::FILE; 
using ::clearerr; using ::fclose; using ::feof; 
using ::ferror; using ::fflush; using ::fgetc; 
using ::fgetpos; using ::fgets; using ::fopen; 
using ::fprintf; using ::fputc; using ::fputs; 
using ::fread; using ::freopen; using ::fscanf; 
using ::fseek; using ::fsetpos; using ::ftell; 
using ::fwrite; using ::getc; using ::getchar; 
using ::gets; using ::perror; 
using ::putc; using ::putchar; 
using ::printf; using ::puts; using ::remove; 
using ::rename; using ::rewind; using ::scanf; 
using ::setbuf; using ::setvbuf; using ::sprintf; 
using ::sscanf; using ::tmpfile; using ::tmpnam; 
using ::ungetc; using ::vfprintf; using ::vprintf; 
using ::vsprintf; 


_STD_END 
#endif /* _GLOBAL_USING */ 
#endif /* RC_INVOKED */ 

#endif /* _CSTDIO_ */ 
+1

也许看看命名空间声明的宏_STD_BEGIN和_STD_END。 – 2010-03-28 09:47:39

+0

我不知道这个宏如何正确工作,但似乎它不包裹'stdio.h'? – user198729 2010-03-28 09:50:55

+0

'_STD_BEGIN'和'_STD_END'之间的'using'语句将这些名称导入std名称空间。他们现在可以作为'size_t'和'std :: size_t'(不要问我为什么应该保持全局​​可见)。 - C++版本有其他区别。例如,看起来有些东西是C库中的宏,C++将其重新定义为普通函数。另外''各种增加对重载函数(C中没有超载)等 – UncleBens 2010-03-28 10:22:43

回答

5

C++标准定义的头文件不需要它,它们都没有.h扩展名。的stdio.h C++版本是:

#include <cstdio> 

它包装stdio.h,将名称中它在C++ std命名空间, 但你仍然可以使用所有的C标准头文件在C++代码,如果你想。

编辑:是地名在cstdio的GCC版本std命名空间的宏:

_GLIBCXX_BEGIN_NAMESPACE(std) 

您可以检查自己的头做它应该做的,试图使用的东西如:

std::printf("hello"); 

在您的代码中。

+0

我看了看'cstdio',但没有找到把名字放在'std'命名空间中的逻辑 – user198729 2010-03-28 09:39:02

+1

@ user198729我不知道你使用的是哪个编译器,但这就是cstdio必须做的标准。 – 2010-03-28 09:43:06

+0

编译器应该没关系,它是头文件本身,没有提及任何关于'std'的地方。你可以看看它,也可以将它粘贴到我的帖子上面:) – user198729 2010-03-28 09:45:36

6

标准C++头不使用.H。所有其他事情(或者更准确地说,其他所有事情都使用它想要的任何扩展名,.h,.hxx,.hpp,.hh和更多)。

标准C头可以被包括在以下两种方式之一:

#include <stdio.h> 
#include <cstdio> 

第二种形式包装其符号在std命名空间。

最初的意图是,原则上,标题可以存储在数据库中的某种高度优化的预编译状态,在这种情况下,文件扩展的想法是没有意义的。我不知道这在实践中发生过。

+0

如果标准输入输出,如果它不是标准C++头? – user198729 2010-03-28 09:23:13

+2

@user:'stdio'是标准的C头文件。这些标题包含为'#include '。 – kennytm 2010-03-28 09:23:58

+1

不,C的'stdio.h'封装在C++的'cstdio'中。对于其他C头文件也是如此。 – 2010-03-28 09:26:44

1

不需要.h,只需在文件系统中的文件名中省略.h即可。