文章目录
前言
这一篇文章将从简单的 helloworld 代码来开启 C++ 的学习!!!
#include <iostream>
using namespace std;
int main()
{
cout << "helloworld" << endl;
return 0;
}
以上的代码 using namespace std 的作用是什么,这就是下面要讲的命名空间了!
一、什么是命名空间
1. 作用域的概念
在学习C语言的时候,我们都知道全局变量和局部变量,全局变量属于全局域,而局部变量属于局部域,即使用{}
限定的代码块;实际上,域决定了编译器如何搜索变量
编译器搜索变量的规则为所处代码块的局部优先,如果找不到变量,再去更大的局部域寻找,最后再到全局域中寻找,如下代码为例:
#include <iostream>
using namespace std;
int a = 0;
int main()
{
cout << a << endl; // 打印 0
int a = 1;
cout << a << endl; // 打印 1
{
int a = 2;
cout << a << endl; // 打印 2
}
return 0;
}
2. 命名空间的本质
命名空间也是一个域 ,在命名空间定义的变量或函数,需要加上特定的操作才能访问,代码如下:
#include <iostream>
using namespace std;
namespace Jeffrey
{
int a = 0;
};
int main()
{
cout << Jeffrey::a << endl; // 告诉编译器去命名空间域中搜索变量
}
二、为什么要有命名空间
1. C 语言的命名冲突
C++ 引入命名空间,本质上是为了解决 C 语言留下的问题–命名冲突,以下代码为例:
#include <stdio.h>
#include <stdlib.h>
int rand = 10;
int main()
{
printf("%d\n", rand);
return 0;
}
// 编译后后报错:error C2365: rand 重定义;以前的定义是函数
原因: rand 在 stdlib.h 中为函数名,在包含此头文件后,又在全局域中定义了名为 rand 的全局变量,造成了命名的冲突
2. C++ 的解决方法
上一段代码在 C++ 中就可以这样写:
#include <stdio.h>
#include <stdlib.h>
namesapce Jeffrey
{
int rand = 10;
}
int main()
{
printf("%d\n",Jeffrey::rand);
return 0;
}
因为命名空间域和全局域属于不同的作用域,故解决了 C 语言在引入头文件后定义全局变量,可能会造成全局域下命名冲突的问题
三、如何使用命名空间
因为命名空间域限定了其中变量对编译器的可见性,故要想访问命名空间中变量,需要使用如下三种方法
1. 展开命名空间
实际上,C++ 的输入输出实现在名为 std 的命名空间下,前言代码的 using namespace std 即展开命名空间 std ,后续编译器在搜索变量或函数时,会到展开的命名空间中搜索
一般不建议直接展开命名空间,因为展开多个命名空间中如果有相同的变量名,还是会造成命名冲突的问题,如下代码为例:
namespace Jeffrey1
{
int a = 3;
};
namespace Jeffrey2
{
int a = 3;
};
using namespace Jeffrey1;
using namespace Jeffrey2;
// 编译报错,a 不明确
2. 声明命名空间中的成员
对于经常要在代码中用到的,且在命名空间中的成员(可以是变量或函数),可以在全局声明
#include <iostream>
using std::cout;
using std::endl;
int main()
{
cout << "helloworld" << endl;
return 0;
}
3. 使用时指定命名空间
如果不想展开命名空间,也不想在全局声明,就需要在使用时指定命名空间;实际上,这也是最安全的使用方法
#incldue <iostream>
int main()
{
std::cout << "helloworld" << std::endl;
return 0;
}
总结
在写一些小代码时,其实很难看到命名空间的作用;但在一项大工程内,多人分工的情况下,命名空间的作用就展现出来了,因为我们很难保证每个人定义的变量名或函数名都不一样,而命名空间则很好地解决了这个问题
C++ 补充了许多 C 语言语法的不足并对 C 语言设计不合理的地方进行了优化,命名空间就是其中一个例子,它解决了 C 语言中命名冲突的问题,增加了代码的健壮性和可维护性