C++编写程序一定要加using namespace std吗?命名空间你真的清楚吗?

hello,大家好啊!经过C语言和简单数据结构的学习,博主终于能开始学习C++了,激动之心溢于言表。
在这里插入图片描述
然而刚开始学习,博主就吃了一个闭门羹。为什么C++编程时几乎每次都要敲上using namespace std;这行代码?问了很多人,得到的答案都是别管为什么,加上就完事了,搞得我真的是一阵无语,带着强烈的好奇心,博主通过科技的力量终于搞懂了为什么,下面整理知识点和大家分享。
在这里插入图片描述

🍀1.命名冲突

大家请看下面这种情况:
在这里插入图片描述

为什么一旦包上stdlib.h头文件,程序就报错了呢?
熟悉C语言的同学肯定发现了,在此库中C语言有一个库函数也叫rand,这就导致了命名冲突的问题。
我们说我们定义变量不能用关键字,但是我们能不能用库里面函数的名称呢?貌似没说呀,而且我咋知道你库函数都取了哪些名字。也有这样一种情况,就是在我们与别人合作时,我们俩定义变量或函数时用了同样的名字,在我这里可能是变量,在他那就是函数名。不一定说和库里面进行冲突,项目和项目之间也会冲突。C语言没有解决这个问题,只能有一方让步,改名字。代码量小好说,代码量大了怎么办,谁都不想让步,难道剪刀石头布吗?
在这里插入图片描述

💐2.命名空间

💓2.1 命名空间定义

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称都将存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。

🍑2.1.1普通的命名空间

C语言没有很好的解决命名冲突这个问题,C++引入namespace关键字解决这个问题。
使用方法:namespace+名字(你想叫啥都可以,后面代码我用Yuucho来演示)+{}。
{}中即为命名空间的成员(变量、函数名、类型都可以哦)。
在这里插入图片描述
我们发现这里并没有打印命名空间里的rand变量值,而是把库函数rand作为一个函数指针,打印了它的地址。那如果我想访问命名空间里的rand怎么办呢?为什么这个时候就没有产生命名冲突呢?我们学习C语言时知道在同一个作用域不能定义同名的变量,现在我们暂且可以认为命名空间里的成员被隔离起来了,那我们在全局这个作用域去看就没有两个rand了。
在这里插入图片描述
这里是不是就是我们说的局部变量优先呀,说明同名变量在不同的作用域是可以存在的。那我们有没有办法可以访问到全局的a?
我们打印时加上这个::就可以了,printf("%d\n",::a);
::这个叫域作用限定符,表示a是属于左边的作用域的,空白默认是全局作用域。
在这里插入图片描述
那我们怎么访问命名空间域里面的成员呢,聪明的你想必都已经猜出来了吧,废话不多说直接上图。
在这里插入图片描述
此外,我们可以有多个命名空间域,里面定义的成员可以同名,再也不用担心命名冲突的问题啦!
在这里插入图片描述

在这里插入图片描述

🐾2.1.2同名的命名空间会被合并

就算我们用命名空间,可能还是会冲突。假设我们有多个头文件,不同头文件之间采用了同名的命名空间,编译器最后会把它们合并在同一个命名空间中。
在这里插入图片描述
可以嵌套命名空间来解决这个问题。

🍁2.1.3命名空间可以嵌套

如果你的项目工程比较大,假设是Shopee(别问为什么是Shopee,菜鸡也有梦想[狗头])内部写了一个库。不同的部门之间也可以通过嵌套命名空间的方式来定义成员名。

在这里插入图片描述
访问成员可以用Shopee::data::Node n1;这种方式一层一层去找。
严格来说定义n1,n2应该这样写:

struct Shopee::data::Node n1;
struct Shopee::cache::Node n2;

C++中struct已经升级为类了,可以不写,什么是类呢?我们后面学了再详细讲解。
注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中
注意:命名空间中a、b还是全局变量,命名空间域不影响变量的生命周期。

🍒2.2命名空间使用

💕2.2.1加命名空间名称及作用域限定符

使用命名空间的时候,我们刚刚讲的Shopee::data::Node n1;一层一层去访问,这种指定的方式是不是很麻烦啊,有没有一种办法我不写Shopee。

🐽2.2.2使用using namespace 将命名空间名称引入

我们可以使用using namespace Shopee;这条语句引入Shopee定义的成员。
在这里插入图片描述
当然我们还可以再引入一层:
在这里插入图片描述
注:引入也需要一层一层引入,顺序不能颠倒,自己想一想为什么。

这种情况也是不行的:
在这里插入图片描述
因为你直接引入了cache,却没有引入Shopee,导致编译器无法识别。

🍂2.2.3使用using将命名空间中成员引入

在这里插入图片描述

🌱3.关于using namespace std;

🍊3.1为什么要加using namespace std;

std是封C++标准库的命名空间,count、endl(下一篇博客会详细介绍)是定义在iostream头文件里的,在std这个命名空间中,如果我们不引入std,编译器是编不过的。
在这里插入图片描述
不加std也可以但麻烦一点点:
在这里插入图片描述
还是得去指定。

🍉3.2加using namespace std;的风险

using namespace std;把std全部引入,虽然方便使用了,但是存在冲突风险。
假设我想定义一个全局变量cout。
在这里插入图片描述
解决方法:

  1. 不引入std,用指定的方法。
    在这里插入图片描述
  2. 引入部分常用的。

在这里插入图片描述

🍈4.总结

C++语法细节很多,前期学习时大家一定要有耐心,不可急于求成。就像建房子,地基不稳,大风一刮或者一个小地震,楼就垮了,有什么用是吧。
如果看了本篇博客有收获,请多多点赞支持博主,你们支持才是我不断写博客的动力!

在这里插入图片描述

评论 34
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yuucho

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值