一.缺省参数
1.1 缺省参数的定义
缺省参数是在函数声明或定义时,为形参设置一个默认值,其作用就是在用户调用函数时,没有写实参或者只写了一部分实参的情况下,仍然给形参一个值。
#include<iostream>
using namespace std;
int fun(int a = 10)
{
return a;
}
int main()
{
cout << fun() << endl; //在这里调用函数时因为没有填写实参所以这里的输出值默认为缺省参数0
cout << fun(10) << endl; //因为这里在调用的时填写了实参 所以这里的输出值为10
return 0;
}
在这个地方缺省参数就像是一个小舔狗一样,在形参接收到实参的值的时候,那么形参就和实参在一起,但是如果实参没有传递值的话,缺省参数就退而求其次和缺省参数在一起。但是在使用上有两点需要注意!
1.2 缺省参数的分类
(1)全缺省参数: 在实参传递时我可以不传参数,可以传递一个参数,可以传递两个也可以传递三个值。但是在传递实参时必须从左到右连续传递,不能跳着传递参数。(不要问我为什么,祖师爷是这么规定的,不遵守就没饭吃)
#include<iostream>
void Func(int a = 1, int b = 2 , int c = 3)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
}
int main()
{
Func();
Func(1);
Func(1,2);
Func(1,2,3);
Func(1,,3);// 错误!!!不能这么写
}
(2)半缺省参数:缺少了几个参数没有设置缺省参数,在实参中就最少传递几个值。而且也不能跳着传递参数。
#include<iostream>
using namespace std;
void Func(int a , int b , int c = 3)
{
cout << "c = " << c << endl;
}
int main()
{
Func(1,2);//正确
Func(1,2,4);//正确
Func(1,,4);//错误
Func(1);//错误
}
1.3 缺省参数的使用中的注意事项
(1)半缺省参数必须从右往左依次给缺省参数,不能隔着给(小舔狗必须排着队)
#include<iostream>
using namespace std;
int fun(int a = 1, int b = 2 , int c = 3) //正确写法(全缺省参数)
{
return a;
}
int fun1(int a ,int b = 2, int c = 3)//正确(半缺省参数)
{
return b;
}
int fun2(int a = 1, int b, int c = 3) //错误写法
{
return;
}
int main()
{
cout << fun() <<endl; // 输出1
cout << fun1() << endl; //输出2
cout << fun2() << endl; //错误
}
(2)缺省参数不能再函数声明和函数定义中同时出现!!! 而且最好写在函数声明中!!
#include<iostream>
using namespace std;
int fun(int a = 1, int b = 2);
int main()
{
fun(1);
}
int fun(int a ,int b )//这么写是错误的因为声明和定义中缺省参数只能出现一次
{
cout << a << endl;
cout << b << endl;
}
二 .函数的重载
2.1 函数重载的定义
函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似但是数据类型不同的问题
换句话说,C++作为对C语言的一种补充,在C语言的编写中有时会出现函数名称相同的情况,在此时C语言会报错,但是在C++中允许这样重名的函数出现。其目的是为了更好的使用函数。
2.2 函数重载的规则
函数重载必须遵循一下规则:
(1)参数类型定义不同
(2)参数个数不同
(3)参数类型顺序不同
#include<iostream>
using namespace std;
// 1.参数类型不同
int add (int left , int right)
{
cout << "int add(int left ,int right)"<<endl;
return left + right;
}
double add (double left , int right)
{
cout << "double add(double left ,double right)"<<endl;
return left + right;
}
//2.参数个数不同
void fun()
{
cout << "fun";
}
void fun(int a)
{
cout << a;
}
//3.参数类型顺序不同
void fun1(int a, char b)
{
cout << a;
cout << b;
}
void fun1(char a,int b)
{
cout << a;
cout << b;
}
int main()
{
add(1,1); add(2.2,1);
fun(); fun(1);
fun1(1,'a'); fun1('a',1);
}
2.3 函数重载的原理
我们在C语言中调用一个函数时,编译器会向操作系统发一个类似 “call + 函数名地址”这样格式的一条指令,如果多个函数名相同时,C语言编译器在这里就会发生错乱,所以会报错。
我们C++的祖师爷本贾尼博士就想了一个办法,在调用函数时添加了一个函数名修饰规则,把函数名修饰成了一个更细致的名字,这个更细致的名字中不仅包括了用户自己定义的函数名,其中还包含了形参的类型,用户定义函数名的长度等信息。
举个例子,我在main中调用fun这个函数,在Linux操作系统下,C++在调用第一个fun函数时就会把他名字封装成类似 " _Zfun3ii "的形式,调用第二个fun函数时就会把他名字封装成 " _Zfun3dd " 的形式。 其中Linux操作系统的函数名修饰规则的格式要求为
“_Z + 用户定义的函数名 + 函数名的长度 + 函数形参的类型名首字母”
void fun(int a, int b)
{
cout << "fun";
}
void fun(double a,double b)
{
cout << a;
}
int main()
{
fun(1,2); // _Zfun3ii
fun(1.1,2.2); // _Zfun3dd
}
在这里虽然有的函数他们的名字相同,但是在操作系统函数名修饰的操作后名字其实对于编译器来说是完全不同的,所以这就是为什么C++支持函数重载的原因喽。
2.4 返回值不同不构成函数重载
因为调用函数时我们是不用写返回值的,这样的话编译器就无法确定调用的到底是哪一个函数。为了避免二义性和不必要的麻烦在C++中 返回值不同不构成函数重载