目录
1. 命名空间
在C/C++中,我们总会遇见重名的情况,而这种情况又给我们带来了许多的不便,所以我们设计了命名空间,将在此定义的变量、类与外界隔绝起来,防止被污染。
1.1 命名空间的定义
既然说到了命名空间的由来,那我们如何来定义一个命名空间?
定义命名空间我们需要一个关键字 - namespace,也是好理解的一个关键字,后面跟上空间名,接下来我们需要使用一对{ }在这里面定义我们的成员变量。
例如:
namespace Stack {
int a;
int b;
}
那里面的成员可以是函数吗?
namespace Stack {
int a;
int b;
int add(int c, int d) {
return c + d;
}
}
答案也是可以的,除此之外命名空间还可以嵌套命名空间
比如:
当创建命名空间一样的两个头文件,则会发生报错,而我又不愿意去改变变量的名字,那如何去改变呢?
这里我们加入一个嵌套,我们会发现之前的警告消失了,这也说明C++的功能是在一个一个坑中生成的。
但我们从上图也可以发现 a,b为什么重定义了呢?
当两个同名的命名文件在一起被执行时,编译器会将两个命名空间合并成为一个。
因此编译器实际上看到的是这样的:
相当于我们重复定义了a和b,那我们如何去改正这个错误呢?
1. 改变变量名 2.将其中一个a和一个b放入queue空间中
这样就不会发生报错。
2. C++如何输入输出
使用说明:
使用cout标准输出(控制台)和cin标准输入(键盘)时,必须包含头文件iostream和释放std命名空间。
代码展示:
3. 缺省参数
3.1 什么是缺省参数?
缺省参数是声明或定义函数时为函数的参数指定一个默认值。在调用该函数时,如果没有指定实参则采用该默认值,否则使用指定的实参。
缺省参数又分为两种情况:
1. 全缺省参数
void TestFunc(int a = 10, int b = 20, int c = 30)
{
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
}
给所有的参数指定一个默认值。
2. 半缺省参数
void TestFunc(int a, int b = 10, int c = 20)
{
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
}
给部分参数默认值。
注意:
1. 半缺省参数必须从右向左进行给出。
2. 缺省参数不能在声明和定义中同时存在。
为什么会出现这个错误呢?
这是因为在声明和定义中都使用缺省参数会造成歧义的存在,因此禁止在声明和定义中同时存在缺省参数。
3. 缺省参数只能是常数或者全局变量
4. 在C语言中是不支持缺省参数
4. 函数重载
4.1 什么是函数重载?
函数重载:是函数的一种特殊情况,C++中允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数或类型或顺序)必须不同。
这就是重载的一种形式。
那我们说到了参数个数或类型或顺序不同才能形成重载,那类型不同呢?是否也可以形成重载?
我们发现当只有类型不同时无法重载,给出的原因是无法区分函数,那在C++中又是怎么区分其他同名的函数呢?
4.2 名字修饰
为什么C++就支持重载,但C不支持重载呢?为什么只有类型不同也不能进行重载呢?
在这一段中我们就会讲出原因:
在一段C/C++程序运行起来会经历四个过程:预处理、编译、汇编、链接
预处理又分为四个主要流程:1. 头文件的展开 2. 宏的替换 3. 替换注释 4. 条件编译
编译:将C/C++语言转换成汇编语言,并且检查语法错误。
汇编:将汇编语言转为二进制语言。
链接:合并段表,生成符号表。
在此处我们需要关注的是在编译这个阶段
这里我们实现了重载
这里我们通过Linux下调至汇编这个阶段,我们可以发现两个同名的函数在C++中函数名被分别修饰成了_Z1fii、_Z1fdd,这样两个同名的函数就发生了变化。
那在C语言中函数名也会发生修改吗?
我们发现在C语言中函数名在编译过程后不会发生函数名修饰,这也是为什么C++可以进行重载而C语言无法进行重载的原因。
因为在之后的链接过程中,我们需要通过函数名在符号表中找寻函数,那如果函数名都一样的话怎么才能保证找到的是自己想要的呢?
既然已经回答了第一个问题,那第二个问题:为什么类型不能分辨函数呢?
我们可以发现当返回类型不同时,函数名不会发生改变,如果只有返回类型不同时,无法分辨函数。
除此之外我们也可以发现C++中函数名修饰的规律:_Z+函数长度+函数名+类型首字母。
既然如此我们可以发现C和C++在同一个过程中有着不同的操作,那我们是否可以在C++中使用C库呢?
5. extern "C"
在某些C++工程中我们可能会需要使用C库中的程序,但C程序又无法使用,我们应该怎么办呢?
这里我们就提及到了一个新的东西 -- extern "C",它可以帮助我们完成在C++中使用C库,也可以在C中使用C++库。
5.1 在C++中使用C库
1. 创建一个C的静态库来验证操作。
2. 在一个C++项目中使用该库
这里我们先需要在该项目属性中引入该C库的目录。
然后我们需要在输入中的附加依赖项添加该静态库的名称,以便于我们找到目标库。
接下来我们需要找到该库中头文件的相对路径并包含起来。
这样我们就可以找到该库中定义的函数并且进行使用。
可是当我们调用该库中的函数时会出现一下问题,这是什么原因呢?
学习了函数命名,我们知道C和C++对于函数的命名修饰是不同的,这样在链接过程中我们是无法找到C语言修饰过的函数。因此会爆出此函数无法解析的错误,那我们如何解决这个问题呢?
当给头文件加上extern"C",此问题就会解决。
在函数前加extern "C",意思是告诉编译器,将该函数按照C语言规则来编译,那么在链接时C++编译器会根据C语言的方式来找寻函数并使用。