iostream和命名空间std之间有什么关系?

时间:2014-05-11 06:28:29

标签: c++ c++11 namespaces

我目前正在使用自学C ++ 21天,第二版一书来学习C ++编码以及Microsoft Visual C ++ 2010 Express。在第1章的最后,有一个关于编写和编译以下代码的小练习:

#include <iostream>

int main ()
{
    cout << "Hello World!\n";
    return 0;
}

很简单,对吧?但令我惊讶的是,由于此错误,代码无法编译:

  

错误C2065:&#39; cout&#39; :未声明的标识符

我开始搜索网络,很快找到了一些解决方案here。事实证明我必须添加 using namespace std;我的代码!

然而书中没有提到命名空间,所以我认为这本书已经过时了。 (它使用#include <iostream.h>预处理器指令!)经过一些网络研究后,我发现了很多关于命名空间的信息,namespace std,以及<iostream.h>和{{1}的一些历史背景所有这些新信息流都让我很困惑。 (更不用说有关医疗性病的所有不必要的Google结果......)

所以这里有一些我到目前为止的问题:

  1. 如果我要加入<iostream>库,为什么需要iostream才能找到namespace?是否有其他cout某处可能导致名称冲突?如果有人可以为此提供图表,那就太棒了。
  2. 作为奖励,有一些历史背景:

    1. cout在更改为iostream.h之前究竟是什么?

    2. iostream是否参与了此更改?

7 个答案:

答案 0 :(得分:20)

所有标准库定义都在命名空间std中。也就是说它们没有在全局范围内定义,因此为了使用它们,您需要以下列方式之一来限定它们:

  • std::cout
  • using namespace std
  • using std::cout

例如,让我们来看看:

// declarations
int global_variable;

namespace n {
int variable2;
}

global_variable可以按原样访问:

int x;
x = global_variable;

但是,variable2不是全局空间的一部分,而是namespace n的一部分。

int x;
x = variable2; // error variable2 identifier not found.

所以你必须使用完全限定名称:

int x;
x = n::variable2;

作为捷径,你可以写:

using namespace n;
int x;
x = variable2; // variable2 is searched in current namespace
               // and in all namespaces brought in with using namespace
               // Found ONLY in namespace n -> OK

using n::variable2; // this makes any unqualified reference to `variable2`
                    // to be resolved to `n::variable2`
int x;
x = variable2;

对于头文件,许多编译器在有标准之前使用了iostream.h。当委员会试图标准化时,他们决定使C ++标题无扩展,以免破坏与现有代码的兼容性。

答案 1 :(得分:7)

因为这一行以#开头,所以它被称为&#34;预处理器指令&#34;。预处理器 在编译程序之前读取程序,只执行以#开头的那些行。预处理器为编译器设置源代码。

#include指令使预处理器将另一个文件的内容包含到程序中。 iostream文件包含允许C ++程序向屏幕显示输出并从键盘输入的代码。 iostream指令出现时,#include文件包含在程序中。 iostream称为头文件,显示在程序的顶部或头部。

<强> using namespace std;

C ++使用命名空间来组织名称或程序实体。它声明该计划将评估属于namespace被叫&#34; std。&#34;的实体。 iostream文件创建的每个名称都是namespace

的一部分

答案 2 :(得分:3)

  

1.如果我要加入iostream库,为什么需要namespace才能找到cout?是否有其他cout某处可能导致名称冲突?

这是必需的,因为C ++标准要求cout位于std命名空间内。 可能是一个冲突的cout,但不会出现在标准库中(例如您自己的代码或某些第三方库。)

  

1. iostream.h在更改为iostream之前究竟是什么?

它可以是任何东西,因为它不是标准的一部分,但它是预标准化标题的名称,它构成了iostream的基础。通常,它在全局命名空间中声明了所有名称,因此您正在查看的示例很可能是在标准化之前编写的。

2.Did namespace参与此更改?

这个问题尚不清楚。关键字namespace可以在实现中使用,它用于在命名空间内声明和定义数据,函数,类型等。所以它在这次变革中确实有一些部分。

namespace foo
{
  void bar();  // declares foo::bar
}

答案 3 :(得分:1)

在C ++中,您可以将标识符逻辑分组到namespacescout流在命名空间std中。您可以通过3种方式使用它。

  1. using namespace std写在最顶层并像您一样使用cout
  2. using std::cout写在最顶层并像您一样使用cout
  3. 使用std::cout代替cout

答案 4 :(得分:0)

感谢@bolov ..理解指向此here的要点,这是声明:

#include <ios>
#include <streambuf>
#include <istream>
#include <ostream>

namespace std 
{
    extern istream cin;
    extern ostream cout;
    extern ostream cerr;
    extern ostream clog;

    extern wistream wcin;
    extern wostream wcout;
    extern wostream wcerr;
    extern wostream wclog;
}

答案 5 :(得分:0)

包含新版本的 c++ 命名空间。 iostream 包含输入和输出的所有声明。命名空间 std 用于告诉我们正在使用 cout 和 cin,它们是 std 命名空间的一部分。您可以在自己的命名空间中创建名为 cout 和 cin 的变量。

答案 6 :(得分:-2)

我和你有同样的问题。我只是要用门外汉的话教你。

想象一下,您需要一支铅笔,该铅笔放在卧室的抽屉里。因此,您需要进入房间才能使用铅笔。这里是 iostream 房间。进入房间后,您需要打开抽屉并拿起铅笔。这里的抽屉是命名空间,铅笔是 cin / cout

参考:-https://en.wikiversity.org/wiki/C%2B%2B/Introduction