中国哪里有树屋:C++中,头文件与命名空间的关系

来源:百度文库 编辑:高考问答 时间:2024/04/29 17:15:22
有些书说有些头文件不在std里是什么意思?std里包含些什么?为什么不用std就不能使用cout?头文件中声明的东西为什么在使用的时候需要先using namespace std;一下?
如果我不用#include<iostream>和其他头文件。只用using namespace std 的话,是不能用cout的。这说明cout是在iostream里声明的,想不通既然声明了为什么还要using namespace一下?但是不using的话vc6报错cout 没有声明。不懂。

######################################
有些书说有些头文件不在std里是什么意思?
######################################
那些书那样说会造成困惑,因为名字空间,就像函数、
结构、类等等,是用代码来表达的一种语言机制。

std(standard的缩写)是标准C++里必须存在的一个
名字空间的名字。所有实现标准C++的编译器都
必须确保这空间的存在。

名字空间声明是这样表达的:
namespace x {
// 创建新名字
}

x是该名字空间的名字。

头文件装代码,代码表达名字空间。
所以应该说“有些头文件的内容不在std里”。
具体的意思就是,在那些头文件里,
没有任何代码是在“namespace std { }”的括号里的。

######################################
std里包含些什么?
######################################
std里包含标准C++库里的所有名字(类名、
函数名、...)。

######################################
为什么不用std就不能使用cout?
######################################
不是不能使用,只是不能直接写cout,必需用空间名和
名字空间限制符作为前缀,写成std::cout。

用某个名字做名字空间声明的时候,若已有同名的
名字空间存在,就是仅仅把括号里的名字加进去,
否则先创建空间,后加入括号里的名字。

加入名字空间后的名字都是对全局空间隐藏的,
但该名字空间的名字却不隐藏(除非该空间在另一个
名字空间里)。
cout隐藏在std里,但std本身不隐藏,所以
你“#include<iostream>”了之后,不必做
使用声明便可直接用std,通过它访问cout。

若你做了使用声明,对该使用声明所处的作用域的隐藏便
被抵消(作用域的开端到声明之间的那段除外),
即不必使用空间名和名字空间限制符作为前缀。

######################################
头文件中声明的东西为什么在使用的时候需要
先using namespace std;一下?
######################################
你已经知道做使用声明是要讨个方便而不是一种必要。

我们作个总结性的复习吧。

(A)这简单的程序里只有全局和局部空间,没有其它的名字空间:

void main( ) {
std::cout << ""; // 错误:std不存在。
cout << ""; // 错误:std不存在cout就不用提了。
}

(B)这个则多了一个叫std的名字空间。std这名字也可见了:

#include<iostream>
void main( ) {
std::cout << ""; // OK:可通过std骚扰cout。
cout << ""; // 错误:cout仍然被包在std里面,不可见。
}

iostream头文件里有std的声明。在编译之前,
预处理器会用iostream里的全部内容来代替
“#include<iostream>”这个预处理器指示符。
效果是,这程序包含iostream里的所有代码。
include是包含的意思。

包含指示是在全局空间里,所以在指示之后的任何地方,
std这个名字是可见、可访问的。

(C)这个不包含声明std的代码却尝试打开std包,
落了个跟(A)一样狼狈的下场:

using namespace std;
void main( ) {
std::cout << ""; // 错误:std不存在。
cout << ""; // 错误:std不存在cout就不用提了。
}

(D)这个声明了std(曝露了std)并把std打开,
让里面的名字(cin、cout、cerr、...)跟
std一样暴露。

[相信你闭上眼都能写出这段代码了]

yangguo2005 | 五级
看这个例子:
namespace std
{
int temp;
......
}//建立一个名字空间
如果不使用using ,那么你在外面这样:
temp=9;是错误的,不过可以这样:std::temp=9;
加上using namespace std后
就可以 temp=9了。当然对于cout来说,你不加using namespace std的话,也可以这样: std::cout来应用的,你不妨试试。其实引入命名空间,就是为了扩大为变量或函数命名的范围。使所有的名字都从属于一个机构。这就相当于,每个学校里的班级的名字是一样的,但由于从属了不同的学校,所以可以区分开来。这里的namespace 便是学校的名字了。

看这个例子:
namespace std
{
int temp;
......
}//建立一个名字空间
如果不使用using ,那么你在外面这样:
temp=9;是错误的,不过可以这样:std::temp=9;
加上using namespace std后
就可以 temp=9了。当然对于cout来说,你不加using namespace std的话,也可以这样: std::cout来应用的,你不妨试试。其实引入命名空间,就是为了扩大为变量或函数命名的范围。使所有的名字都从属于一个机构。这就相当于,每个学校里的班级的名字是一样的,但由于从属了不同的学校,所以可以区分开来。这里的namespace 便是学校的名字了。

用一句话来说明,文件是把程序分块的物理方法,名字空间是把程序分块的逻缉方法.我觉得你看的书有问题,在真正的开发之中,没有人会在头文件中引用别的头文件,这是真的,因为如果出现环话会无法编译,而且我还知道你一定不知道另外的一个概念,编译单位,c++有问题最权威的答案都在<c++程序设计语言>中,你自已去看吧.

std只是一个标准命名空间,就是对一些必要的操作符做声明定义的,并不包含多少可用的东西。
“cout”就是里面定义的一个操作符,如果不用std,系统就不知道那时什么意思呢。
用“using namespace std”就是引用这个命名空间,它不是类所以不用:include<> 的形式

如果你熟悉Java的话,名字空间就是Java里的包。
也就是说,当C++进行开发时,我可以有两个函数的名字都叫A,那么我凭什么区分他们呢?我可以把他们放到两个名字空间里,这就是c++地解决之道。所以一般来说,特定的函数和类是放在特定的名字空间里的。std是标准名字空间,当然不能把所有的函数封装到这个里面,所以有些头文件里的函数群是不在这个名字空间的。如果你用了cout,编译器就必须知道他是哪个空间里的名字,进而才能推定其含义。
简单的说吧,名字空间就像一个函数,他把一些变量放在里面,变成了局部变量,当你要用这个变量的时候,就要调用这个函数。