C++学习第二课:命名空间域namespace

C++学习

C++学习第一课:C++学习须知
C++学习第二课:命名空间域



前言

本篇文章为正式学习C++的第一节课,主要篇幅介绍命名空间域namespace的相关内容,并对涉猎知识作出补充介绍

一、C语言的第一个问题:命名冲突

1. 冲突的各种情况

(1)我们写的和库里的关键字冲突
(2)不同人写的模块合并之后相互冲突

冲突举例

#include <stdio.h>
#include <stdlib.h>
int rand = 10;
// 这里由于stdlib库中含有rand关键字。因此再次定义将会产生冲突
int main()
{
    printf("%d\n", rand);
    return 0;
}
// 编译后后报错:error C2365: “rand”: 重定义;以前的定义是“函数”`

2. 冲突的解决方法

(1)C++学习的第一个关键字:namespace
(2)namespace的类型:
A. 官方命名空间域
B. 自定义命名空间域

命名空间内可以定义各种东西,包括变量、函数、结构体甚至嵌套命名空间

namespace zzw
{
 // 命名空间中可以定义变量/函数/类型
   int rand = 10;
   int Add(int left, int right)
   {
       return left + right;
   }
   struct Node
   {
       struct Node* next;
       int val;
   };
}

(3)namespace的访问

方法一:使用using将命名空间中的某个成员引入

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

方法二:使用using namesapce将命名空间引入

using namespce N;
int main()
{
    printf("%d\n", N::a);
    printf("%d\n", b);
    Add(10, 20);
    return 0;    
}

方法三:使用命名空间名称及作用域限定符

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

注一:头文件是将头文件中的内容cv到代码中,而命名空间域的展开是允许进入搜索,两者并不等同
注二:命名空间只可在全局域中展开,不能在局部展开

3. 域的相关知识补充

(1)域的种类
A. 命门空间域namespace
B. 类域
C. 局部域
D. 全局域
(2)不同的域可以定义同一个变量

示例代码如下

#include <stdio.h>
int a = 10;
int main()
{
    int a = 0;
    printf("%d\n", a);
    return 0;
}

(3)变量在多个域中的访问规则
A. 局部域优先,全局域次之

如何跳过局部域直接访问全局域

#include <stdio.h>
int a = 10;
int main()
{
    int a = 0;
    printf("%d\n", ::a);
    return 0;
}

B. 命名空间域没有展开或者指定访问是不会进行搜索的

问:展开命名空间之后,全局和命名空间谁被访问
答:展开命名空间可以理解为把空间内部的东西放到全局中(虽然我们知道本质只是允许进入搜索),因此展开之后会突然变量冲突而报错

4. 学成归来:解决一开始的冲突问题

#include <stdio.h>
#include <stdlib.h>

namespace zzw
{
    int rand = 10;
}
int main()
{
    printf("%d\n", zzw::rand);
    return 0;
}

问:我直接在局部定义一个rand不就好了吗
答:那样就变成局部变量了,有违初衷

二、命名空间的嵌套

1. 为什么需要嵌套

答:域太大自身也容易冲突,因此进行“分装”

嵌套代码示例

namespace N1
{
int a;
int b;
int Add(int left, int right)
 {
     return left + right;
 }
namespace N2
 {
     int c;
     int d;
     int Sub(int left, int right)
     {
         return left - right;
     }
 }
}

2. 嵌套之后如何访问

namespace N1
{
    int a = 1;
    namespace N2
    {
      int a = 0;
    }
}
int main
{
    printf("%d\n"N1::N2::a);
}

3. 多个同名的命名空间会被合并

问:合并之后要是变量冲突了怎么办
答:再定义一个空间域进行嵌套即可

三、基于命名空间浅谈输入输出

1. std是什么?

答:std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中

2. 为什么代码中常常出现std的展开

答:因为cout、cin、endl等关键字在std域中

#include<iostream>
//使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件,以及按命名空间使用方法使用std。
using namespace std;
int main()
{
    cout<<"Hello world!!!"<<endl;
    return 0;
}

注:实际上cout和cin分别是ostream和istream类型的对象,>>和<<也涉及运算符重载等知识,这些知识我们我们后续才会学习
注:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文件不带.h

3. 比展开std更好的选择?

A. 为什么直接展开不好
答:展开有风险,容易冲突报错,当然平时直接展开也不会有问题
B. 更好的选择:指定访问

using std::cout

四、输入输出

1. <<和>>

答: <<是流插入运算符,>>是流提取运算符

2. cout 、cin和 endl

答:cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream >头文件中。

3. cout与printf

A. cout的好处:可以自动识别类型
B. cout的坏处:精度调节异常麻烦
注:c++可以兼容c,因此需要精度调节可以直接使用printf
问:printf的输出比printf快?
答:正确的,因为c++兼容c
注意:c++对于c的兼容可以关闭,以此提速

总结

本节课主要对命名空间域namespace的使用做出了较为完整的说明,并涉猎了一点输出输入的内容,这方面会在后面做更详细的介绍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值