前文:
C++ 是一种高级语言,它是由 Bjarne Stroustrup 于 1979 年在贝尔实验室开始设计开发的。C++ 进一步扩充和完善了 C 语言(补充C语言语言的不足,以及C++是如何对C语言设计不合理的地方进行优化的,比如:作用域方面、IO方面、函数方面、指针方面、宏方面等。),是一种面向对象的程序设计语言。
C++是在C语言的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式等。
文章目录
![请添加图片描述](https://img-blog.csdnimg.cn/direct/70b40620b42f4547b337bf1af1ef3d42.gif)
命名空间
在C++中,对于符号常量、变量、函数、类和对象等。在工程中,会频繁地对对象取名称,这会可能导致名称冲突(程序员间或者程序员和头文件间)。使用命名空间的目的:对标识符的名称进行本地化,以避免命名冲突或名字污染(namespace关键字解决这样子的问题,在不同域下重复命名是被允许的)
#include <stdio.h></font>
#include <stdlib.h>
int rand=10;
int main()
{
printf("%d\n",rand);
return 0;
}
报错:“rand”: 重定义;以前的定义是“函数”
创建一个整型变量名称为rand,rand是stdlib.h声明的库函数,在预编译阶段头文件会展开,会导致rand重命名;
命名空间的定义
定义命名空间的格式(需要使用关键字namespace)
namespace 命名空间名字
{
命名空间成员
}
命名空间相关特点及说明
- 一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中
- 命名空间中可以定义变量/函数/类型
- 命名空间可以嵌套
- 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中
对于第一点:
Cpp具有域的概念,目前先阶段所接触到的域有全局、局部作用域加上现在的命名空间域。在函数外定义的命名空间与全局、局部作用域的关系。对于命名空间可以看成一个被圈起来的私人空间。
第二点:定义变量/函数/类型
namespace N
{
int a;
int b=10;
int Add(int x,int y)
{
return x+y;
}
struct N
{
int c;
};
}
第三点;可以嵌套
面对不同场景,需要嵌套多层命名空间起到隔离的效果
比如:现在A公司有一堆重要数据,A公司用命名空间将这些数据圈起来。A公司里面有两个程序员B和C。B程序员做了个Push函数实现压栈的功能,而C程序员做了Push函数实现插入元素的功能,在A公司所定义的命名空间,出现名称冲突的问题,对此需要B和C程序员定义自己的命名空间存放自己的数据。这里就需要命名空间的嵌套。
#include <iostream>
using namespace std;
namespace A_company
{
namespace B_epe
{
Push();
}
namespace C_epe
{
Push();
}
}
使用方式:cout<<A::B_epe::内容<<endl;
第四点:
//test.h
namespace N
{
int a;
int d;
}
//test.cpp
namespace N
{
int a=1;
int Add(int x,int y)
{
return x+y;
}
}
报错:“int N::a”: 重定义.报错的原因不是命名空间名称冲突,而是当相同名称的命名空间合并同一个命名空间中,变量a名称冲突导致
先简单介绍下:编译器搜索原则
不指定域:1.当前局部域 2.全局域
指定域:如果指定域,直接去指定域搜索(优先去域中搜索,比如std::cout)
::是域作用限定符(优先向全局范围搜索)
使用场景
int x=10;
int main()
{
int x=1;
printf("%d\n",x);//1
printf("%d\n",::x)//10
return 0;
}
命名空间的使用有三种方式
namespace N
{
int a=1;
int b=0;
int Add(int x,int y)
{
return x+y;
}
}
1.加命名空间名称及作用域限定符
int main()
{
printf("%d\n",N::a)
return 0;
}
2.使用using将命名空间中某个成员引入
using N::b;
int main()
{
printf("%d\n",b);
printf("%d\n",N::a)
return 0;
}
//将N命名空间中变量b的权限打开
3.使用using namespace命名空名称引入
using namespce N;
int main()
{
printf("%d\n", N::a);
printf("%d\n", b);
Add(10, 20);
return 0;
}
//将N命名空间展开(跟头文件的展开是不同的,就像李大爷说你可以来我家菜园顺便采菜)
简单了解:C++输入和输出
#include <iostream>
using namespace std;
int main()
{
cout<<"Helloc world"<<endl;
return 0;
}
说明:
-
使用cout标准输出对象(控制台)和cin标准输入对象时,必循包含头文件以及按照命名空间使用方式使用std
-
cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含头文件中
-
<<是流插入运输符,>>是流提取运算符
-
使用C++输入输出更加方便,不需要像printf/scanf输入输出时那样,需要手动控制格式,。C++的输入输出可以自动识别变量类型
-
实际上cout和cin分别时ostream和ostream类型的对象,>>和<<也涉及运算符重载等知识。 这里只需要简单学习他们的使用就行,后面还有不断深入学习
注意:早期标准库将所有功能在全局域中是实现,声明在.h后缀的头文件中,使用时只需包含对应头文件即可,后来将其实现在std命名空间下,为了和C语言中头文件区分,也为了正确使用命名空间,规定C++头文件不带.h.旧编译器(vc6.0)中还支持<iostream.h>格式,后续编译器已不支持,因此推荐使用+std的方式
关于第三、四点
#include <iostream>
using namespace std;
int main()
{ //为什么Cpp兼容C,对此一些符号可以有多重意思
<<:可以表示左移或者流插入(自动识别类型)
int i=10;char p='a';
i=i<<1;
cout<<i<<p<<endl;
>>:可以表示右移或者流提取(自动识别类型)
int a=0;
cin>>a;
关于自动识别类型的功能:关于精度打印可以使用printf函数
比如:double d=1.11111;
printf("%.2lf\n",d);
cout<<d<<endl;
对此显然时printf更加胜任这些操作,当然可以根据不同场景选择输入即可。
return 0;
}
其中关于cout和cin还有很多更加复杂的用法,这里就不展开学习
std命名空间的使用惯例
std是C+标准库的命名空间,如何展开std使用更加合理呢?
-
在日常练习中,建议直接使用using namespace std即可,这样就很方便。
-
using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多,规模大,就很容易出现。所以建议在项目开发中使用,向std::cout这样使用时指定命名空间和using std::cout展开常用的库对象/类型等方式。