数组引用的思考

@当给一个函数传递数组相关的参数时,除了可以传递数组的起始地址,还可以传递整个数组的引用。

 

如:

 

void function(int (&arr)[10]);

此时,将函数的形参声明为一个数组的引用,这个数组的大小是10个int元素。

对于该函数的使用方法为:

 

int main(){

    int i = 0, j[2] = {1,2};

    int k[10] = {0--9};//伪代码

    function(&i);//error

    function(j);//error

    function(k);//ok

}

可见,只有当传递的实参为一个大小为10的整形数组的名称时才能得到正确的编译结果。

 

@编译器内部的行为:

1. 编译器在这里不再接受一个对象实参,而是接受数组名,即数组的地址,其实,引用只不过是一个取对象地址,形成const 指针,对该const 指针解引用的过程

   ,此时,由于避开了取对象地址这一步(因为直接获取到了数组的地址),编译器需要做的就是将该指针在函数内部const 化,然后检测该指针的类型和数组的

   大小与声明的是否匹配。

2.在函数内部使用形参时,对数组引用而言,实际上传递的是一个指针的引用,例如function(int (&arr)[10]),函数中传递的实际是数组名的引用,即指向数组首元素

  的地址的指针,因此,在函数内部,必须像使用指针一样使用arr,如:

  void function(int (&arr)[10]){

    for(int i =0; i <10; i++)

         arr[i] = i+1;

}从这里可以看出,编译器所需要做的其实很简单,检测arr指向的类型是不是一个int类型,数组的大小是不是10.因此可以说,这种形式与传递指针引用并无区别,唯一区

  别开来的是,对指针引用的检查更加的严格了。

 

@当使用模板时,能够使用可变的指针类型和数组大小,如下:

template<typename T, size_t N> void function(T (&arr)[N]){

    for(int i = 0; i < N; i++)

      arr[i] = 0;

}

 

int main(){

    int x[42];

   double y[10];

   function(x);//①

   function(y);//②

}

①处编译器将函数模板实例化为function(int (&arr)[42])

②处编译器将函数模板实例化为function(double (&arr)[10])

 

@以下两种运用模板参数为引用的函数模板具有相同的效果:

template<typename T, int N1, int N2>
void fref(const T (&arr1)[N1], const T (&arr2)[N2]){
     cout<<"A template with a reference of a array."<<endl;
}

template<typename T>
void fref_nonarray(const T &, const T &){
     cout<<"A template with a reference."<<endl;
}

 

int main(int argc, char **argv){

 

     int a[10] = {0};
     int b[10] = {0};
     int c[20] = {0};
     fref(a,c);//①
     fref_nonarray(a,b);//②


     return 0;
}

在①处,可以将不同长度的数组作为模板实参传给模板,让编译器生成具体的函数实例。

在②处,需要将相同类型相同长度的数组传递给模板,此时编译器推断的参数为const T& ---->const int(&)[10],因此生成的具体的函数实例为:

void fref_nonarray(const int(&)[10], const int(&)[10]);

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值