缺省参数
概述
缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
举例:
void fun(int a = 5) { cout << a << endl; } int main() { fun(10); //传参,使用指定的参数-->10 fun(); //没有传参,使用参数的默认值 return 0; }
在这串代码中,在fun
函数中有一个形参int a = 5
,主函数中,fun(10)
,传了参数,于是在fun
函数中就是用传的参数;而fun()
中没有传参数,就是用参数的默认值。
输出结果:
10 5
缺省参数的分类
全缺省
void Func(int a = 10, int b = 20, int c = 30) { cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c << endl; } int main() { Func(); return 0; }
结果:
a = 10 b = 20 c = 30
主函数中Func()
没有任何参数,则全部使用缺省值。
半缺省参数
void Func(int a = 10, int b = 20, int c = 30) { cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c << endl << endl; } int main() { Func(1, 2, 3); Func(1, 2); Func(1); return 0; }
结果:
a = 1 b = 2 c = 3 a = 1 b = 2 c = 30 a = 1 b = 20 c = 30
半缺省参数必须从右往左依次来给出,不能间隔着给
Func(1, 2)
是给了第一个参数和第二个参数值,,而没有给第三个参数值
Func(1)
只给第一个参数传了值
不存在只给第一个参数和第三个参数传值的说法,这种是错误的,只能从左至右一次给出。
注意
- 缺省参数不能在函数声明和定义中同时出现
//test.h void Func(int a = 10); // test.cpp void Func(int a = 20) {}
如果生命与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值
- 缺省值必须是常量或者全局变量
函数重载
在汉语中,一个词语会有多种意思,人们可以结合语境可以判断一个词的意思。如“方便”一词:”你现在方便嘛”、“我要去方便一下”。
概述
函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。
重载类型不同
参数类型不同
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; } int main() { cout << Add(2, 3) << endl; cout << Add(2.0, 3.0) << endl; }
运行结果:
函数名称同为Add,但是定义此函数的类型不同,一个是int,另一个是double,在主函数中调用的Add函数,如果传的参数为int型,那么调用int Add(int left, int right);如果传的参数为double型,那么调用double Add(double left, double right)。
编译器会根据参数类型,自动选择调用的函数
参数个数不同
void fun() { cout << "f()" << endl; } void fun(int a) { cout << "f(int a)" << endl; } int main() { fun(); fun(1); return 0; }
运行结果:
主函数中,第一个调用的函数fun()
,没有参数,第二个调用的函数fun(1)
传了一个参数,属于参数不同的情况。
但是在无参调用时,出现了歧义,对于两个fun
函数来说,都可以不传参。
参数类型顺序不同
void Text(int a, char b) { cout << "Text(int a,char b)" << endl; } void Text(char b, int a) { cout << "Text(char b, int a)" << endl; } int main() { Text(1, 'a'); Text('a', 1); return 0; }
运行结果:
编译器自己会根据传入的参数类型不同而选择相应的函数。
C++支持函数重载的原理
为什么C++支持函数重载,而C语言不支持函数重载呢?
在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接。
预处理是展开头文件/宏替换/条件编译/去掉注释
编译是检查语法,转成汇编代码
汇编是把汇编代码转成二进制机器码
实际项目通常是由多个头文件和多个源文件构成,而通过C语言阶段学习的编译链接,我们
可以知道,【当前a.cpp中调用了b.cpp中定义的Add函数时】,编译后链接前,a.o的目标
文件中没有Add的函数地址,因为Add是在b.cpp中定义的,所以Add的地址在b.o中。
如何处理这一问题?
链接阶段就是专门处理这种问题,链接器看到a.o调用Add,但是没有Add的地址,就
会到b.o的符号表中找Add的地址,然后链接到一起。每个编译器都有自己的
函数名修饰规则。
Windows系统下的命名规则稍复杂,在Linux操作系统下会简单些,可参考文章–>Linux编译器-gcc/g++