1.缺省参数
一般情况下,函数调用时的实参个数应与形参相同,但为了方便地使用函数,C++允许定义具有缺省参数的函数,这种函数调用时,实参个数可以与形参不相同。
缺省参数指在定义函数时为形参指定缺省值(默认值)。
这样的函数在调用时,对于缺省参数,可以给出实参值,也可以不给出参数值:
如果给出实参,将实参传递给形参进行调用;
如果不给出实参,则按缺省值进行调用。
#include<iostream>
using namespace std;
void delay(int loops = 5)
{
//延时函数,默认延时5个时间单位
for (loops = 5; loops > 0; loops--);
}
int main()
{
delay(3);
cout << "延长3个时间单位" << endl;
delay();//等同于delay(5)
cout << "延长5个时间单位" << endl;
return 0;
}
输出结果为:
缺省参数的函数调用:缺省实参并不一定是常量表达式,可以是任意表达式,甚至可以通过函数调用给出。如果缺省实参时任意表达式,则函数每次被调用时该表达式被重新求值。但表达式必须有意义。
#include<iostream>
using namespace std;
int my_rand()
{
srand(time(NULL));
/*用于设置随机数生成器种子的常见操作。它使用当前时间作为种子,
以确保每次程序运行时生成的随机数序列都是不同的。
这样可以增加随机性,使得随机数更具预测性和不可重现性。*/
int ra = rand() % 100;//是随机生成0~99的数
return ra;
}
void fun(int a, int b = my_rand())
{
cout << "a=" << a << " b=" << b << endl;
}
int main()
{
fun(12);
return 0;
}
运行三次输出结果分别为:
缺省参数可以有多个,但所有缺省参数必须放到参数表的右侧,即先定义所有的非缺省参数,再定义缺省参数。这是因为在函数调用时,参数自左向右逐个匹配,当实参和形参个数不一致时只有这样才不会产生二义性。
#include<iostream>
using namespace std;
void fun(int a, int b = 23, int c = 8000)
{
cout << "a=" << a << " b=" << b << " c=" << c << endl;
}
int main()
{
fun(12);
fun(10, 20);
fun(10, 20, 30);
fun(10, , 30);//error 注意,它没有办法实现b不传,只传a和c,也就是说编译器只能按照顺序自左向右传递
return 0;
}
输出结果如下:
2.缺省参数的分类
(1)全缺省参数
全缺省参数就是所有的参数都带有缺省值。
int Add(itn a = 10, int b = 20, int c = 30) {}
全缺省参数通常这样进行参数传递:
#include<iostream>
using namespace std;
int Add(int a = 10, int b = 20, int c = 30)
{
return a + b + c;
}
int main()
{
cout << Add() << endl;//打印60,没有实参,使用缺省值
cout << Add(1) << endl;//打印51,将1传递赋值给a,b和c使用缺省值
cout << Add(1, 2) << endl;//打印33,将1传递赋值给a,将2传递赋值给b,c使用缺省值
cout << Add(1, 2, 3) << endl;//打印6,a,b,c分别传递赋值为1,2,3,不使用缺省值
//cout << Add(1, , 3) << endl;//error,编译器不会跳着传参
return 0;
}
输出结果如下:
(2)半缺省参数
函数只有部分参数有缺省值,且在函数定义时缺省值要从右向左依次给出。
int func(int a, int b = 20, int c = 30) {} // 只有参数b、c具有缺省值
半缺省参数通常这样进行参数传递:
#include<iostream>
using namespace std;
int Sum(int a , int b = 20, int c = 30)
{
return a + b + c;
}
int main()
{
//cout << Sum() << endl;//编译出错,因为a没有缺省值,在调用函数时必须传参
cout << Sum(1) << endl;//打印51
cout << Sum(1, 2) << endl;//打印33
cout << Sum(1, 2, 3) << endl;//打印6
return 0;
}
3.多文件结构
A.h
如下:
#pragma once
#ifndef A_H
#define A_H
void fun(int a, int b = 23, int c = 8000);
//也可以是以下形式
//void fun(int , int = 23, int = 8000);
#endif
A.cpp
如下:
#include<iostream>
using namespace std;
#include"A.h"
//void fun(int a, int b = 10, int c = 20);
//定义中 不可以再给出缺省值,不可以重定义默认参数
void fun(int a, int b , int c )
{
cout << "a=" << a << " b=" << b << " c=" << c << endl;
}
Maintest.cpp
如下:
#include<iostream>
using namespace std;
#include"A.h"
int main()
{
fun(12);
fun(10, 20);
fun(10, 20, 30);
return 0;
}
输出结果为:
习惯上,缺省参数在公共头文件包含的函数声明中指定,不要在函数的定义中指定。
如果在函数的定义中指定缺省参数值,在公共头文件包含的函数声明中不能再次指定缺省参数值。
4.总结
(1)所有带缺省的参数必须放在参数列表的右侧,即先定义所有的非缺省参数,再定义缺省参数
(2)缺省参数在公共头文件包含的函数声明中指定,不要在函数的定义中指出(如果在函数的定义中指定缺省参数值,在公共头文件包含的函数声明中不能再次指定缺省参数值)
(3)缺省实参不一定必须是常量表达式,可以使用任意表达式
(4)当缺省实参是一个表达式时,在函数被调用时该表达式被求值
(5)C语言不支持缺省参数