> 文章列表 > C++基础知识-----命名空间

C++基础知识-----命名空间

C++基础知识-----命名空间

本期开始我们来对C++进行学习

目录

1.C++关键字

2.命名空间 

3.C++的输入与输出


1.C++关键字

C++总计63个关键字,C语言32个关键字

asm do if return try continue
auto double inline short typedef for
bool dynamic_cast int signed typeid public
break else long sizeof typename throw
case enum mutable static union wchar_t
catch explicit namespace static_cast unsigned default
char export new struct using friend
class extern operator switch virtual register
const false private template void true
const_cast float protected this volatile while
delete goto

reinterpret_cast

我们并不需要刻意的去记住这些关键字,在后续使用中我们就会慢慢熟悉他们

2.命名空间 

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

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

 我们在编译这一段代码时,会出现错误,在C语言中,并不会出现这种错误,但是在C++中却会报错

我们来看这段错误,是重定义,即我们定义的rand和库中的一个rand函数冲突,所以在C语言中,是存在命名冲突的

命名冲突主要包含两方面,一方面是我们和库冲突,所以在使用C语言写一些大型项目时会出现这样的问题,在我们引入某个库后会出现一堆报错,因为我们定义的变量或者函数和库里的冲突了,另一方面是我们互相之间冲突,比如两个人写一个项目,一个人定义了一个了一个变量a,另一个人也定义了一个变量a,最后两个代码是会合并的,而合并时就会出现冲突,此时就需要一个人来改变变量名,如果将这个变量使用了成百上千遍,那就非常麻烦了

为了解决这个问题,C++引入了命名空间

我们在网络上看C++代码时,经常能看到这样一段代码

#include<iostream>
using namespace std;

第二行的代码是什么意思呢?我们先将这个问题保留,一会回过头来看

为了使程序不冲突,我们使用域来进行隔离

#include<stdio.h>
#include<stdlib.h>
//域
namespace hello {int rand = 10;
}int main() {printf("%d\\n", rand);return 0;
}

 我们先看这段代码

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

我们知道,这两个a是可以同时存在的,main函数里的a是局部变量,也就是在局部域,而外部的a是全局变量,也就是在全局域,我们知道,运行这段代码,会输出10

如果我们想要访问全局的a,该如何访问呢?

在C++里,我们可以使用::来进行访问,:: 叫做域作用限定符,局部域和全局域,是优先在局部搜索,没有局部才在全局搜索,::的左边什么也没有(加上空白是为了好看)

我们再看这样一段代码

#include<stdio.h>
#include<stdlib.h>int a = 0;
namespace hello {int a = 10;
}
int main() {int a = 20;return 0;
}

这3个a我们该如何访问呢?

 如果我们直接进行访问,访问的是局部的a

如果局部不存在,接下面就是全局搜索了 ,而命名空间域里的变量,不指定是不会去搜索的

 如果想要访问命名空间域,有两种操作,一种是展开命名空间域,另一种是指定访问命名空间域

所以using namespace是展开命名空间域,此时我们回过头来看using namespace std;

这段代码的意思就是展开命名空间域,而这个std是标准库的命名空间

那如果我们想要同时访问3个a呢?

 这个操作就是指定访问命名空间域,::前面什么都不加,就是访问全局域

我们再看这种情况,展开的本意就是暴露到全局,所以是会报错的

此时就不知道你需要访问哪一个了

所以我们不要轻易展开命名空间,展开是编译时是否去命名空间中搜索,没有展开就不会去搜索

我们再回过头来解决rand的问题,我们只需指定访问即可解决 

命名空间除了定义变量,还可以定义函数,定义类型,唯一要注意的是命名空间最后的 } 后是没有 ; 的

命名空间也是可以嵌套的

namespace n1
{int a = 10;;int b;int add(int left, int right){return left + right;}namespace n2{int a = 20;int c;int d;int sub(int left, int right){return left - right;}}
}

命名空间过大时,为了防止冲突时就需要使用嵌套分割

嵌套的命名空间我们需要访问时要进行如下操作

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

这里我定义了两个头文件

在每个头文件里都定义了hello的命名空间

我们在test.c里可以对这三个命名空间里数据进行访问,这三个命名空间合并成了一个命名空间

C++里有STL库,每个库都有命名空间,最后也合并在一起,就是这样使用的

 下面,我们回过头来看这句代码

#include<iostream>

我们发现c语言的头文件都是xxx.h,而c++不是.h,为什么呢?

其实在早年的时候,是有#include<iostream.h>的,但是现在只能在很老的编译器下使用,这个头文件是没有命名空间的,但是C++后面有了命名空间后,很多库都用了命名空间,,而且有时候会和C有冲突,比如C的string.h,在C++里也有string,所以C++标准库就直接把.h去掉了

C++的iostream库里有一个cout,这个类似C里面的printf,但是我们发现这里报错了,原因就是我们上面说的,如果我们不指定访问或者展开命名空间,就不会去主动搜索

我们的一种解决办法为让他直接去命名空间搜索

 但是这样写我们每次都要加std::,是非常麻烦的

第二种办法就是我们展开命名空间

 

 另外,我们展开不展开都是可以加std::的,一般是推荐使用第一种方法

我们展开的话是要去std里搜索,但前提是上面有std,如果没有的话也是不行的 ,不加是不会搜索的

但是用using namespace std;全部展开是有风险的,如果我们和库有冲突,就会报错

所以我们建议项目里面不要展开,在项目里我们用指定访问,不要轻易展开

我们使用这种办法,展开常用的即可

3.C++的输入与输出

我们在上面使用了cout,这是一个全局对象

我们发现cout << "hello "  << endl;

<<在C里面叫做移位运算符,在C++里叫做流插入运算符,并且可以支持多个值输出

我们输出了字符串hello world,输出了10,\\n是换行,endl也是换行,endl也是全局的

cout相比于printf,真的强大的地方在于自动识别类型,我们使用printf需要指定%d,%f等等,而cout不需要指定类型

 既然有cout,与之对应的还有cin,这个类似scanf

>>叫做流提取运算符

这几个可以混着用,大家怎么舒服怎么来就行

以上即为本期全部内容,希望大家可以有所收获

如有错误,还请指正