【C++入门】你知道为什么在写C++代码之前通常要在开头写上using namespace std吗?

文章介绍了C++如何解决C语言中的命名冲突问题,通过引入命名空间来管理不同域的变量,如全局域、局部域和命名空间域。还讨论了usingnamespace的使用及其潜在危害,建议在项目开发中谨慎使用,以避免变量名冲突。此外,提到了C++的输入输出系统,如cout和cin,以及如何进行格式化输出。
摘要由CSDN通过智能技术生成

在这里插入图片描述

👦个人主页:@Weraphael
✍🏻作者简介:目前学习C++和算法
✈️专栏:C++航路
🐋 希望大家多多支持,咱一起进步!😁
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨


前言

本章是补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的。

一、C++输入和输出

既然学习一门新的语言,那就少不了输出hello world

#include<iostream>
using namespace std;
int main()
{
	cout<<"Hello world"<<endl;
	return 0;
}

在这里插入图片描述

  1. 使用cout标准输出对象和cin标准输入对象时,必须包含<iostream>头文件以及按命名空间std
  2. endl是特殊的C++符号,表示换行输出,他们都包含在包含<iostream>头文件中。<<是流插入运算符,>>是流提取运算符
  3. 使用C++输入输出更方便,不需要像printf/scanf那样,需要手动控制格式。C++的输入输出可以自动识别变量类型!但C++也可以格式化输入输出,但比较复杂,如果题目要求格式化输入输出,可以使用printfscanf,因为 C++兼容C语言

格式化输出模板

#include <iostream>
#include<iomanip>
using namespace std;

int main()
{
	double pai = 3.1415926;
	// 保留3位小数
	cout << fixed << setprecision(3) << pai << endl;
	return 0; 
}

在这里插入图片描述

二、问题引入

来看看以下简单的C语言程序:

在这里插入图片描述

首先它是能在VS上编译通过,并且在屏幕上打印了rand:666。但接下来加上头文件#include <stdlib.h>,代码是否还能正常输出呢?

在这里插入图片描述

  • rand重定义,这是为什么?

原因是:randstdlib库中的一个函数(如下图所示),在预处理阶段,#include <stdlib.h>就会被展开(相当于全局有一个rand函数),因此导致变量名和库函数相同,引发了 命名冲突问题

【总结】
C语言存在命名冲突问题:

  1. 可能与函数库中冲突。
  2. 可能与同组开发冲突。

因此,为了解决C语言命名冲突问题,C++引入了namespace这个关键字,用来定义一个命名空间域,其作用可以防止命名冲突问题。格式如下:

//name -- 名字随便取
namespace name
{
	int rand = 666;
}

三、什么是域

域分为全局域、局部域、命名空间域,当然还有类域(后面博客会详细讲解)

3.1 全局域和局部域

在这里插入图片描述

main函数外的变量称为全局域main函数内部的变量则称为局部域。而且,以上的代码是可以编译成功,因为 不同的域可以定义同名变量,但相同的域不能定义同名变量;并且 当全局域和局部域命名冲突时,优先访问局部域(局部域优先)

3.2 命名空间域

在这里插入图片描述

3.3 如何同时访问三个域的变量

如果当全局域、局部域和命名空间域发生命名冲突,正常来说局部域是直接访问,并且如果全局域出现同名遍历,我还想访问全局域;以及如何访问命名空间域的变量?

在这里插入图片描述

  • 局部域没什么好说的,直接访问
  • 当局部域和全局域同名时,并且还想访问全局变量,那就使用 :: —> 域作用限定符。表示变量a去域作用限定符左边空白搜索,而这个空白代表的是全局域。
  • . 同理地,若想访问命名空间域的变量,在域作用限定符前加上命名空间域的名字即可,表示的是变量awj这个域搜索变量

3.4 三种域访问的优先问题

当全局域、命名空间域和局部域同时存在,根据变量搜索原则,优先访问的是局部域

在这里插入图片描述

如果没有同名的局部变量,那么毫无疑问优先访问全局域

在这里插入图片描述

但是,它不会直接去命名空间搜索。那么怎样才能访问命名空间域里的变量呢?请继续往下看

在这里插入图片描述

3.5 访问命名空间域的方法

  • 指定访问(域作用限定符)

在这里插入图片描述

  • 展开命名空间域

展开的本意就是暴露到全局

在这里插入图片描述

3.6 解答标题的问题

因此,using namespace std的意思就是展开标准库std的命名空间,而标准库std提供了大量常用功能的库,包括输入输出 <iostream> 、字符串<string>、容器<vector>等等

在这里插入图片描述

四、使用using namespace的危害

注意:如果使用using namespace直接展开命名空间域,在编译阶段就会去命名空间域搜索,就相当于暴露在全局环境下了(相当于全局变量)。因此,如果全局域也有一个命名相同的变量,就会产生命名冲突,也就报错了

在这里插入图片描述

【总结】
从此可以看出,其实使用using namespace的效果也是不佳的,因为它把命名空间展开后,域中的变量就相当于全局变量,而命名空间域的意义就是为了防止命名冲突的。因此不能轻易展开命名空间。(注意:这里的展开是代码编译阶段是否去命名空间搜索,而#include是在预处理阶段就会被替换。)
【建议】

  1. 建议在写项目不要使用using namespaceusing namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模大,就很容易出现错误。
    所以建议在项目开发过程中使用指定访问
    在这里插入图片描述
    或者可以部分展开
    在这里插入图片描述
  2. 在日常练习中,建议直接using namespace std即可,这样就很方便

五、命名空间的嵌套

命名空间是允许嵌套的。

在这里插入图片描述

【输出结果】

在这里插入图片描述

ps:嵌套可以存在有同名变量(因为是不同的作用域),例子如下:

在这里插入图片描述

【输出结果】

在这里插入图片描述

需要注意的是:同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。因此,名称相同的命名空间是不允许定义同名变量的

在这里插入图片描述

  • 23
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值