数组作为函数形参
参数为数组的函数体的错误实现
#include <iostream>
using namespace std;
void ShowInf(int arr[2], int n)
{
for (int var : arr)
{
cout << var << endl;
}
}
int main()
{
int arr[] = { 1,2,3,4 };
ShowInf(arr, 2);
}
数组作为形参的实质(指针传递)
当函数的参数为任何形式的数组的时候,本质上都是传入了一个指针,只不过这个指针维度不同。
一维指针 |
Fun(int arr[2]) |
Fun(arr[]) |
|
Fun(*arr) |
注:针对于一维数组,这里arr[2]不会限制arr后面跟的元素的个数,在arr[]中指定数组的个数是没用的也是没意义的。
#include <iostream>
using namespace std;
void ShowInf(int arr[2], int n)
{
for (int i = 0; i < n; i++)
{
cout << *(arr + i) << endl;
}
}
int main()
{
int arr[] = { 1,2,3,4 };
ShowInf(arr, 3); // arr[2]不会限制arr后面跟的元素个数
}
二维指针 |
Fun(arr[][2]) |
Fun(**arr) |
对于多维数组,那就有些区别:
如果这个形参不是引用形参,同样实际传递的是一个指针,因此,和一维数组的形参一样,说明数组形参的最低维(即最外层)的大小是不需要也是没有任何意义的,但是必须指明其他每一维的大小。
#include <iostream>
using namespace std;
void ShowInf(int arr[][2]) // 限定传入数组的第二维度的元素必须是两个,但是并未对于第一维度做出限定
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
cout << *(*(arr + i) + j) << endl;
}
}
}
int main()
{
int arr[][2] = { {1,2},{3,4} };
ShowInf(arr);
}
注:虽然形参是“int arr[][2]”这种形式,可以限定二三维度的数组大小,但是这并不可以完全限定输入数组的格式。而且引用数组形参相较于非引用数组形参的优势前面针对于一维数组已经说明。
数组作为形参的实质(数组的引用)
相较于“简单的传递数组首地址”,用数组的引用作为形参可以限定数组的元素个数,而且比用传递地址更安全,仅仅传递一个地址我们不知道地址对应的存储空间之内存储着什么,当指针是NULL(数组不存在)时,地址作为形参就显得不安全,即使我们可以在数组内对其进行检查和限定,但是这样太慢太麻烦了。
当我们用“数组的引用“作为形参时,由于变量的引用是没有存储空间的,因此当我们传入参数时这个参数一定存在,而且传参效率大大提高,可以在函数内对参数实验for range进行访问。除此之外,不用在传入我们需要访问数组元素的个数了。
#include <iostream>
using namespace std;
void ShowInf(int (&arr)[2]) // 限定传入数组元素必须是两个
{
for (int var:arr) // for range进行遍历
{
cout << var << endl;
}
}
int main()
{
int arr[] = { 1,2 };
ShowInf(arr);
}
可变参数的函数形参
#include <iostream>
using namespace std;
int average(initializer_list<int> score)
{
int average = 0, n = 0;
for (int var: score) // 用for range的方式进行遍历
{
average += var;
n++;
}
return (average / n);
}
int main()
{
cout << average({ 2, 3, 4 }) << endl; // 注意数据输入格式{Data1,Data2…}
}
这里,我们 使用的initializer_list<DataType>是个可变模板参数,而且一定要注意的是:我们输入的变量默认都是const类型的,都是不可以被修改的。其实我们编程要养成一个好习惯:“我们向函数传入的参数都仅仅在函数体内使用而不是修改它”。