【C++】命名空间 namespace 与 标准流 iostream ( 命名空间概念简介 | 命名空间定义 | 命名空间使用 | iostream 中的命名空间分析 )

文章目录

  • 一、命名空间 namespace
    • 1、命名空间基本概念
    • 2、名称概念
    • 4、C 语言的命名空间
    • 3、命名空间避免标识符冲突
  • 二、命名空间定义
    • 1、命名空间基本概念
    • 2、命名空间定义语法
    • 3、代码示例 - 命名空间定义使用
  • 三、命名空间使用
    • 1、命名空间默认访问方式
    • 2、使用命名空间
    • 3、使用默认的命名空间
    • 4、代码示例 - 使用命名空间
  • 四、标准流 iostream
    • 1、查看 iostream 头文件
    • 2、iostream 头文件源码
    • 3、yvals_core.h 头文件中 std 命名空间相关宏定义
    • 4、iostream 使用时一般导入 std 命名空间





一、命名空间 namespace




1、命名空间基本概念


命名空间 namespace 又称为 名字空间 , 名称空间 , 名域 , 作用域 , 是 C++ 语言 对 C 语言 的扩展 之一 ;

C++ 中的 命名空间 namespace 指的是 标识符 的 可见范围 , C++ 标准库中的 所有 标识符 , 都定义在 std 命名空间中 ;


2、名称概念


命名空间 英文名称是 " namespace " , name 是 名字 , 名称 的意思 , space 空间 ; 这里的 名称 name 可以是

  • 符号常量 名称
  • 变量 名称
  • 宏定义 名称
  • 函数 名称
  • 结构体 名称
  • 枚举 名称
  • 类 名称
  • 对象 名称

在命名空间中 , 可以定义上述 符号常量 , 变量 , 宏定义 , 函数 , 结构体 , 枚举 , 类 , 对象 等内容 ;

命名空间 不是专门定义 标识符名称的 , 而是可以定义 C++ 中出现的所有语法元素 ;


4、C 语言的命名空间


在 C 语言中 , 只有一个命名空间 namespace , 就是 全局作用域 ;

C 语言中 , 所有的 全局标识符 , 都共享 同一个 命名空间 namespace ( 作用域 / 名字空间 ) ;

这就使得 , 在 C 语言开发中 , 标识符 定义 经常出现冲突 , 在 C 语言 的 大规模开发中 , 不同的团队 开发者之间不好协调 ;

  • 示例 1 : 开发者 A 定义了 全局变量 name , 开发者 B 也定义了 全局变量 name , 这就导致了二者之间出现了冲突 ;
  • 示例 2 : C 语言模块 1 中定义了 全局变量 name , 在 C 语言模块 2 中定义了相同名称的全局变量 name , 如果 主程序 同时导入了这两个模块 , 就出现了冲突 ;

鉴于上述问题 , 在 C++ 中引入了新的概念 , 命名空间 namespace , 解决上述 标识符名称冲突的问题 ;


3、命名空间避免标识符冲突


C++ 被设计用于开发 大规模 的程序 , 参与开发的 开发者 或 团队 可能很多 , 每个开发者都要定义各种 变量 函数 类 对象 等 , 涉及到大量的 标识符 名称 ;

为了避免名称冲突 , 引入了 命名空间 namespace 关键字 , 每个开发者将自己写的 名称 定义到 专门的空间中 , 这个空间就是 命名空间 namespace ;


命名空间 namespace 可以避免 定义 各种 变量名称 / 函数名称 等名称时 , 出现 " 名称冲突 " 问题 ;

在 命名空间 中 , 开发者可以 将 各种 常量 / 变量 / 宏定义 / 函数 / 结构体 / 枚举 / 类 / 对象 等 内容 , 组织在一起 , 避免与 其它 命名空间 或 全局标识符 发生冲突 ;


命名空间 可以 将 整体的 全局作用于 切割成 不同的区域 , 也就是 不同的区域 使用 不同的 命名空间 ;

不同的 命名空间 中 , 可以定义 相同名称的 标识符 , 不会出现冲突 ;

C++ 中 的 默认命名空间是 全局作用域 , 访问 全局作用域 中的标识符 ,

  • 可以直接访问 ,
  • 也可以使用 ::标识符 进行访问 ;

命名空间 是 可以嵌套的 , 可以在一个命名空间中 , 定义另外一个命名空间 ;


C++ 的命名空间 可以理解为 Java 中的 包名 Package , 在不同的 Package 包 中 , 可以定义相同名称的 类 ;





二、命名空间定义




1、命名空间基本概念


C++ 命名空间类型 :

  • 嵌套命名空间 :命名空间 中可以 嵌套 定义 另一个命名空间 , 内层 被 嵌套的 命名空间 可以进一步嵌套 ; 访问 嵌套 命名空间 标识符 , 需要将 不同层次 的 命名空间都写上 ;
  • 普通命名空间 : 标识符 独立 的 使用 范围 , 在 普通命名空间 中定义的标识符 , 可以在 其它命名空间 或 默认的全局命名空间 中使用 ;

2、命名空间定义语法


命名空间定义语法 : 定义 命名空间 需要使用 namespace 关键字 , 将要定义的内容 写在 namespace 命名空间名称 后的大括号中 ;

namespace 命名空间名称 {  // 声明标识符  // 可以是 符号常量 , 变量 , 宏定义 , 函数 , 结构体 , 枚举 , 类 , 对象 等内容  
}

命名空间定义示例 :

// 自定义命名空间
namespace MyNamespace {// 声明标识符  int myVariable = 10;void myFunction() {// 函数体  cout << "MyNamespace myFunction" << endl;}
}

3、代码示例 - 命名空间定义使用


这里要特别注意 , 在下面的代码中 , 定义了 MyNamespace 命名空间 ,

但是在该 文件 中没有使用 该 命名空间 , 那么如果要访问 命名空间 中的内容 , 需要添加 MyNamespace :: 前缀 ,

访问 MyNamespace 命名空间中的 的 myVariable 变量 , 需要使用 MyNamespace::myVariable 代码访问 ;

访问 MyNamespace 命名空间中的 的 myFunction 方法 , 需要使用 MyNamespace::myFunction() 代码访问 ;


代码示例 :

// 包含 C++ 头文件
#include "iostream"// 使用 std 标准命名空间
//		该命名空间中 , 定义了很多标准定义
using namespace std;// 自定义命名空间
namespace MyNamespace {// 声明标识符  int myVariable = 10;void myFunction() {// 函数体  cout << "MyNamespace myFunction" << endl;}
}int main() 
{cout << "命名空间中的变量 : " << MyNamespace::myVariable << endl;MyNamespace::myFunction(); // 调用命名空间中的函数 // 控制台暂停 , 按任意键继续向后执行system("pause");
}

执行结果 :

命名空间中的变量 : 10
MyNamespace myFunction
Press any key to continue . . .

在这里插入图片描述

在这里插入图片描述





三、命名空间使用




1、命名空间默认访问方式


如果不导入命名空间 std , 将 using namespace std; 代码注释掉 , 此时就会报错 , cin , cout , endl 都会报 " 未定义标识符 " 错误 ;

在这里插入图片描述

如果想要在 不声明 命名空间 的情况下 , 使用 标准流 中的标识符 , 就需要使用

  • std::cout
  • std::endl
  • std::cin

否则 无法访问 这些 标识符;


代码如下 : 在下面的代码中 , 没有声明全局命名空间 std , 要使用 iostream 中的标识符 , 必须加上 std:: 前缀 ;

// 包含 C++ 头文件
#include "iostream"// 使用 std 标准命名空间
//		该命名空间中 , 定义了很多标准定义
//using namespace std;int main()
{// 定义圆半径 , 周长 , 面积 对应的变量double r = 0, p = 0, a = 0;// 提示输入圆半径std::cout << "输入圆半径 :" << std::endl;// 从命令行标准输入得到的数据 到 变量 r 指示的内存空间中std::cin >> r;std::cout << "接收到圆半径 :" << r << std::endl;// 计算圆周长p = 3.14159 * 2 * r;// 计算圆面积a = 3.14159 * r * r;// 打印计算结果std::cout << "圆周长为 :" << p << " 圆面积为 : " << a << std::endl;// 控制台暂停 , 按任意键继续向后执行system("pause");
}

执行结果 :

输入圆半径 :
10
接收到圆半径 :10
圆周长为 :62.8318 圆面积为 : 314.159
请按任意键继续. . .

在这里插入图片描述


2、使用命名空间


使用命名空间 语法 : 使用如下语法 , 可以 声明使用一个命名空间 , 可以直接访问命名空间中的元素 ;

// 使用 指定的 命名空间
using namespace 命名空间名称;

如果要使用 嵌套的命名空间 , 如 : 命名空间 A 中定义 命名空间 B , 命名空间 B 中定义了 命名空间 C , 则使用如下语法 :

// 使用 指定的 嵌套 命名空间
using namespace A::B::C;

之前的章节中 , 自定义了 命名空间 MyNamespace ,

// 自定义命名空间
namespace MyNamespace {// 声明标识符  int myVariable = 10;void myFunction() {// 函数体  cout << "MyNamespace myFunction" << endl;}
}

但是 , 使用时 , 必须通过 MyNamespace::myVariable 的形式访问 命名空间 中的变量 ;

如果想要 直接访问命名空间元素 , 可以使用上述 语法 , 导入命名空间 :

// 使用自定义的命名空间
// 注意 : 使用命名空间需要在 定义命名空间之后
using namespace MyNamespace;

注意 : 使用 命名空间 需要在 定义命名空间之后 , 否则会报错 ;


3、使用默认的命名空间


当前的 全局命名空间 就是 默认的 命名空间 , 如果你 没有在 命名空间 中定义 变量 / 类 / 函数 等元素 , 而是 直接在 C++ 代码中直接定义 , 那么这些元素 就是 定义在了 默认的 命名空间 中 ;

将变量定义在 C++ 代码中 , 就是定义了 全局空间变量 , 就是 默认命名空间 中的变量 ;

调用 默认命名空间 中的变量 , 可以使用 :: 前缀访问 ;


代码示例 :

// 包含 C++ 头文件
#include "iostream"// 将变量 定义在了 默认命名空间 : 全局命名空间
int globalVariable = 10;// 将函数 定义在了 默认命名空间 : 全局命名空间
void globalFunction() {std::cout << "globalFunction" << std::endl;
}int main() {::globalFunction();		// 调用全局函数 默认命名空间中的函数  ::globalVariable = 20;  // 修改全局变量 默认命名空间中的变量std::cout << "::globalVariable : " << ::globalVariable << std::endl;// 调用 默认命名空间 中的元素 , 不加域操作符也可以使用globalFunction();		// 调用全局函数 默认命名空间中的函数  globalVariable = 30;    // 修改全局变量 默认命名空间中的变量std::cout << "globalVariable : " << globalVariable << std::endl;// 控制台暂停 , 按任意键继续向后执行system("pause");return 0;
}

执行结果 :

globalFunction
::globalVariable : 20
globalFunction
globalVariable : 30
Press any key to continue . . .

在这里插入图片描述

在这里插入图片描述


4、代码示例 - 使用命名空间


完整代码示例 :

// 包含 C++ 头文件
#include "iostream"// 使用 std 标准命名空间
//		该命名空间中 , 定义了很多标准定义
using namespace std;// 自定义命名空间
namespace MyNamespace {// 声明标识符  int myVariable = 10;void myFunction() {// 函数体  cout << "MyNamespace myFunction" << endl;}
}// 使用自定义的命名空间
// 注意 : 使用命名空间需要在 定义命名空间之后
using namespace MyNamespace;int main() 
{cout << "命名空间中的变量 : " << myVariable << endl;myFunction(); // 调用命名空间中的函数 // 控制台暂停 , 按任意键继续向后执行system("pause");
}

执行结果 :

命名空间中的变量 : 10
MyNamespace myFunction
Press any key to continue . . .

在这里插入图片描述
在这里插入图片描述





四、标准流 iostream



标准流 iostream 的内容 , 都定义在 std 命名空间中 ;

C++ 语言为了与 C 语言 在 头文件上 进行区分

  • C++ 语言的头文件没有 .h 后缀 ;
  • C 语言的头文件有 .h 后缀 ;

1、查看 iostream 头文件


在代码中 , " Ctrl + 左键 " 点击 iostream 头文件 , 即可 跳转到该 标准流 头文件中 ;
在这里插入图片描述

在 Visual Studio 2019 中的 解决方案资源管理器 中 , 双击展开 外部依赖项 ,

在这里插入图片描述

向下翻 , 就可以找到 iostream 头文件 ,

在这里插入图片描述


2、iostream 头文件源码


iostream 头文件 , 只有 60 行代码 , 核心的内容都定义在 yvals_core.h 和 istream 头文件中 ;

在 该头文件 中 , 第 19 行使用了 _STD_BEGIN 宏定义 , 相当于定义 namespace std { 命名空间的开始 , 最后的第 53 行使用的 _STD_END 宏 相当于 命名空间的 定义结束 } ;

// iostream standard header// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception#pragma once
#ifndef _IOSTREAM_
#define _IOSTREAM_
#include <yvals_core.h>
#if _STL_COMPILER_PREPROCESSOR
#include <istream>#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new
_STD_BEGIN // 开始定义 std 命名空间
#ifdef _M_CEE_PURE
__PURE_APPDOMAIN_GLOBAL extern istream cin, *_Ptr_cin;
__PURE_APPDOMAIN_GLOBAL extern ostream cout, *_Ptr_cout;
__PURE_APPDOMAIN_GLOBAL extern ostream cerr, *_Ptr_cerr;
__PURE_APPDOMAIN_GLOBAL extern ostream clog, *_Ptr_clog;__PURE_APPDOMAIN_GLOBAL extern wistream wcin, *_Ptr_wcin;
__PURE_APPDOMAIN_GLOBAL extern wostream wcout, *_Ptr_wcout;
__PURE_APPDOMAIN_GLOBAL extern wostream wcerr, *_Ptr_wcerr;
__PURE_APPDOMAIN_GLOBAL extern wostream wclog, *_Ptr_wclog;#else // _M_CEE_PURE// OBJECTS
__PURE_APPDOMAIN_GLOBAL extern _CRTDATA2_IMPORT istream cin, *_Ptr_cin;
__PURE_APPDOMAIN_GLOBAL extern _CRTDATA2_IMPORT ostream cout, *_Ptr_cout;
__PURE_APPDOMAIN_GLOBAL extern _CRTDATA2_IMPORT ostream cerr, *_Ptr_cerr;
__PURE_APPDOMAIN_GLOBAL extern _CRTDATA2_IMPORT ostream clog, *_Ptr_clog;__PURE_APPDOMAIN_GLOBAL extern _CRTDATA2_IMPORT wistream wcin, *_Ptr_wcin;
__PURE_APPDOMAIN_GLOBAL extern _CRTDATA2_IMPORT wostream wcout, *_Ptr_wcout;
__PURE_APPDOMAIN_GLOBAL extern _CRTDATA2_IMPORT wostream wcerr, *_Ptr_wcerr;
__PURE_APPDOMAIN_GLOBAL extern _CRTDATA2_IMPORT wostream wclog, *_Ptr_wclog;// CLASS _Winit
class _CRTIMP2_PURE_IMPORT _Winit {
public:__thiscall _Winit();__thiscall ~_Winit() noexcept;private:__PURE_APPDOMAIN_GLOBAL static int _Init_cnt;
};
#endif // _M_CEE_PURE
_STD_END // 结束定义 std 命名空间
#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
#pragma warning(pop)
#pragma pack(pop)
#endif // _STL_COMPILER_PREPROCESSOR
#endif // _IOSTREAM_

3、yvals_core.h 头文件中 std 命名空间相关宏定义


在 yvals_core.h 头文件中 , 定义了 std 命名空间相关的宏定义 , 如 : _STD_BEGIN , _STD_END , _STD 等 ;

// NAMESPACE
#define _STD_BEGIN namespace std {
#define _STD_END }
#define _STD ::std::

4、iostream 使用时一般导入 std 命名空间


在 C++ 代码中 , 经常见到 下面两行代码 在一起使用 ,

使用 C++ 的 iostream 标准流时 , 需要使用 #include "iostream" 代码先导入该标准库 ;

由于 iostream 头文件中没有定义 全局命名空间 , 如果要使用 cin 或者 cout , 必须加上 std:: 前缀 , 如 : std::cinstd::cout ;

// 包含 C++ 头文件
#include "iostream"// 使用 std 标准命名空间
//		该命名空间中 , 定义了很多标准定义
using namespace std;

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

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

相关文章

实战项目ssm权限系统 3-总结篇,权限模块保护业务模块

一 工程模块介绍 1.1 工程模块关系 在业务微服务模块中引入安全认证模块&#xff0c;起到对业务模块的认证授权保护

在线设计APP ui的网站,分享这7款

在数字时代&#xff0c;用户界面&#xff08;UI&#xff09;设计变得非常重要&#xff0c;因为良好的UI设计可以改善用户体验&#xff0c;增强产品吸引力。随着科学技术的发展&#xff0c;越来越多的应用在线设计网站出现&#xff0c;为设计师和团队提供了一种新的创作方式。本…

postgresql基于postgis常用空间函数

1、ST_AsGeoJSON 图元转geojson格式 select ST_AsGeoJSON(l.geom) from g_zd l limit 10 2、 ST_Transform 坐标转换 select st_transform(l.shape, 3857) from sde_wf_cyyq l limit 10select st_astext(st_transform(l.shape, 3857)) from sde_wf_cyyq l limit 103、st_aste…

使用动态IP是否会影响网络

今天我们要谈论的话题是关于动态IP和网络的关系。也许有些小伙伴对这个概念还比较陌生&#xff0c;但别担心&#xff0c;我会简单明了的给你理清楚。让我们一起看看动态IP到底能否影响到网络。 首先&#xff0c;我们先来搞明白什么是动态IP。在互联网世界中&#xff0c;每一个连…

【NLP】1、BERT | 双向 transformer 预训练语言模型

文章目录 一、背景二、方法 论文&#xff1a;BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding 出处&#xff1a;Google 一、背景 在 BERT 之前的语言模型如 GPT 都是单向的模型&#xff0c;但 BERT 认为虽然单向&#xff08;从左到右预测…

WPF中手写地图控件(3)——动态加载地图图片

瓦片增加一个Loading动画 可以查看我的另一个博客WPF中自定义Loading图 从中心扩散 进行从里到外的扩散&#xff0c;方向是上左下右。如下图所示 于是我们可以定义一个拥有坐标X跟Y的集合&#xff0c;他允许这个集合&#xff0c;内部使用枚举器的MoveNext自动排序&#xf…

stm32之5.长按按键(使用时钟源)调整跑马灯速度

------------------------------ 源码 #include <stm32f4xx.h> #include "led.h" #include "delay.h" #include "my_str.h" #include "beep.h" #include "key.h" int main(void) { key_init(); Led_init();…

Ubuntu-Server 22.04安装详细过程-图文版

一.下载Ubuntu Server镜像&#xff0c;官方地址下载即可 https://ubuntu.com/download/server 乌班图镜像网址&#xff0c;点击下载即可 二.安装乌班图镜像&#xff0c;最好自己准备u盘在ISO软件内制作完成 1.选择 Install Ubuntu Server 2.选择安装语言为英语 3.安装程序更新选…

数据库第十五课-------------非关系型数据库----------Redis

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

港联证券|指数或进入磨底阶段 短期关注环保、煤炭等板块

磨底历来都不是一天能达到的&#xff0c;比方2018年的政策底到商场底&#xff0c;半途也阅历两个多月时间。当下政策底出现之后至今也有近一个月时间&#xff0c;并且下跌量能不断缩短&#xff0c;心情面也降至冰点&#xff0c;种种迹象阐明离真正商场底的构成已经不远了。此时…

ElasticSearch常用方法

ElasticSearch:是一个储存、检索、数据分析引擎。 在互联网项目中我们经常会按一定的条件去索引我们指定的数据&#xff0c;但是在大量的数据中我们如果直接查询数据库效率是非常低的&#xff0c;ElasticSearch就可以很好的帮我们完成检索。 es封装了api提供给我我们直接操作…

测试框架pytest教程(3)夹具-@pytest.fixture

内置fixture Fixture使用pytest.fixture装饰&#xff0c;pytest有一些内置的fixture 命令可以查看内置fixture pytest --fixtures fixture范围 在pytest中&#xff0c;夹具&#xff08;fixtures&#xff09;具有不同的作用范围&#xff08;scope&#xff09;&#xff0c;用于…

【MySQL】JSON 格式字段处理

MySQL 5.7 版本后已支持 JSON 格式&#xff0c;这虽是 MySQL 的一小步&#xff0c;但可以说是程序开发的一大步&#xff0c;再也不用将 JSON 内容塞到 VARCHAR 类型字段了&#xff0c;程序设计也会变得更加灵活。网上大多只针对JSONObject 对象类型&#xff0c;本文也将详解 JS…

RabbitMQ 消费者

RabbitMQ的消费模式分两种&#xff1a;推模式和拉模式&#xff0c;推模式采用Basic.Consume进行消费&#xff0c;拉模式则是调用Basic.Get进行消费。   消费者通过订阅队列从RabbitMQ中获取消息进行消费&#xff0c;为避免消息丢失可采用消费确认机制 消费者 拉模式拉模式的实…

企业数字化转型中,VR数字展厅能有哪些体验?

在数字化转型的浪潮下&#xff0c;企业纷纷开始注重数字展厅的开展&#xff0c;VR虚拟展厅结合VR全景技术&#xff0c;可以创造出许多有趣的玩法和体验&#xff0c;无论是虚拟参观、互动体验还是VR云会议对接&#xff0c;都为企业客户带来了全新的感知方式。 同传统展厅相比&am…

Kotlin 高阶函数详解

高阶函数 在 Kotlin 中&#xff0c;函数是一等公民&#xff0c;高阶函数是 Kotlin 的一大难点&#xff0c;如果高阶函数不懂的话&#xff0c;那么要学习 Kotlin 中的协程、阅读 Kotlin 的源码是非常难的&#xff0c;因为源码中有太多高阶函数了。 高阶函数的定义 高阶函数的…

好用的电容笔有哪些推荐?开学季便宜好用电容笔推荐

开学马上要来了&#xff0c;想必很多学生党都在为开学而做准备&#xff0c;要知道&#xff0c;原装的Apple Pencil&#xff0c;虽然功能很强&#xff0c;但是价格却很贵&#xff0c;不是一般人能够承受得起的。所以&#xff0c;是否也有类似于Apple Pencil这样的电容笔&#xf…

php开发websocket笔记(1)

1.运行server1.php文件 Windows命令行运行 php server1.php<?phperror_reporting(E_ALL); set_time_limit(0); //ob_implicit_flush(); $address 0.0.0.0;//可以监听网络上的请求 $address 127.0.0.1;//只能监听本机的请求$port 10005; //创建端口 $socket1 socket_cr…

6个比较火的AI绘画生成工具

随着人工智能技术的发展&#xff0c;市场上出现了越来越多的人工智能图像生成工具。这些人工智能图像生成工具可以自动创建惊人的图像、艺术作品和设计&#xff0c;以帮助设计师和创意人员更快地实现他们的创造性想法。在本文中&#xff0c;我们将推荐7种最近流行的人工智能图像…