目录
1.缺省参数
1.1 缺省参数定义
定义:缺省参数是声明或定义函数时,为函数的参数指定一个默认值。在调用函数时,如果没有指定实参则采用该默认值,否则使用指定的实参。
举个例子,你晚上准备一个人吃水煮肉片(默认),如果有人约你吃饭,你就马上会去吃他安排的(指定的实参),如果没人约,还是吃默认的水煮肉片。
#include<iostream>
using namespace std;
void test(int x = 1)
{
cout << x << endl;
}
int main()
{
test();
test(30);
return 0;
}
在没有指定的实参时,打印默认值,1 在指定实参后 ,打印 30.
1.2 缺省参数分类
1.2.1全缺省参数
即函数的所有参数都是缺省参数
void test1(int a = 1, int b = 2, int c = 3)
{
cout << a<< endl;
cout << b << endl;
cout << c << endl;
}
test1 函数的所有参数都是缺省参数,这理解起来没有困难。
但是我们需要注意的是,在对全缺省参数指定实参时,只能按照从左到右依次,做不到指定位置。
void test1(int a = 1, int b = 2, int c = 3)
{
cout << a<< endl;
cout << b << endl;
cout << c << endl;
}
int main()
{
test1(20);
cout << endl;
test1(20, 30);
cout << endl;
test1(10, 20, 30);
cout << endl;
return 0;
}
当我们尝试指定位置时,会报错,C++并不支持这种功能。
1.2.2 半缺省参数
半缺省参数 实际上指的是 部分缺省参数。即函数的有一部分参数为缺省参数。
缺省参数必须从右往左,且连续,不满足其中的任一条件都会报错。
void test2(int a, int b = 1)
{
cout << a << endl;
cout << b << endl;
}
int main()
{
test2(20);
cout << endl;
test2(20, 40);
return 0;
}
我们还需要注意的点
缺省参数不能在函数的声明和定义中同时初现 (推荐在声明时使用缺省参数,更直观)
缺省值必须是常量,或者全局变量
2. 函数重载
2.1 函数重载概念
函数重载是函数的一种特殊情况,C++ 允许在同一作用域中,声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数或类型或顺序)必须不同。
例如
int Add(int x, int y)
{
return x + y;
}
double Add(double x, double y)
{
return x + y;
}
long Add(long x, long y)
{
return x + y;
}
int main()
{
cout<<Add(5, 10)<<endl;
//cout << Add(1.1, 1.2)<<endl; cout标准输出时,自动识别数据类型,不利于我们判断
printf("%lf", Add(1.1, 1.2));
cout << endl;
//cout << Add(10L, 20L) << endl;
printf("%ld", Add(10L, 20L));
}
这个例子就很好的展示的函数重载,但是可能有细心的读者也发现了上述几个函数的返回值类型不同,注意,返回值类型不是判断函数重载与否的标准 , 判断的标准从来只有 参数类型,个数,顺序 三个方面。
2.2 名字修饰
C++支持函数重载,为什么C语言不支持?
我们需要更深层次的理解
在C/C++中,一个程序的运行过程需要经历 :预处理 编译 汇编 链接
(26条消息) C语言提高篇——程序环境和预处理_杨斯文。的博客-CSDN博客
简单回顾一下编译器编译程序的过程
1.预处理 -> 头文件展开 ,宏替换,条件编译,去掉注释
2.编译 -> 检查语法 ,生成汇编代码 ,语法,词法,语义分析,符号汇总
3.汇编 -> 汇编代码转换二进制机器码 ,形成符号表
4.链接
在C语言中,编译时,由于C语言是直接通过函数名标识和查找,两个重载函数,函数名相同,在形成符号表时,就会存在歧义和冲突,其次在链接时,也存在歧义和冲突。
C++的目标文件符号表不是直接用函数名来标识和查找函数,有自己的函数名修饰规则,不同的编译器有不同的规则。g++ 的修饰函数名规则 : _Z + 函数名长度 +函数名 +参数首字母
因为修饰规则的存在,只要参数不同,那么在符号表中的重载函数就不存在歧义和冲突了。
实际我们的项目通常由多个头文件和源文件构成,在一个文件中,如果文件有函数的定义,编译时,直接填上地址,如果当前文件只有函数的声明,那么定义就在其他的源文件中,此时只能链接时去其他的文件的符号表中根据函数的修饰名称去找,这也是链接的重要工作。
总结 : C语言直接使用函数名来标识和查找函数,它无法区分同名函数,不支持重载。C++ 是通过函数修饰规则来区分,只要参数有不同,就可以区分同名函数,实现重载。