1.缺省参数
先看一个简单的函数,功能就是打印出传递过来的数字:
#include <iostream> using namespace std; void Func(int num) { // 此时接收,num = 1 cout << num << endl; } int main() { Func(1); // 传参:1 return 0; }
如果我不想传参呢?我想直接调用 Func 函数:
#include <iostream> using namespace std; void Func(int a) { cout << a << endl; } int main() { Func();//此时就会报错 return 0; }
因为没有传递参数,所以自然会引发报错。
不过,在C++里我们可以利用一个叫 "缺省参数" 的东西,
让该函数可以做到不传参也能运行的效果。
#include <iostream> using namespace std; void Func(int a = 0) { cout << a << endl; } int main() { Func();//成功打印0 return 0; }
下面我们就将学习这个神奇的 "缺省参数" 。
1.1缺省参数概念
缺省参数通俗讲就是默认参数
缺省参数: 声明或定义函数时 为函数的 参数指定一个缺省值 。在调用该函数时,
如果没有指定实 参则采用该形参的缺省值,否则使用指定的实参。
简单来说就是:传参了就用传来的值,没传参就用默认值。
1.2缺省参数的使用:
#include <iostream> using namespace std; void Func(int a = 0) // 缺省值作为形参,传给 a { cout << a << endl; } int main() { Func(10); // 传参时:使用指定的实参(传入10) Func(); // 没有传参时,使用默认的参数值(默认值:0)。 return 0; }
① 第一次调用 Func 时,指定了实参,就会照常传入,这里指定的是 10,所以传过去的是 10。
② 第二次调用 Func 时,并没有指定实参,所以进入函数后,
形参 a 会取缺省值 0 作为参数的值。
③ 因此,第一次打印的结果是 10,第二次打印的结果是 0。
注意:
① 声明不能在 .h 和 .cpp 里同时出现缺省参数,要么声明里写,要么在定义里写!
② 缺省值必须是常量或全局变量。
② 缺省参数C++里面的,C语言不支持(编译器不支持)。
1.3缺省参数的分类
缺省参数分为 全缺省参数 和 半缺省参数。
① 全缺省参数:函数中的所有参数都给了缺省值。
② 半缺省参数:函数中的参数从右往左给一部分的缺省值。
1.3.1 全缺省参数
必须所有参数都带有缺省值,才能叫作全缺省参数。
代码演示:
#include <iostream> using namespace std; void Func(int a = 10, int b = 20, int c = 30)、 { printf("%d %d %d\n", a, b, c); } int main() { Func(); // 不穿,一个都没传 Func(1); // 只传了一个 Func(1, 2); // 传了两个,但没完全传 Func(1, 2, 3); // 全都传了,就没缺省参数什么事了 return 0; }
打印:
10 20 30
1 20 30
1 2 30
1 2 3
解析:
① 第一次调用 Func 时,什么都没有传,所以结果直接就采用默认值。
② 第二次调用 Func 时,只传了一个参数,那么结果只有 a 不是默认值。
③ 第三次调用 Func 时,传了两个参数,那么结果只有 c 会是默认值了。
④ 最后一次调用 Func 时,所有参数都传了,那么结果都不会是默认值。
只想传中间的b可以吗?:
#include <iostream> using namespace std; void Func(int a = 10, int b = 20, int c = 30) { printf("%d %d %d\n", a, b, c); } int main() { Func(, 2,);//错误 return 0; }
不可以!
参数的传递按照语法是从左往右传递的,因为这是语法定死的,所以没有办法传。
1.3.2 半缺省参数
半缺省参数:函数中的所有参数从右往左连续地缺省一部分
这一部分可以是多个参数,也可以是一个参数(一个也算一部分),
但是它们必须是 "连续地" 。参数传递顺序根据根据函数调用约定。
注意事项:
① 半缺省并不是缺省一半,而是缺省一部分。
② 半缺省参数必须从右往左缺省,且必须是连续地。即,必须从右往左连续缺省。
吐槽:既然不是缺省一半,还叫半缺省参数,这合理吗?这不合理!(小声)
这个 "半" 字确实用的不合理,倒不如叫 "部分缺省参数" ,会显得更加合理一些。
代码演示:
#include <iostream> using namespace std; // 从左往右 "连续地" void Func(int a, int b, int c = 30) { printf("%d %d %d\n", a, b, c); } /* 半缺省:从右往左连续地缺省一部分参数 a - 必须传 (因为没缺省) b - 必须传 (因为没缺省) c - 可传可不传 (因为缺省了) */ int main(void) { Func(1, 2); // a b 没缺省,所以必须要传,c缺省了所以可以不传 Func(1, 2, 3); // 都传 return 0; }
打印:
1 2 30
1 2 3
建议:既然大佬是这么设计的,那我们也没办法。所以为了迎合这个特性,设计函数的时候如果有参数是必须要传递的,就放到前面;不是必须要传的,可以放到后面(制作成缺省参数)。
1.4缺省参数的应用场景
缺省参数的运用场景有很多,我们随便举个例子。
我们在学习数据结构时,实现顺序表、栈时定义容量 capacity 时,默认值我们当时推荐的是给 4,这里就可以设置缺省值:
演示(仅展示部分代码):
typedef struct Stack { int* array; int top; int capacity; } Stack; void StackInit (Stack* pst, int capacity = 4 ) // 设置缺省值为4(默认容量为4) { pst->array = (int*)malloc(sizeof(int) * capacity); pst->top = 0; pst->capacity = capacity; } int main() { Stack st; StackInit(&st); // 不知道栈最多存多少数据,就用缺省值初始化 StackInit(&st, 100); // 知道栈最多存100数据,显示传值。这样可以减少增容次数。 return 0; }
这么一来,就不需要考虑增容的概念了,这就是缺省参数的好处。
所以,这个特性确实是很有用的,可以让我们更方便。
2. 函数重载
自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,
即该词被重载了。
比如:以前有一个笑话,国有两个体育项目大家根本不用看,也不用担心。一个是乒乓球,一个
是男足。前者是 “ 谁也赢不了 ” ,后者也是 “谁也赢不了” "谁也赢不了" ,就相当于被重载了。
2.1函数重载的概念
函数重载常用来处理实现功能类似数据类型不同的问题。
函数重载:C++ 允许在同一个作用域中存在同名的函数。
下面三个不同只要满足一个不同,就可以触发函数重载:
① 参数类型不同
② 参数个数不同
③ 参数顺序不同
代码演示:
① 参数类型不同
#include <iostream> using namespace std; int Add(int x, int y) { cout << "int Add:" << endl; // 为了方便区分 return x + y; } double Add(double x, double y) { cout << "double Add:" << endl; // 为了方便区分 return x + y; } int main() { cout << Add(1, 2) << endl; cout << Add(1.1, 2.2) << endl; return 0; }
打印输出:
② 参数个数不同
#include <iostream> using namespace std; void Func(int a) { cout << "Func(int a)" << endl; } void Func(char b, int a) { cout << "Func(char b, int a)" << endl; } int main() { Func(10); Func('A', 20); return 0; }
③ 参数顺序不同
#include <iostream> using namespace std; void Func(int a, char b) { cout << "int a, char b" << endl; } void Func(char b, int a) { cout << "char b, int a" << endl; } int main(void) { Func(10, 'A'); Func('A', 10); return 0; }
2.2不支持函数重载的情况
除了上面讲的三种情况,其他情况都不能构成函数重载
常见错误:①返回值不同,调用时无法区分:
函数重载不能依靠返回值的不同来构成重载,
因为调用时无法根据参数列表确定调用哪个重载函数。
#include <iostream> using namespace std; int func(double d) { ; } void func(double d) { ; } int main() { foo(1.1); // ??? 会不知道这里到底是进 int func 还是 void func return 0; }
②缺省值不同,可构成重载但存在歧义,但使用时又是会出现问题
#include <iostream> using namespace std; void func() { cout << "func()" << endl; } void func(int a = 0) { cout << "func(int a)" << endl; } int main() { //func(); // 调用存在歧义 func(1); // 可以(调用下面的有参数的函数) return 0; }
从C语言到C++②(第一章_C++入门_中篇)缺省参数+函数重载+引用(中):https://developer.aliyun.com/article/1513636?spm=a2c6h.13148508.setting.22.5e0d4f0emCh6wU