1. 数组有两个特殊的性质:
-
不允许数组的拷贝和赋值:不能将数组的内容拷贝给其他数组作为其初始值,也不能用数组为其他数组赋值。(一些编译器支持数组的赋值,这就是所谓的编译器扩展,最好避免使用非标准特性) int a[] = {0 ,1 ,2};
int a2[] = a;
a2 = a;
-
使用数组时,通常会将其转化成指针。
通过以上两个性质可以看出,数组无法拷贝,因此数组无法以值传递的方式使用数组参数。因为数组会被转换成指针,所以当我们为函数传递一个数组时,实际上传递的是指向数组首元素的指针。
2.函数数组形参的传递
尽管不能以值传递的方式传递数组,但是可以写成形参类似数组的形式:
void print(const int*);
void print(const int[]);
void print(const int[10]);
尽管表现形式不同,但上面三个参数是等价的:每个函数唯一的类型的形参都是 const int* 类型的。函数在运行时,只检查传入的参数是否为const int*
注意:和其他使用数组的代码一样,以数组作为形参的函数也必须保证使用数组时不会越界。
因为数组,是以指针的形式传递给函数的,所以数组一开始并不知道数组的确切尺寸。通常有三种方法对数组进行管理。
void print(const char *cp)
{
if(cp) // 若cp不是一个空的指针
while(*cp) // 指针所指的字符不是空字符
cout << *cp++; // 输出当前字符并将指针向前移动一个位置
}
该种方法只适用于那些有明显结束标记不会与普通数据混淆的情况,但是对于像int这种所用取值都合法的数据就不太好处理了。
void print(const int *beg, const int *end)
{
while(beg != end)
cout << *beg++ << endl;
}
void print (const int ia[], size_t size)
{
for(size_t i = 0; i != size; ++i)
{
cout << ia[i] << endl;
}
}
3.函数数组的引用传值
C++语言允许将变量定义成数组引用,基于同样的道理,形参也可以是数组的引用。此时,引用形参绑定到对应的实参上,也就是绑定到数组上。
void print(int (&arr)[10])
{
for(auto elem : arr)
{
cout << elem << endl;
}
}
上述写法,数组的大小构成数组的一部分,只要不超过维度,就可以在函数体内,放心使用数组。但是,这一用法无形中,限制了print函数的可用性,我们只能将函数作用于大小为10的数组。
int i = 0, j[2] = {0, 1};
int k[10] = {0,1,2,3,4,5,6,7,8,9};
print(&i);
print(j);
print(k);
参考:《C++ primer》
|