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
#include

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

C++基础知识-----命名空间_第1张图片

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

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

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

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

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

#include
using namespace std;

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

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

#include
#include
//域
namespace hello {
	int rand = 10;
}

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

C++基础知识-----命名空间_第2张图片

 我们先看这段代码

#include
#include

int a = 0;
int main() {
	int a = 10;
	printf("%d", a);
	return 0;
}

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

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

C++基础知识-----命名空间_第3张图片

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

我们再看这样一段代码

#include
#include

int a = 0;
namespace hello {
	int a = 10;
}
int main() {
	int a = 20;
	
	return 0;
}

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

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

C++基础知识-----命名空间_第4张图片

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

C++基础知识-----命名空间_第5张图片

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

C++基础知识-----命名空间_第6张图片

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

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

那如果我们想要同时访问3个a呢?
C++基础知识-----命名空间_第7张图片

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

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

C++基础知识-----命名空间_第8张图片

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

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

C++基础知识-----命名空间_第9张图片

我们再回过头来解决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;
		}
	}
}

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

嵌套的命名空间我们需要访问时要进行如下操作
C++基础知识-----命名空间_第10张图片

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

C++基础知识-----命名空间_第11张图片

这里我定义了两个头文件

C++基础知识-----命名空间_第12张图片

C++基础知识-----命名空间_第13张图片

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

C++基础知识-----命名空间_第14张图片

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

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

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

#include

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

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

C++基础知识-----命名空间_第15张图片

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

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

C++基础知识-----命名空间_第16张图片 但是这样写我们每次都要加std::,是非常麻烦的

C++基础知识-----命名空间_第17张图片

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

 C++基础知识-----命名空间_第18张图片

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

C++基础知识-----命名空间_第19张图片我们展开的话是要去std里搜索,但前提是上面有std,如果没有的话也是不行的 ,不加是不会搜索的

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

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

C++基础知识-----命名空间_第20张图片

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

3.C++的输入与输出

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

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

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

C++基础知识-----命名空间_第21张图片

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

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

C++基础知识-----命名空间_第22张图片

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

C++基础知识-----命名空间_第23张图片

>>叫做流提取运算符

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

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

如有错误,还请指正

你可能感兴趣的:(c++,c语言)