一、传值参数
1.指针形参和其他非引用类型一样,执行指针拷贝时,拷贝的是指针的值,拷贝之后,两个指针是不同的指针。由于指针可以使我们间接访问它所指向的对象,所以可以通过指针修改值
void fx(int* a)
{
if (*a == 0)
*a = 1;
}
二、传引用参数
1.通过使用引用形参,允许函数改变一个或多个实参的值,形式如下
void fx(int& a)
{
if (a == 0)
a = 1;
}//作用同上
2.拷贝大的类类型对象或容器对象比较低效甚至不支持拷贝操作,只能通过引用形参访问该类型的对象,但由于无需改变对象,故可以把形参定义成对常量的引用
bool lencmp(const string s1, const string s2)
{
return s1.size() > s2.size();
}
3.函数只有一个返回值,所以如果想要拥有更多信息,可以使用引用形参
三、const形参和实参
1.传参时只是拷贝,不考虑顶层const
int fx(int a)
{
a += 5;
return a ;
}
void solve()
{
const int a = 1;
printf("%d", fx(a)); //输出6
}
2.形参的初始化方式和变量的初始化方式是一样的,规则一样
3.比较重要的一点是:不能把const对象、字面值或者需要类型转换的对象传递给普通的引用形参,而要使用常量引用
四、数组形参
1.由于数组不能拷贝,无法使用值传递的方式,因为数组会被转成指针,所以我们为函数传递一个数组时实际上是传递数组首元素指针,以下三种形式等价
void printa(const int*)
void printa(const int[])
void printa(const int[10]) //表示期望数组有多少元素,实际不一定
2.由于不知道传参时不知道数组的大小,为了避免越界,可以使用以下方法:使用标记指定数组元素(数组末尾设为0);显示传递一个表是数组大小的形参;使用标准库规范(传递指向数组首元素和尾后元素的指针,如下)
void printa(const int* begin, const int* end){}
printa(begin(a), end(a));
3.c++允许将变量定义成数组的引用,同理形参也可以是数组的引用,但是只能作用于大小为10的数组
void printa(int (&arr)[10]){} //10不可省
4.传递多维数组,以下两种做法等价
void printa(int (*arr)[10]) //指向含有十个整数的数组的指针
void printa(int arr[][10])
五、main:处理命令行选项
1.有时需要给main传递实参
int main(int argc,char *argv[])
六、含有可变形参的函数
1.如果无法提前预知向函数传递几个形参,解决方法有两个:如果实参的类型相同,可以传递一个名为initializer_list的标准库类型;如果类型不同,则需要编写可变参数模板
2.c++还有一种特殊的形参类型,即省略符形参,可以用它传递可变数量的实参,这种功能一般只用于与c函数交互的接口程序