C++Primer 函数
目录
1、参数传递
写在前面,函数中很基础的概念参数传递,如果形参是引用类型,它将绑定到对应的实参上;否则,将实参的值拷贝后赋给形参。
需要注意的是const:下面的这个函数虽然合法,但不算特别有用。
bool is_empty(string &s)
{
return s.empty();
}
局限主要在于两个方面:
1.容易给使用者一种误导,即程序允许修改变量s的内容;
2.限制了该函数所能接受的实参类型,我们无法把const对象、字面值常量或者需要进行类型转换的对象传递给普通的引用形参。
综上,应该修改为:
bool is_empty(const string &s)
{
return s.empty();
}
1.1、含有可变形参的函数
如果函数的实参数量未知但是全部实参的类型都相同,可以使用initializer_list类型的形参。initializer_list是一种标准库类型,用于表示特定类型的值的数组,initializer_list定义在同名头文件中。
下面用代码举例说明:
函数的参数是initializer_list<int>类型的对象,函数功能是计算列表中所有元素的和。这里跟容器差不多,如果参数改为vector也是可以的。
int iCount(initializer_list<int> il)
{
int count = 0;
for(auto val:il)
count+= val;
return count;
}
int main()
{
cout<< "1+4+5 = " << iCount({1,4,5}) <<endl;
return 0;
}
1.2、数组形参
数组的两个特殊性质对我们定义和使用作用在数组上的函数有影响,这两个性质分别是:
- 不允许拷贝数组
- 使用数组时(通常)会将其转换成指针
因为不能拷贝数组,所以我们无法用值传递的方式使用数组参数。因为数组会被转换成指针,所以当我们为函数传递一个数组时,实际上传递的是指向数组首元素的指针。
void print(const int *)
void print(const int[])
void print(const int[10])
上述三行代码,尽管形式不同,但这三个print函数是等价的,即使有维度,表示的是我们期望数组含有多少元素,实际不一定。每个函数的唯一形参都是const int *类型的。
C++允许将变量定义成数组的引用,基于同样的道理,形参也可以是数组的引用。此时,引用形参绑定到对应的实参上,也就是绑定到数组上。数组引用形参:
void print(int (&arr)[10]) //维度是类型的一部分
{
for(auto elem: arr)
cout<<elem<<" ";
arr[0] = 90;
cout<<endl;
}
int main()
{
int k[10] = {0,1,2,3,4,5,6,7,8,9};
print(k);
cout<<k[0]<<endl;
return 0;
}
注:&arr两端的括号不可少
f(int &arr[10]) //错误:将arr声明成了引用的数组 f(int (&arr)[10]) //正确:arr是具有10个整数的整型数组的引用