一直以来都只记得,编写C++程序可以通过以下两种方式来添加头文件:

         1.#include<iostream.h>

         2.#include<iostream>
           using namespace std;

    今天上网查了好些资料,终于对这些知识有了新的认识。本文主要是个人根据网上资料得到的知识总结,如有不对,还请勿喷。

 带.h头文件和不带.h头文件的区别

    带.h的头文件,如stdio.h、iosteam.h等,是旧的C版本头文件,定义了标准C所使用的标识符(不推荐使用)。不带.h的头文件,如iostream、string、vector等,是新版C++的标准化头文件。二者的主要区别在于:

    当包含带.h的头文件时,被引用的标识符是作为全局变量使用;
    当包含不带.h的头文件时,被引用的标识符是作为局部变量,并被封装到namespace std中。

    那么我们不禁会问,什么是namespace呢,为什么要定义namespace?

什么是namespace

    namespace根据字面理解的意思是命名空间(或者名字空间),它主要用来界定标识符的可见范围。简单来讲,随着程序复杂程度的增加,我们可能无法避免的在同一个程序中使用了相同的标识符,这就造成了“重名”。Namespace正是为了解决这一问题而提出的,通过将两个相同的标识符封装到不同的命名空间,从而使我们可以正常使用这些标识符。可以这样类比,namespace就像是文件夹,同一个文件夹里不能出现相同的文件名,但是在不同文件夹里面则可以。

    理解了为什么要定义namespace,那么接下来就得谈谈namespace的本质究竟是什么,该如何使用的问题了。

    namespace其实就像类、结构一样,是由一段代码组成的。它的定义方式如下:

          namespace X {

             //此处添加名称

             type name1;

             ……

          }

    这样我们就可以在程序中使用该命名空间了。主要可以通过两种方式来访问名称name1:

    1.使用区域限定符访问,如X::name1。
    2.使用using namespace 语句。通过声明using namespace X,就可以直接在代码中使用名称name1了。

    下面我来解释一下为什么#include<iostream>以后要用using namespace std:

    先前已经说过,标准化的C++头文件将标识符封装到namespace std。怎样理解这句话呢?

    首先,我们查看一下自己的编译环境下的INCLUDE文件夹,不难发现里面同时    包含了带.h和不带.h的头文件,而且里面包含的内容也完全不同。这两个文件里    面具体是什么我们现在不做深究,主要来看不带.h的头文件。 

    我们可以发现,几乎每个不带.h的头文件中都包含这样的结构

           _STD_BEGIN

             ……

          _STD_END

    _STD_BEGIN和_STD_END其实是宏名,具体在哪里定义我也不清楚。但是我通过查资料知道_STD_BEGIN代表字符串“namespace std {”,_STD_END代表字符串“}”。展宏以后不正是namespace的定义吗!

    所以,我们可以下结论,其实每个不带.h的头文件都将内容定义在std中。当创建一个namespace时,若该namespace已存在,则直接将内容添加到原有namespace。所以当你添加多个不带.h的头文件时,本质上是在扩展std里面包含的名称数量。

    因此,只要包含了任何一个不带.h的头文件,我们都可以通过std::XXX来访问其中的标识符,而添加using namespace std只是为了让访问更方便。

    由于能力有限,关于namespace的问题就先讨论到这里。如果有什么地方理解错了欢迎大家指出,一起学习一起进步嘛~~