目录
<iostream>的历史
命名空间(namespace)的使用
所谓namespace,是指标识符的各种可见范围。C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。
在C++中,名称(name)可以是符号常量、变量、宏、函数、结构、枚举、类和对象等等。为了避免,在大规模程序的设计中,以及在程序员使用各种各样的C++库时,这些标识符的命名发生冲突,标准C++引入了关键字namespace(命名空间/名字空间/名称空间/名域),可以更好地控制标识符的作用域。
相较于C语言:
C中的命名空间:在C语言中只有一个全局作用域, 所有的全局标识符共享同一个作用域,这样就存在标识符之间可能发生冲突的风险(实际项目经验告诉我们,这种情况经常发生,而且,非常不好修改)。举个例子,如果在C语言下编写的函数,一旦重名,必定会造成冲突,因为其只有一个全局作用域。
为应对这种问题,C++中提出了命名空间的概念,命名空间将全局作用域分成不同的部分,不同命名空间中的标识符可以同名而不会发生冲突,命名空间可以相互嵌套,全局作用域也叫默认命名空间。
C++命名空间的定义:
namespace name { … }
/*
C++命名空间的使用:
使用整个命名空间:using namespace name;
使用命名空间中的变量:using name::variable;
使用默认命名空间中的变量:::variable
默认情况下可以直接使用默 认命名空间中的所有标识符
*/
看个例子:
namespace NameSpaceA
{
int a = 0;
}
namespace NameSpaceB
{
int a = 1;
namespace NameSpaceC
{
struct Teacher
{
char name[10];
int age;
};
}
}
如上代码,"NameSpaceA","NameSpaceB"是两个不同的命名空间,在其各自的命名空间中,都可以定义变量,而且,在这两个命名空间中定义的相同变量"a"将不会重合,因为其在不同的作用域里面;命名空间也可以进行嵌套,"NameSpaceC"中,嵌套于"NameSpaceB"中,里面定义了一个结构体。
下面来看命名空间的使用:
int main()
{
using namespace NameSpaceA;
using NameSpaceB::NameSpaceC::Teacher;
printf("a = %d\n", a);
printf("a = %d\n", NameSpaceB::a);
/*
NameSpaceB::NameSpaceC::Teacher t2 //如果不使用 "using
//NameSpaceB::NameSpaceC::Teacher;"这样的简洁调用方式就必须要用这种复杂的调用方式进行。
*/
Teacher t1 = {"aaa", 3};
printf("t1.name = %s\n", t1.name);
printf("t1.age = %d\n", t1.age);
system("pause");
return 0;
}
再举一个例子:
#include "iostream"
using namespace std;
//1文件中iostream 没有引入标准的 std ; 需要我们程序员手工的写
//2 如果不写 using namespace std; 需要显式的引入std(std::endl)
void main31()
{
cout<<"namespace test"<<endl;
/*
std::cout<<"namespace test"<<std::endl; //不写" using namespace std;"时
*/
system("pause");
}
当使用<iostream>的时候,该头文件没有定义全局命名空间,必须使用namespace std。
定义命名空间:
namespace namespaceA
{
int a = 10;
}
namespace namespaceB
{
int a = 20;
namespace namespaceC
{
struct Teacher
{
char name[32];
int age ;
};
}
}
使用命名空间:
下面中就是展示在两个命名空间下定义的相同变量a的使用方法及使用嵌套的命名空间中的结构体的使用方法。
void main()
{
using namespace namespaceA;
using namespace namespaceB;
cout<<namespaceA::a<<endl;
cout<<namespaceB::a<<endl;
//显示的, 写全
{
//namespaceB::namespaceC::Teacher t1;
//t1.age = 33;
}
//也可以不写全
using namespaceB::namespaceC::Teacher ;
Teacher t2;
t2.age = 36;
system("pause");
}
做个总结:
- 当使用<iostream>的时候,该头文件没有定义全局命名空间,必须使用namespace std;这样才能正确使用cout。若不引入using namespace std ,需要这样做。std::cout。
- c++标准为了和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。
- C++命名空间的定义: namespace name { … }
- using namespace NameSpaceA;
- namespce定义可嵌套。
<iostream>的历史
<iostream>和<iostream.h>格式不一样,前者没有后缀,实际上,在你的编译器include文件夹里面可以看到,二者是两个文件,打开文件就会发现,里面的代码是不一样的。后缀为.h的头文件c++标准已经明确提出不支持了,早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,c++标准为了和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。 因此,
1)当使用<iostream.h>时,相当于在c中调用库函数,使用的是全局命名空间,也就是早期的c++实现;
2)当使用<iostream>的时候,该头文件没有定义全局命名空间,必须使用namespace std;这样才能正确使用cout。