数组参数

有两个数组的特殊性质:

  • 不能拷贝数组
  • 使用数组,它常常会被转成指针

因为不能拷贝数组,所以不能按值传递数组(pass an array by value)。因为数组会被转成指针,给函数传递一个数组时,实际 传递的是指向数组第一个元素的指针。

下面的函数声明都是正确的:

void print(const int*);
void print(const int[]);
void print(const int[10]); // 维数其实没有实际作用;只有文档作用。

因此数组是作为指针传递的,函数是不知道其大小的。我们得提供其它信息告知调用函数数组的大小。 常见的有三种方法:

  • 使用一个标记作为数组的界

这种方法需要数组本身包含一个结束的标记。比如C风格的字符串就是这个方法的例子(因为其结尾是个空字符)。

void print(const char *cp)
{
    if (cp)
       while(*cp)
         cout << *cp++;
}
  • 使用标准库转换

第二种方法是通过同时传递指向第一个元素的指针,和指向最后一个元素下一个的指针。

void print(const int *beg, const int *end)
{
    while(beg != end)
       cout << *beg++;
}
  • 显示地传递大小
void print(const int ia[], size_t size){}

int j[] = {0, 1};
print(j, end(j) - begin(j));

数组Parameter与const

上面三个版本的print的parameter都是指向const的指针。

数组引用Parameter

void print(int (&arr)[10])
{
    for (auto elem: arr)
       cout << elem;
}

&外必须要有括号。

f(int &arr[10])的parameter是引用的数组。

因为数组的大小也其类型的一部分;调用这个版本的print时, 数组大小必须是恰好为10个。

int i = 0, j[2] = {0, 1};
int k[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
print(&i); // error
print(j); // error
print(k); // error