在C++中我们在定义或声明一个函数的时候,有时会在形参中给它赋一个初始值作为不传参数时候的缺省值,例如:
int FUN(int a = 10);
代表没有传参调用的时候,自动给a赋一个10的初始值。然而这种操作在c89下是行不通的,在c语言下这么写就会报错。
我们都知道,系统在调用任何一个函数的时候都有函数栈帧的开辟,如果函数有参数则需要压入实参。平常在我们人为给定实参的时候,是按照参数列表从右向左依次将参数通过
mov eax/ecx dword ptr[ebp-4] //假设是int数据
指令传入寄存器,再通过push指令压入。现在我们已经给定了函数参数的默认值,那么在压实参的时候只需要一步push初始值即可。效率更高。
另外需要注意的是,赋初始值必须从参数列表的右边开始赋值,从左边开始赋值将会出错:
int sum1(int a = 10,int b); //错误
int sum2(int a,int b = 20); //正确
因为如果sum1的声明是正确的,那么我们调用的时候怎么调用?sum1( ,20)?很可惜这样属于语法错误,调用这么写既然不对那就当然不能这样赋初始值了。相反,sum2的调用:sum2(20);合情合理,没有任何问题。
实际在写工程的时候,我们都习惯将函数的声明写在头文件中而非本文件里,然后在不同的文件中写出它们的定义。那么这种情况可以赋初始值吗?当然可以,不论是定义还是声明处,只要你遵守从右向左赋的规则就可以。甚至你还可以这样给初始值:
int fun(int a ,int b = 10);
int fun(int a = 20,int b);
眼尖的同学看见了下面的那行代码大喊错误,因为先给左边赋值了!
其实这样声明完全没有问题,两句声明是同一个函数(函数多次声明没有问题),第一句已经给b了一个初始值,运行到第二句时已经等价于int fun(int a = 20,int b = 10);了。但是注意,这两句的顺序不能反转,否则就是错误的。