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

What is the relationship between iostream and namespace std?

本文关键字:关系 是什么 之间 命名空间 std iostream      更新时间:2023-10-16

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

#include <iostream>
int main ()
{
    cout << "Hello World!n";
    return 0;
}

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

错误C2065: 'cout':未声明的标识符

我开始在网上搜索,很快就在这里找到了一些解决方案。结果我得加上using namespace std;到我的代码!

然而,书中没有提到名称空间,所以我认为这本书已经过时了。(它使用#include <iostream.h>预处理器指令!)在进行了更多的Web研究之后,我发现了很多关于名称空间namespace std的信息,以及<iostream.h><iostream>的一些历史背景,所有这些新信息的流动让我感到非常困惑。(更不用说所有不必要的谷歌搜索结果关于医疗性传播疾病…)

到目前为止,我有一些问题:

  1. 如果我包括iostream库,为什么需要namespace来找到cout ?是否存在其他可能导致名称冲突的cout ?如果有人能提供一个图表,那就太好了。

作为奖励,一些历史背景:

  1. iostream.h在被改成iostream之前到底是什么?

  2. namespace在这一变化中发挥了作用吗?

所有的标准库定义都在命名空间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++头文件无扩展,以免破坏与现有代码的兼容性。

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

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

using namespace std;

c++使用名称空间来组织名称或程序实体。它声明程序将评估被称为"std"的namespace的一部分实体。iostream文件创建的每个名称都是该namespace的一部分。

1。如果我包括iostream库,为什么需要namespace来找到cout ?是否有其他可能导致名称冲突的cout ?

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

1。iostream.h在改成iostream之前到底是什么?

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

2。namespace在这一变化中发挥了作用吗?

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

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

在c++中,您可以在逻辑上将标识符分组到命名空间中。cout流在命名空间std中,你可以用三种方式使用它:

  1. using namespace std写在顶部,并使用cout
  2. using std::cout写入顶部,并使用cout
  3. 使用std::cout代替cout

感谢@bolov . .为了理解这个标准的要点,下面是声明:

#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;
}

包含新版本的c++命名空间。Iostream包含输入和输出的所有声明。命名空间std用于告知我们正在使用属于std命名空间的cout和cin。您可以在自己的名称空间中创建名为cout和cin的变量。

我也有同样的问题。我只是用门外汉的语言来教你。

想象一下,你需要一支铅笔,它放在你卧室的抽屉里。所以你需要进入你的房间去拿你的铅笔。这里房间是iostream。当你进入你的房间,你需要打开抽屉,拿铅笔。这里抽屉是命名空间,铅笔是cin/cout

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