命名空间
由来
在c语言中,任何函数,变量的名字都不能一样,如果是一个人的代码库里还好,大不了自己再改改,但是当和其他人,公司的库合起来,那就很麻烦了,到底是谁的名字改呢,不免有很多冲突。
c++针对这一情况引进了命名空间(namespace)的语法
命名空间是什么?
- 访问变量默认是在全局域里去访问的,相当于一片草原
- 如果main函数里也有相同名字的定义就符合就近原则
- namespace则相当于在草原上起了一个围墙,和进击的巨人里的围墙一样,namespace也可以嵌套定义,那就是多重围墙了
- namespace zzb 即是命名空间的定义,不需要加分号
namespace zzb
{
int age=19;
namespace partner
{
int age=20;
}
}
有了命名空间,就算有相同的名字也不怕啦,我们可以根据我们所想访问变量
命名空间的三种使用方式
- 命名空间名称+作用域限定符——zzb::a
- using将命名空间中的某个成员引入,using zzb::a
- using namespace+名称——相当于将围墙扑倒,如果这时候命名空间里的变量或者函数和全局变量里的变量或者函数名字相同的时候,编译器就会不知道访问哪个而报错了
注意事项
- 如果同一个工程里存在多个名字相同的命名空间,那么最后会合并成一个命名空间
- 一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中可以包含变量,函数,结构体
c++的输入输出
- c++常用cin,cout作为输入输出的函数,其相比于scanf,printf的最大的好处就是可以自动识别类型,这里涉及函数重载的知识,我们后续再详谈
- 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件
- cout对应的是<<,为流插入运算符
- cin对应的是>>为流输出运算符
- 要使用cin,cout的前提就是要在工程开头加一个using namespace std;
std是C++标准库的命名空间
1. 在日常练习中,建议直接using namespace std即可,这样就很方便。
2. using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对
象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模
大,就很容易出现。所以建议在项目开发中使用,像std::cout这样使用时指定命名空间 +
using std::cout展开常用的库对象/类型等方式。
缺省参数(默认参数)
缺省参数也就是默认参数的意思,如果你传参了那么形参就是你传的值,如果没传就是默认值
主要分为全缺省和半缺省两种类型
全缺省
就是全部参数都有默认值
Add(int a=10,int b=10,int c=10)
{
return a+b+c;
}
int main()
{
Add();
return 0;
}
//结果为30
半缺省
部分参数有默认值,注意不是字面意思一半参数有默认值的意思
int Add(int a=10,int b=10,int c)
{
return a+b+c;
}
int main()
{
Add(,,10);
return 0;
}
以上的调用方法是错误的,半缺省参数必须从左到右依次给出
注意:
- 1. 半缺省参数必须从右往左依次来给出,不能间隔着给
- 2. 缺省参数不能在函数声明和定义中同时出现
函数重载
可以形象地理解为一词多义的意思,在c语言中定义一个Swap(int*a,int*b)可以交换两个整形
但是要交换两个浮点数的话,只能换个名字接着定义了,这很影响我们的体验感
而函数重载被发明出来解决这一问题,c++里只需要Swap(double*a,double*b)即可,用的时候会感觉就是在使用一个函数一样,提高我们的使用感
函数重载触发的三个条件
- 参数个数不同
- 参数类型不同
- 参数顺序不同
注意:返回值不同不能作为重载的条件;要在相同的作用域中
当其与前面的namespace结合起来时,又有有趣的画面
//这里就不是函数重载了,因为他们的作用域不同
namespace zzb
{
void Func(int a)
namespace zzb2
{
void FUnc(float a)
}
}
为什么c语言不支持函数重载而c++支持函数重载呢?
在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接
- 1. 实际项目通常是由多个头文件和多个源文件构成,而通过C语言阶段学习的编译链接,我们可以知道,【当前a.cpp中调用了b.cpp中定义的Add函数时】,编译后链接前,a.o的目标文件中没有Add的函数地址,因为Add是在b.cpp中定义的,所以Add的地址在b.o中。那么怎么办呢?
- 2. 所以链接阶段就是专门处理这种问题,链接器看到a.o调用Add,但是没有Add的地址,就会到b.o的符号表中找Add的地址,然后链接到一起。
- 3. 那么链接时,面对Add函数,链接接器会使用哪个名字去找呢?这里每个编译器都有自己的函数名修饰规则。
由上我们可以得知正是因为不同参数个数,参数类型不同,参数顺序不同可以导致函数名发生变化
- 而编译器就可以根据函数名的不同来调用不同的参数
- 这里我们也更深刻地认识了为什么返回值不同的函数不能作为重载的条件,因为其不能改变函数名,编译器也就不能区分出它和原来函数的区别而不知道调用哪一个函数,从而报错
- c语言正是因为只通过函数名称找函数,没有修饰规则,所以不能区分调用哪一个寒素,所以不支持重载
总结
好久没写博客了,之前都在突击期末落下了很多,今天开始会经常更新的
迈过初阶数据结构的坎,开启c++的大门了,希望自己能继续加油
以上为入门篇的总结,希望对大家能有所帮助!