【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展开常用的库对象/类型等方式

    在这里插入图片描述

🚩总结

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

跨境电商IP防关联是什么?有什么作用?

做跨境电商的朋友应该都知道IP防关联这个词,那么为何IP需要防关联呢&#xff1f;今天为大家来解答这个问题。 跨境电商IP防关联是指在跨境电商运营中&#xff0c;通过采取一系列技术手段&#xff0c;确保每个跨境电商账号使用独立的IP地址&#xff0c;以避免账号之间因为IP地址…

双出口nat配置示例

一、需求&#xff1a; 局域网内两个网段&#xff0c;vlan10 和 vlan 20&#xff0c;分别实现 vlan10 可访问专网&#xff0c;vlan20 可访问互联网&#xff0c;且两个网段彼此不互通。拓朴如下&#xff1a; 二、配置思路&#xff1a; 1、S1起 vlan10、20&#xff0c;做 acl 配置…

[深度学习]yolov8+streamlit搭建精美界面GUI网页设计源码实现三

【设计思路介绍】 为了使用YOLOv8和Streamlit搭建一个精美的界面GUI网页&#xff0c;你需要遵循几个关键步骤。以下是一个简化的流程&#xff0c;帮助你设计并实现这一目标&#xff1a; 1. 环境准备 安装YOLOv8 YOLOv8是一个先进的实时目标检测模型。你需要先下载并安装YOL…

Pandas操作MultiIndex合并行列的Excel,写入读取以及写入多余行及Index列处理,插入行,修改某个单元格的值,多字段排序

Pandas操作MultiIndex合并行列的excel&#xff0c;写入读取以及写入多余行及Index列处理&#xff0c;多字段排序尽量保持原来的顺序 1. 效果图及问题2. 源码参考 今天是谁写Pandas的 复合索引MultiIndex&#xff0c;写的糊糊涂涂&#xff0c;晕晕乎乎。 是我呀… 记录下&#…

JS中throw new Error(error) 和 throw error的用法与区别

抛出错误一般都是与try catch 同时出现的。 ① throw new Error(error)&#xff0c;这个是创建错误&#xff0c;创造一个错误类型&#xff08;错误实例对象&#xff09;抛出&#xff1b; ② throw error&#xff0c;这个是抛出错误。&#xff08;不建议的写法&#xff09; …

unity内存优化Texture2D优化

作为unity开发者&#xff0c;我们使用memory Profiler来查看内存&#xff0c;本期我们项目中Texture2D的内存占有比较高&#xff0c;为了对这块做优化我们先看下内存的占有情况。 step1 使用memory Profiler对手机应用程序截图 打开截取后的内存页面&#xff0c;选择顶部Unit…

【dll解密】Dll加壳保护方案分析修复

分析背景 NGame游戏海外版出现了破解版&#xff0c;该版本在dump出游戏的dll中不能直接通过反编译工具查看修改后的游戏代码&#xff0c;导致无法确定外挂修改的直接逻辑点。本文主要针对AssemblyCSharp.dll模版&#xff0c;分析其dll保护的方法。 分析过程 1、拿到Encrypt_As…

Spark-Scala语言实战(7)

在之前的文章中&#xff0c;我们学习了如何在IDEA中导入jars包&#xff0c;并做了一道例题&#xff0c;了解了RDD。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢…

04-JavaScript函数

函数&#xff08;重点&#xff09; 1.为什么使用函数? 用函数来解决代码重用的问题。 2.函数的意义 函数其实就是封装&#xff0c;把可以重复使用的代码放到函数中&#xff0c;如果需要多次使用同一段代码&#xff0c;就可以把封装成一个函数。这样的话&#xff0c;在你需…

Redis中处理处理没有ACK确认的Stream

系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 Stream是一个只能追加内容的数据类型。也就是说Stream这种数据类型,我们…

vue的创建、启动以及目录结构详解

vue的创建、启动以及目录结构详解目录 一. vue项目的创建 二. vue的目录结构 三. src的目录结构 四. vue项目的启动 4.1 方法1 4.2 方法2 一. vue项目的创建 创建一个工程化的Vue项目&#xff0c;执行命令&#xff1a;npm init vuelatest 注意&#xff1a;如果你在这个目…

pdf在浏览器上无法正常加载的问题

一、背景 觉得很有意思给大家分享一下。事情是这样的&#xff0c;开发给我反馈说&#xff0c;线上环境接口请求展示pdf异常&#xff0c;此时碰巧我前不久正好在ingress前加了一层nginx&#xff0c;恰逢此时内心五谷杂陈&#xff0c;思路第一时间便放在了改动项。捣鼓了好久无果…

动态链接dlopen/dlclose/..

dlopen&#xff0c;dlsym,dlclose可以在不去link shared library的前提下&#xff0c;在runtime时调用shared library里面的函数.这样可以实现shared library的覆盖或是省略编译阶段的链接检查.但dlopen/dlclose要谨慎使用,尤其是有些写的不是很好的shared library. 动态链接函…

搜索与图论——Prim算法求最小生成树

在最小生成树问题里&#xff0c;正边和负边都没问题 朴素版prim算法 时间复杂度O(n^2) 生成树&#xff1a;每一次选中的t点&#xff0c;它和集合的距离对应的那条边&#xff0c;就是生成树的一条边 算法流程和dijkstra算法非常相似 #include<iostream> #include<cs…

OKCC的API资源管理平台怎么用?

API资源管理平台&#xff0c;重点是“资源”管理平台&#xff0c;不是API接口管理平台。 天天讯通推出的API资源管理平台&#xff0c;类似昆石的VOS系统&#xff0c;区别是VOS是SIP资源管理系统&#xff0c;我们的API资源管理平台是API资源管理系统&#xff08;AXB、AX、回拨AP…

【御控物联】JavaScript JSON结构转换(7):数组To数组——键值互换属性重组

文章目录 一、JSON结构转换是什么&#xff1f;二、案例之《JSON数组 To JSON数组》三、代码实现四、在线转换工具五、技术资料 一、JSON结构转换是什么&#xff1f; JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换&#xff0c;生成新的JS…

【Spring Cache】基于注解的缓存框架 简化redis代码

文章目录 一、介绍二、常用注解三、快速入门3.1 EnableCaching3.2 CachePut3.3 Cacheable3.4 CacheEvict 一、介绍 Spring Cache 是一个框架&#xff0c;实现了基于注解的缓存功能&#xff0c;只需要简单地加一个注解&#xff0c;就能实现缓存功能。 Spring Cache 提供了一层…

带你认识线程

线程的概念 前言&#xff1a; 一个程序运行起来&#xff0c;就会对应一个进程&#xff0c;例如&#xff0c;启动一个 Java 程序&#xff0c;就会创建一个 Java 进程。进程也被称为系统分配资源的基本单位。 一个进程可以包含一个线程&#xff0c;也可以包含多个线程&#xff…

政安晨:【Keras机器学习实践要点】(九)—— 保存、序列化和导出模型

目录 介绍 如何保存和加载模型 保存一个Keras模型 装回模型 设置 保存 例子&#xff1a; 自定义对象 向 load_model() 传递自定义对象 使用自定义对象范围 模型序列化 APIs 内存模型克隆 任意对象序列化和反序列化 保存模型权重 内存中的权重传递接口 无状态层…

新能源充电桩站场视频汇聚系统建设方案及技术特点分析

随着新能源汽车的普及&#xff0c;充电桩作为新能源汽车的基础设施&#xff0c;其安全性和可靠性越来越受到人们的关注。为了更好地保障充电桩的安全运行与站场管理&#xff0c;TSINGSEE青犀&触角云推出了一套新能源汽车充电桩视频汇聚管理与视频监控方案。 方案采用高清摄…