三、缺省参数
3.1缺省参数概念
缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
3.2缺省参数分类
①全缺省参数
所谓全缺省参数,就是在调用该函数时,没有指定一个实参而全部采用该形参的缺省值。
比如:
void Flower(int a = 66, int b = 88, int c = 99) { cout << "a==" << a << endl; cout << "b==" << b << endl; cout << "c==" << c << endl; }
②半缺省参数
比如:
void Flower(int a, int b = 88, int c = 99) { cout << "a==" << a << endl; cout << "b==" << b << endl; cout << "c==" << c << endl; }
注意:
1、半缺省参数必须从左往右,依次来给出,不能间隔着给。
void Flower(int a, int b = 88, int c = 99) { cout << "a==" << a << endl; cout << "b==" << b << endl; cout << "c==" << c << endl; } int main() { Flower(1);//会给到a值 Flower(1, 2);//给到a,b值 Flower(1, 2, 3);//给到a,b,c //Func(1, ,2);//间隔着给,不支持 return 0; }
2、缺省参数不能在函数声明和定义中同时出现
像这样,尽管定义和声明设置的缺省参数一致,但编译器依然报错,所以缺省参数不能在函数声明和定义中同时出现,要么都不出现,要么声明或定义一个出现。为什么这么设置呢?
如果生命与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用哪个缺省值。
3.缺省值必须是常量或者全局变量
这一条说明,我们可以把缺省参数和全局const定义的变量或者宏结合起来使用。
4.缺省参数C语言是不支持的。
四、函数重载
4.1函数重载概念
函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。
简单来说,函数重载是为了解决一类问题,什么问题呢?非常简单的举个例子,在C语言阶段,我们写一个加法函数,可以解决int类型,而我们要解决double类型的呢?还需要再写一个函数,并且名字还要不同,同样,还有比如要交换两个变量的值,int类型的写一个,double类型的再写一个,名字还要不同显然是很不方便的,因此便有了重载函数的概念。
①参数类型不同
int Add(int left, int right) { cout << "int Add(int left, int right)" << endl; return left + right; } double Add(double left, double right) { cout << "double Add(double left, double right)" << endl; return left + right; }
②参数个数不同
void f() { cout << "f()" << endl; } void f(int a) { cout << "f(int a)" << endl; }
③参数类型顺序不同
void f(int a, char b) { cout << "f(int a,char b)" << endl; } void f(char b, int a) { cout << "f(char b, int a)" << endl; }
参数类型顺序不同本质上也是参数类型不同,因为形参的命名是无所谓的。
4.2函数重载的二义性
并不是所有的函数重载都具有二义性的,仅在一些情况下会出现二义性导致出错。
①缺省参数导致的二义性
我们来看这段代码,出错的原因就在于编译器不知道执行哪个函数,因为我们调用的f()既可以指本身无参的f()函数,也可以指代不传参而使用缺省参数的函数f(int a=0,char b=1).所以才会有对重载函数的调用不明确的报错。
②返回值不同的二义性
相信有小伙伴注意到为什么返回值不同不能作为重载函数呢?
很简单,我们来看以下代码。
返回值不同是无法区分函数的,因为你传参是一样的,那么传到哪个函数呢?返回的时候返回哪个函数计算的值呢?这些都是不明确的,会导致二义性。
4.3 C++支持函数重载的原理
为什么C++支持函数重载,而C语言不支持函数重载呢?
之前博主有写过C语言预处理的相关内容,我们知道在预处理阶段需要经过预处理->编译->汇编->链接等过程。其中,在链接阶段要进行符号表的合并,符号表中寸的是一些变量,类型,函数等的地址,符合表合并后拿到有效地址。而C语言和C++在链接阶段对于符号表合并后地址的命名是不同的。我们可以来观察以下它们的命名。
采用C++编译器编译后结果:
我们通过对比,发现它们的命名是不相同的,在C语言编译器中,对于函数地址的命名是简单的,不考虑参数类型的,而C++是考虑到参数类型不同的,并且不同C++编译器有自己的命名规则,通过参数类型不同,就算函数名相同,命名也是不同的。所以,C++编译器是可以区分相同命名不同形参的函数的,也就是说,这就是它为什么允许函数重载!