2013-02-10 76 views
1

我在理解C++中的预处理器和命名空间时遇到了一些麻烦。例如,考虑下面的程序:命名空间和预处理器

#include <iostream> 

int main() 
{ 
    using namespace std; 

    cout << "Hello World!" << endl; 

    return 0; 
} 

因此,当该程序正在准备进行编译,预处理器将识别#include指令和iostream的文件添加到程序,使程序将I/O能力(即“cout”和“endl”)。现在根据我的教科书,作为C++编译器标准组件的类,函数和变量放置在命名空间std中。

这是令人困惑的,因为如果标准函数(“cout”和“endl”)放在这个命名空间中,iostream的目的是什么?我基本上试图理解为什么我们需要iostream和一些关于正在使用的命名空间的信息。

回答

2

严格地说,你不需要using namespace std;它所做的就是让你写

cout << "Hello World!" << endl; 

,而不是

std::cout << "Hello World!" << std::endl; 

命名空间“含有” iostream的定义(按标准提供的其他定义中C++库),只是在std::隐含地“前缀”到所有名称的意义上。 “包含”与“iostream文件包含输入/输出函数的定义”中的“包含”不同:文件实际上包含定义;命名空间名称只是一个前缀,可以避免名称冲突。

+0

因此,如果我正确理解你,iostream文件包含“cout”和“endl”的实际定义,而命名空间包含iostream定义以及其他定义。是否仅仅包含关于名称空间的信息(例如,用std ::加前缀或者用“namespace std;”来表示)来避免名称冲突?你需要的所有定义似乎有点奇怪(通过预处理器步骤),你仍然需要提供更多关于命名空间的信息 – Ockham 2013-02-10 00:27:10

+1

@Ockham我不会使用“contains”这个词来避免命名空间混乱。这里唯一真正的遏制是“iostream包含'cout'和'endl'的定义。”在iostream内部,这些定义被封装在'std'命名空间中。 'cout'的“真名”(也称为“完全限定名称”)是'std :: cout'。当你使用'using'指令时,编译器会隐式地将'std ::'前缀到*非限定*名称(即没有作用域解析运算符'::的名称)来解析它们的定义。虽然'使用'是完全可选的。 – dasblinkenlight 2013-02-10 00:43:37

+0

另外,'using namespace std;'是有问题的,因为它会污染名称空间,尤其是一旦包含更多的标准头文件。 (它在函数内并没有像在文件级别那样糟糕,但我仍然认为这不是个好主意,并且使用std :: cout;',使用std :: endl'更好。 – us2012 2013-02-10 00:51:26

1

头文件<iostream>包括几个有用的东西的声明,包括变量std::coutstd::endl

如果没有这些声明,当您编写cout << ...时,编译器不会知道您指的是什么。