闲话少叙,咱们这章来说说缺省参数。
何为缺省参数?
先请诸位来看一段代码:
//缺省参数
#include <iostream>
using namespace std;
void Fun(int a = 10)//此处为函数的定义,这里形参a给了一个缺省值10
{
cout << a << endl;//此处想要实现打印a的值
}
int main()
{
Fun();//当不传参的时候结果是什么?
Fun(100);//传个实参过去,打印结果是多少呢?
return 0;
}
你可能有些奇怪,诶,这个在int a = 10这个赋值行为怎么出现在了函数的参数列表,竟然还没有报错。
咱们再来看运行截图:
接下来就听老夫给各位说道说道:缺省参数。
缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。在调⽤该函数时,如果没有指定实参 则采⽤该形参的缺省值,否则使⽤指定的实参。
void Fun(int a = 10)//此处为函数的定义,这里形参a指定了一个缺省值10
{
// 形参a此时就是缺省参数
//...
}
可以见得,缺省参数——一个形参,有缺省值——合起来,一个有缺省值的形参。
那我们调用这种有缺省参数的函数时:
Fun();//当不传参的时候,形参使用缺省值
Fun(100);//传个实参过去,形参使用实参值(传值调用嘛)
#include <iostream>
using namespace std;
void Fun(int a = 10)
{
cout << a << endl;//此处想要实现打印a的值
}
int main()
{
Fun();
Fun(100);
return 0;
}
根据Fun函数的定义,最后调用的结果,不传参的函数打印缺省值10,传实参值过去的函数打印实参值100;
缺省参数分为全缺省和半缺省参数
全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省参数必须从右往左 依次连续缺省,不能间隔跳跃给缺省值
//全缺省
void FunAll(int a = 10,char b = 'b', int c = 100)//这种全部形参都有缺省值,之谓全缺省
{
std::cout << a << " " << b << " "<< c << " " << std::endl;//此处想实现所有参数的打印
}
//半缺省
void FunPart(int a,char b = 'x',double c = 3.14)//不是所有参数都有缺省值(此处a没有),之谓半缺省
{
//...
}
你要写全缺省,那没毛病,函数定义时全部形参给上一个缺省值。但说要写半缺省,你就要考虑很多了:
这第一点,就得从右往左给,不得跳跃,就比如第二段代码,就不能写成这样:
//半缺省
void FunPart(int a = 10,char b = ‘x’,double c)//教科书错误示范1——从左往右给
{
//...
}
“默认实参不在形参列表的结尾”,编译器编着编着发现:好小子,让你从右边开始给参数。结果左边有,反而右边开头还没有,直接报错。
void FunPart(int a = 10, char b, double c = 3.14)//教科书错误示范2——跳跃间断给
{
//...
}
这回编译器检查半缺省,还是从右往左检查,发现左右都有缺省,中间竟然没有,二话不说又给报错。
所以,写好半缺省,不二法门是什么? 从右边开始写,一旦不写,后面都不写。
void FunPart(int a, char b, double c = 3.14)//从c开始写
{
//...
}
函数调用:从左往右
带缺省参数的函数调⽤,C++规定必须从左到右依次给实参,不能跳跃给实参。
其实,这两句合起来,反而更好理解:正是基于传实参给形参是从左至右,如果需要三个参数,你只给俩,最右边的,自然而然就可以使用它的缺省值。
自然,你一个实参也不传,三个形参就只好用自己的缺省值。
反过来:给缺省值,如果从左向右给,在函数调用时,你也只传俩。从左往右录入给形参(这是原则),此时,你让第三个形参如何是好?定义时没给它缺省值,调用又忽略它。
编译器随迟但到,函数调用处给你报个“参数太少”的错。
故此,为了避免这种情况,从右至左给缺省值似乎也说得通了,编译器也直接落实从右至左检查缺省值。——以上解释,纯属博主猜想,希望随着博主日渐学习和思考过程中,能更加贴近其中奥妙,不过,咱们刚学C++,多思考一点,总是没错的。
函数声明和定义分离
函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省值。
看咱们前面写的函数,声明和定义并未分离:
//缺省参数
#include <iostream>
using namespace std;
void Fun(int a = 10)
{
//...
}
int main()
{
//...
return 0;
}
而声明和定义分开是这样写的:
void Fun(int a = 20);//规定在声明里面给缺省值
int main()
{
FunAll();
return 0;
}
void Fun(int a)
{
//...
}
虽说是规定,但咱们也不是不可以尝试着理解。依在下看,此计可谓“先声夺人”。
在函数定义时,反而与普通函数无二。况且,看了前面,就发现,缺省值其实可用可不用:在不传实参的情况下有用,其实大部分情况你既然设置了参数,都会有意识传参。缺省值,似乎是给形参提供了下限。这样在声明里给上缺省值,而在定义里不写缺省值,保证函数定义和原来函数差不多,而缺省值又在声明里醒目,提醒你缺省值有了,你尽管在函数定义里写。
缺省值的作用:
在应对传实参不确定时,缺省值有奇效。