【正确答案】
【答案解析】C++可以给函数定义默认参数值。在函数调用时没有指定与形参相对应的实参时,就自动使用默认参数。
默认参数的语法与使用:
1)在函数声明或定义时,直接对参数赋值,这就是默认参数。
2)在函数调用时,省略部分或全部参数。这时可以用默认参数来代替。
通常调用函数时,要为函数的每个参数给定对应的实参。例如:
void delay(int loops);∥函数声明
void delay(int loops)∥函数定义
{
if(loops==0){
return;
}
for(int i=0;i<loops;i++)
}
上例中,无论何时调用delay()函数,都必须给函数传递一个值以确定时间,否则无法正确调用函数。此种方法虽然没有什么,问题,但当需要用相同的实参反复调用delay()函数时,反复地传递参数,一方面会不方便,另一方面会造成代码冗余。是否有一种方法可以解决这两种问题了?答案是肯定的,在C++中,可以给函数参数定义默认值,若不给出参数,则按指定的默认值进行工作。例如,在上例中,如果将delay()函数中的loops定义成默认值1000,只需简单地把函数声明改为void delay(int loops=1000)。
这样,以后无论何时调用delay()函数,都不用给loops赋值,程序都会自动将它当做值1000进行处理。例如,当执行delay(2500)调用时,loops的参数值为显性化的,被设置为2500;当执行delay()时,loops将采用默认值1000。允许函数默认参数值,是为了让编程简单,让编译器做更多的检查错误工作。
默认参数在函数声明中提供,当有声明又有定义时,定义中不允许默认参数。如果函数只有定义,则默认参数才可出现在函数定义中。例如:
void point(int=3,int=4);∥声明中给出默认值
void point(int x,int y)∥定义中不允许再给出默认值
{
cout<<x<<endl;
cout<<y<<endl;
}
在使用默认参数时,一般需要注意以下几个问题:
1)如果一个函数中有多个默认参数,则形参分布中,默认参数应从右至左逐渐定义。例如:
①void fun(int a=1,int b,int c=3,int d=4);
②void fun(int a,int b=2,int c=3,int d=4);
上例中,第1种声明方法就是错误的,而第2种声明方法就是正确的。
2)在默认参数调用时,调用顺序为从左到右逐个调用。例如,首先声明一个带默认参数的函数void mal(int a,int b=3,int c=5),函数调用mal(3,8,9)在调用时有指定参数,则不使用默认参数,是合法调用;函数调用mal(3,5)在调用时只指定两个参数,按从左到右的顺序调用,相当于mal(3,5,5),是合法调用:函数mal(3)在调用时只指定1个参数,按从左到右的顺序调用,相当于mal(3,3,5),是合法调用;而函数调用mal()因为a没有默认值,所以调用错误;函数调用mal(3,,9)应按从左到右的顺序逐个调用,所以也错误。
3)默认值可以是全局变量、全局常量,甚至是一个函数。例如:
int a=1;
int fun(int);
int g(int x,fun(a));∥正确:允许默认值为函数
默认值不可以是局部变量,因此默认参数的函数调用是在编译时确定的,而局部变量的位置与值在编译时均无法确定。例如:
void fun()
{
int i;
void g(intx=i);∥错误:处理g()函数声明时,i不可见
}
4)默认参数可将一系列简单的重载函数合成为一个。例如下面的3个重载函数:
void point(int,int){∥...}
void point(int a){return point(a,4);)
void point(){return point(3,4);)
可以用下面的默认参数的函数来替代:
void point(int=3,int=4);
上例中,当调用“point();”时,即调用“point(3,4);”它是第3个声明的重载函数。当调用“point(6);”时,即调用“point(6,4);”它是第2个声明的重载函数。当调用“point(7,8);”时,即调用第1个声明的重载函数。
如果一组重载函数(可能带有默认参数)都允许相同实参个数的调用,将会引起调用的二义性。例如:
void func(int);∥重载函数之一
void func(int,int=4);∥重载函数之二,带有默认参数
void func(int=3,int=4);∥重载函数三,带有默认参数
func(7);∥错误:到底调用3个重载函数中的哪个?
func(20,30);∥错误:到底调用后面两个重载函数的哪个?