【C++的奇迹之旅(二)】C++关键字命名空间使用的三种方式C++输入输出命名空间std的使用惯例

请添加图片描述

文章目录

  • 📝前言
  • 🌠 C++关键字(C++98)
  • 🌉 命名空间
    • 🌠命名空间定义
    • 🌉命名空间使用
  • 🌠命名空间的使用有三种方式:
    • 🌉加命名空间名称及作用域限定符
    • 🌠使用using将命名空间中某个成员引入
    • 🌉 使用using namespace 命名空间名称 引入
  • 🌠命名空间的查找先后顺序
  • 🌉 C++输入&输出
  • 🌠`std`命名空间的使用惯例
  • 🚩总结


📝前言

C++是在C的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式
等。熟悉C语言之后,对C++学习有一定的帮助,本章节主要目标:

  1. 补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的,比如:作用
    域方面、IO方面、函数方面、指针方面、宏方面等。
  2. 为后续类和对象学习打基础。

🌠 C++关键字(C++98)

C++总计63个关键字,C语言32个关键字
ps:下面我们只是看一下C++有多少关键字,不对关键字进行具体的讲解。后面我们学到以后再
细讲。
语言的发展就像是练功打怪升级一样,也是逐步递进,由浅入深的过程。我们先来看下C++的历史版本。

asmdoifreturntrycontinue
autodoubleinlineshorttypedeffor
booldynamic_castintsignedtypeidpublic
breakelselongsizeoftypenamethrow
caseenummutablestaticunionwchar_t
catchexplicitnamespacestatic_castunsigneddefault
charexportnewstructusingfriend
classexternoperatorswitchvirtualregister
constfalseprivatetemplatevoidtrue
const_castfloatprotectedthisvolatilewhile
deletegotoreinterpret_cast

🌉 命名空间

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

🌠命名空间定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}
中即为命名空间的成员。

 1. 正确的命名空间定义
//正确的命名空间定义
namespace Asen
{
	//命名空空间中可以定义变量/函数/类型
	int rand = 10;
	
	int Add(int begin, int end)
	{
		return begin + end;
	}

	struct Node
	{
		struct Node* next;
		int data;
	};
}
  1. 命名空间可以嵌套
namespace Asen
{
	int a;
	int b;
	
	int Add(int left, int right)
	{
		return left + right;
	}

	namespace needs_confidence
	{
		int Sub(int begin, int end)
		{
			return begin - end;
		}
	}
}
  1. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
    如:一个工程中的test.h和上面test.cpp中两个asen会被合并成一个
    在这里插入图片描述

注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中

🌉命名空间使用

命名空间中成员该如何使用呢?比如以下代码运行:

namespace Asen
{
	int a = 0;
	int b = 1;
	
	int Add(int left, int right)
	{
		return left + right;
	}

	namespace needs_confidence
	{
		int Sub(int begin, int end)
		{
			return begin - end;
		}
	}
}


int main()
{
	printf("%d\n", a);
	return 0;
}

运行截图:
在这里插入图片描述

🌠命名空间的使用有三种方式:

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

int main()
{
	printf("%d\n", Asen::a);
	return 0;
}

在这里插入图片描述

🌠使用using将命名空间中某个成员引入

using Asen::b;
int main()
{
	printf("%d\n", Asen::a);
	printf("%d\n", b);
	return 0;
}

在这里插入图片描述

🌉 使用using namespace 命名空间名称 引入

using namespace Asen;
int main()
{
	printf("%d\n", Asen::a);
	printf("%d\n", b);
	Add(66, 88);
	return 0;
}

在这里插入图片描述

🌠命名空间的查找先后顺序

一. 命名空间的查找顺序是:

当前命名空间 > 父命名空间 > 全局命名空间 > 模块命名空间 > 内置模块命名空间

从最具体的当前命名空间开始向上级别进行查找,一直到全局和内置模块命名空间,以此来解决可能出现的同名变量和函数的命名冲突问题。

具体规则如下:

  1. 当前命名空间
    首先在当前命名空间中查找。
  2. 父命名空间
    如果当前命名空间没有找到,则查找其直接父命名空间。
  3. 嵌套的父命名空间
    如果直接父命名空间也没有找到,则继续向上查找更高层次的父命名空间。
  4. 全局命名空间
    如果所有父命名空间都没有找到,则最后在全局命名空间中查找。
  5. 导入的命名空间
    如果使用了using指令导入其他命名空间,也会在导入的命名空间中查找。

举个例子:

namespace A 
{
  void func() 
  {
    // do something 
  }
}

namespace B 
{
	  namespace C 
 	 {
  	 	 void func() 
  	 	 {
    	 	 // do something
   		 } 
 	 }

 	 using namespace A;

	  void test() 
 	 {
   		 func(); // 会调用B::C::func()
  	 }
}

这里B命名空间中的test函数,首先在B命名空间中查找func,没有找到,然后去B的子命名空间C中查找,找到就调用C中的func

简单总结
编译默认查找
a、当前局部域 : 自留地
b、全局域找 : 村子野地
c、到展开的命名空间中查找 : 相当于张大爷在自己的自留地加了声明,谁需要就来摘

二. 以下是有关命名空间的查找使用实例:

namespace Asen
{
	namespace needs_confi
	{
		int rand = 0;
		 
		int Add(int left, int right)
		{
			return left + right;
		}

		struct Node
		{
			struct Node* next;
			int data;
		};
	}
}

namespace needs_confi
{
	int rand = 0;

	int Add(int left, int right)
	{
		return (left + right) * 10;
	}
}

int main()
{
	printf("%p\n", rand);
	printf("%d\n", Asen::needs_confi::rand);

	printf("hello world\n");

	printf("%d\n", Asen::needs_confi::Add(2, 3));
	printf("%d\n", needs_confi::Add(2, 3));

	struct Asen::needs_confi::Node pnode;
}

在这里插入图片描述

三· 展开命名空间暴露问题:
展开命名空间可能会导致的主要问题如下:

  1. 名称冲突
    当使用using namespace将一个命名空间中的所有名称导入到当前作用域时,如果导入的命名空间和当前命名空间存在同名的变量/函数等,就会产生名称冲突,编译或运行时可能会出现错误。
  2. 污染全局作用域
    使用using namespace后,导入的所有名称都会暴露到全局作用域,可能会与其他代码产生冲突,也更难追踪是哪个命名空间中的名称。
  3. 难以区分来源
    如果直接使用using namespace,在代码中看到一个名称就不知道它来自哪个具体的命名空间。这给代码维护和调试带来困难。
  4. 性能影响
    使用using namespace后,编译器需要在更广泛的作用域中查找名称,这可能会影响编译效率和程序性能。
  5. 依赖隐藏
    使用using namespace可能会隐藏某些依赖关系,例如标准库名称可能会屏蔽用户自定义的同名名称。
  6. 难以控制
    直接使用using namespace没有办法精细控制导入的范围,无法选择性导入某些名称。

因此一般来说,不推荐在头文件中使用using namespace,在源文件中使用也应谨慎。建议直接使用具体的命名空间限定名称。

如:这里我包含了两个头文件,其中这个#include"Stack.h"的内容如下,这里主要是用namespace 空间定义,然后展开namespace ,目的是为了看两个命名空间都有相同的内容,在查找时看看会先用哪个?还是会编译报错:
在这里插入图片描述

#include"Queue.h"
#include"Stack.h"

namespace xjh
{
	typedef struct Stack
	{
	}ST;

	void STInit(ST* ps)
	{}


	struct Queue
	{
		//...
	};
}

// 展开命名空间 
using namespace ahui;
using namespace xjh;

// 编译默认查找
// a、当前局部域				: 自留地
// b、全局域找				: 村子野地
// c、到展开的命名空间中查找  : 相当于张大爷在自己的自留地加了声明,谁需要就来摘

int main()
{
	struct Stack st1;
	STInit(&st1);
	printf("%d\n", sizeof(st1));

	ahui::ST st;
	printf("%d\n", sizeof(st));

	STInit(&st);
	STPush(&st, 1);
	STPush(&st, 2);
	STPush(&st, 3);
	STPush(&st, 4);

	return 0;
}

代码运行:

在这里插入图片描述

🌉 C++输入&输出

和我们刚学C语言时,学习了printf和scanf来进行输出和输入,C++同样也有输入和输出,我们来看下C++是如何来实现问候的。

#include<iostream>
// std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中
using namespace std;
int main()
{
	cout<<"Hello world!!!"<<endl;
	return 0;
}

运行图:
在这里插入图片描述
说明:

  1. 使用cout标准输出对象(控制台)cin标准输入对象(键盘)时,必须包含< iostream >头文件
    以及按命名空间使用方法使用std
  2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含<
    iostream >头文件中。
  3. <<是流插入运算符,>>是流提取运算符
  4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。
    C++的输入输出可以自动识别变量类型。
  5. 实际上coutcin分别是ostreamistream类型的对象,>><<也涉及运算符重载等知识,
    这些知识我们我们后续才会学习,所以我们这里只是简单学习他们的使用。后面我们还有有
    一个章节更深入的学习IO流用法及原理。
    注意:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应
    头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,
    规定C++头文件不带.h;旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因
    此**推荐使用<iostream>+std**的方式。

注意:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应
头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,
规定C++头文件不带.h;旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因
此推荐使用+std的方式。

#include <iostream>
using namespace std;
int main()
{
   int a;
   double b;
   char c;
     
   // 可以自动识别变量的类型
   cin>>a;
   cin>>b>>c;
     
   cout<<a<<endl;
   cout<<b<<" "<<c<<endl;
   return 0;
}

在这里插入图片描述>注意:关于coutcin还有很多更复杂的用法,比如控制浮点数输出精度,控制整形输出进制格式等
等。因为C++兼容C语言的用法,这些又用得不是很多,我们这里就不展开学习了。后续如果有需要,我
们再学习。

🌠std命名空间的使用惯例

stdC++标准库的命名空间,如何展开std使用更合理呢?

  1. 在日常练习中,建议直接using namespace std即可,这样就很方便。
  2. using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对
    象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模
    大,就很容易出现。所以建议在项目开发中使用,像std::cout这样使用时指定命名空间 +
    using std::cout展开常用的库对象/类型等方式

    在这里插入图片描述

🚩总结

感谢你的收看,如果文章有错误,可以指出,我不胜感激,让我们一起学习交流,如果文章可以给你一个小小帮助,感谢💓 💗 💕 💞,喜欢的话可以点个关注,也可以给博主点一个小小的赞😘呀
请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/507746.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB绘制堆叠填充图--巧用句柄

MATLAB绘制堆叠填充图–巧用句柄 目录 MATLAB绘制堆叠填充图--巧用句柄1. 主要原理讲解1.1 主要函数1.2 句柄原理 2. 绘图示例2.1 准备数据2.2 绘制堆叠填充图-使用句柄控制图形属性2.3 设置填充颜色和样式2.4 添加标题和标签2.5 绘图效果 3. 结语 堆叠填充图是一种常见的数据可…

StringBuffer与StringBuilder

1.区别 (1). String : 不可变字符序列. (2). StringBuffer : 可变字符序列.线程安全&#xff0c;但效率低. (3). StringBuilder : 可变字符序列.线程不安全&#xff0c;但效率高. 既然StringBuffer与StringBuilder都是可变字符序列&#xff0c;但二者咋区分开呢&#xff1f…

Dimitra:基于区块链、AI 等前沿技术重塑传统农业

根据 2023 年联合国粮食及农业组织&#xff08;FAO&#xff09;、国际农业发展基金&#xff08;IFAD&#xff09;等组织联合发布的《世界粮食安全和营养状况》报告显示&#xff0c;目前全球约有 7.35 亿饥饿人口&#xff0c;远高于 2019 年的 6.13 亿&#xff0c;这意味着农业仍…

碳素光线疗法与宠物健康

碳素光线与宠物健康 生息在地球上的所有动物、在自然太阳光奇妙的作用下、生长发育。太阳光的能量使它们不断进化、繁衍种族。现在、生物能够生存、全仰仗于太阳的光线。太阳光线中、包含有动物健康所需要的极为重要的波长。因此、和户外饲养的动物相比、在室内喂养的观赏动物、…

【机器学习300问】59、计算图是如何帮助人们理解反向传播的?

在学习神经网络的时候&#xff0c;势必会学到误差反向传播&#xff0c;它对于神经网络的意义极其重大&#xff0c;它是训练多层前馈神经网络的核心算法&#xff0c;也是机器学习和深度学习领域中最为重要的算法之一。要正确理解误差反向传播&#xff0c;不妨借助一个工具——计…

初始C语言最后一章《编译、链接与预处理详解》

前言 感谢老铁们的陪伴和支持&#xff0c;初始C语言专栏在本章内容也是要结束了&#xff0c;这创作一路下来也是很不容易&#xff0c;如果大家对 Java 后端开发感兴趣&#xff0c;欢迎各位老铁来我的Java专栏&#xff01;当然了&#xff0c;我也会更新几章C语言实现简单的数据结…

从C到C++:深入理解基础语法差别

C基础语法讲解 前言1.输入输出2.命名空间2.1命名空间的理解&#xff1a;2.2命名空间的使用方式 3.缺省参数3.1概念&#xff1a;3.2分类&#xff1a;半缺省函数注意事项&#xff1a; 3.3使用案例&#xff1a;顺序表的初始化 4.函数重载4.1参数重载类型类型&#xff1a; 5.引用5.…

C++刷题篇——05静态扫描

一、题目 二、解题思路 注意&#xff1a;注意理解题目&#xff0c;缓存的前提是先扫描一次 1、使用两个map&#xff0c;两个map的key相同&#xff0c;map1&#xff1a;key为文件标识&#xff0c;value为文件出现的次数&#xff1b;map2&#xff1a;key为文件标识&#xff0c;va…

性能测试必备docker环境准备

在当今快速发展的软件开发领域&#xff0c;docker作为一种开源的容器化技术&#xff0c;已经成为提高应用部署效率、实现快速、一致的环境配置的重要工具。而性能测试&#xff0c;则是确保软件应用在各种负载和压力条件下表现良好的关键步骤。二者的结合&#xff0c;为软件开发…

基于springboot酒店管理平台

摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于酒店管理平台系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了酒店管理平台系统&#xff0c;它彻底改变了过…

手写Spring框架(上)浅出

手写Spring框架 准备工作Spring启动和扫描逻辑实现依赖注入的实现Aware回调模拟实现和初始化机制模拟实现BeanPostProcessor (Bean的后置处理器) 模拟实现Spring AOP 模拟实现 准备工作 准备一个空的工程创建spring的容器类&#xff0c;它是Spring IOC理念的实现&#xff0c;负…

目标检测:数据集划分 XML数据集转YOLO标签

文章目录 1、前言&#xff1a;2、生成对应的类名3、xml转为yolo的label形式4、优化代码5、划分数据集6、画目录树7、目标检测系列文章 1、前言&#xff1a; 本文演示如何划分数据集&#xff0c;以及将VOC标注的xml数据转为YOLO标注的txt格式&#xff0c;且生成classes的txt文件…

web学习笔记(五十一)

目录 1. post请求和get请求的区别 2. CORS 跨域资源共享 2.1 什么是同源 2.2 什么是同源策略 2.3 如何实现跨域资源共享 2.4 使用 cors 中间件解决跨域问题 2.5 JSONP 接口 2.6 实现 JSONP 接口的步骤 1. post请求和get请求的区别 传参方式不同&#xff1a;get请求参数…

NOSQL - Redis的简介、安装、配置和简单操作

目录 一. 知识了解 1. 关系型数据库与非关系型数据库 1.1 关系型数据库 1.2 非关系型数据库 1.3 区别 1.4 非关系型数据库产生背景 1.5 NOSQL 与 SQL的数据记录对比 2. 缓存相关知识 2.1 缓存概念 2.2 系统缓存 2.3 缓存保存位置及分层结构 二 . redis 相关知识 1.…

虚拟机下的Ubuntu系统,NAT网卡连接不上网络的问题

文章目录 解决办法1解决办法2解决办法3Ubuntu20.04桥接网卡和NAT网卡不能同时使用问题解决 本博主花了许久时间解决这个NAT网卡上网问题&#xff0c;如果你试过网上所有教程&#xff0c;检测了Windows环境和Ubuntu环境没问题&#xff0c;无法启动系统服务、ping网络失败、重置虚…

为什么感觉张宇 25 版没 24版讲得好?

很多同学反映&#xff1a;25版&#xff0c;讲得太散了, 知识点太多&#xff0c;脱离了基础班。 三个原因&#xff1a; 1. 25版改动很大&#xff0c;课程没有经过打磨&#xff1b; 2. 因为24考试难度增加&#xff0c;所以改动的总体思路是“拓宽基础”&#xff1a;即把部分强…

这些生活中常用的东西到底要怎么寄?

寄生活中这些常见的“大家伙”&#xff0c;不用发愁啦&#xff01; 看看德邦快递专业包装&#xff0c;如何保驾护航。 01、行李怎么寄&#xff1f; 如果是装有物品的行李箱&#xff1a;1.使用气泡膜包裹物品&#xff0c;轮子部位加强缓冲物防护&#xff1b; 2.放入适配纸箱&am…

Coursera自然语言处理专项课程04:Natural Language Processing with Attention Models笔记 Week01

Natural Language Processing with Attention Models Course Certificate 本文是学习这门课 Natural Language Processing with Attention Models的学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。 文章目录 Natural Language Processing with Attention ModelsWeek 01…

代码随想录算法训练营第41天 | 343:整数拆分, 96:不同的二叉搜索树

Leetcode - 343&#xff1a;整数拆分 题目&#xff1a; 给定一个正整数 n &#xff0c;将其拆分为 k 个 正整数 的和&#xff08; k > 2 &#xff09;&#xff0c;并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 示例 1: 输入: n 2 输出: 1 解释: 2 1 1, …

WinForm_初识_事件_消息提示

文章目录 WinForm开发环境的使用软件部署的架构B/S 架构应用程序C/S 架构应用程序 创建 Windows 应用程序窗口介绍查看设计窗体 Form1.cs 后台代码窗体 Form1.cs窗体的常用属性 事件驱动机制事件的应用事件的测试测试事件的级联响应常用控件的事件事件响应的公共方法 消息提示的…