很多人c和c++的初学者都知道这样一个事实:数组不能直接作为函数的形参,当传入一个数组名时,数组会退化为对应的指针类型。
例如考虑如下函数:
void chuanrushuzu(int a[10])
{
return;//没有实质内容,只是为了说明数组的传入
}
这里函数的形参虽然指定了数组的大小,但实质上编译器是不认的,在编译器眼中,被传入的只是一个int*类型的指针,也就是说,在此例的函数中,int a[10]等价于int* a,你传入的数组名无论其实际大小是多少,只要类型正确,都能通过编译。
那是不是就没有办法限定传入数组的大小了呢,方法是有的!
那就是利用指针(c/c++)或引用。
下面举一个利用引用的例子:
#include<iostream>
using namespace std;
void dingchangshuzu(int (&p)[10])
{
cout<<"传入了定长数组"<<endl;
}
int main()
{
int p1[5]={};
int p2[10]={};
int p3[15]={};
int* p4=new int[15]();
dingchangshuzu(p1);//error C2664: “dingchangshuzu”: 不能将参数 1 从“int [5]”转换为“int (&)[10]”
dingchangshuzu(p2);//通过
dingchangshuzu(p3);//error C2664:不能将参数 1 从“int [15]”转换为“int (&)[10]”
dingchangshuzu(p4);//error C2664:不能将参数 1 从“int *”转换为“int (&)[10]”
return 0;
}
这里,int (&p)[10]定义了一个含有10个元素的数组的引用,引用在形参表中不会退化,因此当传入大小不一致的数组时,编译不能通过。
利用指针的例子也类似
只要把int (&p)[10]替换成int (*p)[10],传入数组名的时候对数组名取地址(形如&p1)即可,留给感兴趣的读者自己尝试,由于c语言不支持引用,所以这种方式可以用作c环境下的编程。
总结一下,C/C++之所以不支持定长数组的直接传入,是因为数组名在传入形参时会进行一次退化,那既然这样,我们的应对方式就是绕过这次退化,传入数组名的引用或指向数组名的指针。