为什么不能数组作为函数的参数传递? [英] Why can't arrays be passed as function arguments?

查看:421
本文介绍了为什么不能数组作为函数的参数传递?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么你不能传递数组作为函数的参数?

我一直在阅读本C ++的书,说'你不能将数组作为函数参数,但它从来没有解释为什么。此外,当我看着它在网上我找到了这样的评语:你为什么要这么做呢?这并不是说我会做,我只是想知道为什么你不能。


解决方案

  

为什么不能数组作为函数的参数传递?


他们可以:

 无效美孚(const int的(安培; myArray的)[5]){
   //`myArray`是五个整数原始数组
}

在技术方面,争论的类型是参照5 的数组常量 INT 的;与引用,我们可以围绕通过的实际的对象的免责声明:术语由抽象级别而异)。

你所不能做的是通的通过值的,因为历史原因,我们不得的复制的阵列。相反,试图通过价值数组传递到一个函数(或传递一个的复制的数组),导致它的名字衰变成一个指针。的一些资源得到这个错了!


数组名衰减到指针传递按值

这意味着:

 无效美孚(INT * PTR);INT AR [10]; // 数组
富(AR); //自动传递ptr的Ar的第一元件(即,放​​大器;芳[0])

另外还有巨大的误导语法糖的看起来的一样可以按值传递任意长度的数组:

 无效美孚(INT PTR []);INT AR [10]; // 数组
富(AR);

但是,实际上,你还只是一个指针传递(以的第一个元素AR )。 是一样的,因为它是以上!

虽然我们在这,下面的函数的的并没有真正有签名,它似乎。看看会发生什么,当我们试图调用这个函数而不定义它:

 无效美孚(INT AR [5]);
诠释主(){
   INT AR [5];
   富(AR);
}//错误:未定义的引用`FUNC(INT *)'

所以需要为int * 事实上的 INT [5]

现场演示。


但是,你可以工作,围绕它!

您可以通过包装阵列中的结构破解>或,因为默认的拷贝操作符的将会的复制数组:

 结构Array_by_val
{
  INT my_array [10];
};无效FUNC(Array_by_val X){}诠释主(){
   Array_by_val X;
   FUNC(X);
}

这是有点混乱的行为。


或者,更好的,通用的传递通过引用的方式

在C ++中,有一些神奇的模板,我们可以使两者可重复使用的,并能够接收阵列功能:

 模板< typename的T,为size_t N'GT;
无效美孚(常量T(&安培; myArray的)[N]){
   //`myArray`是N Ts的原始数组
}

但是,我们仍然不能传递一个由价值。事情要记住。


未来......

此外,由于C ++ 11只是在地平线上,和C ++ 0x的支持一直很好主流工具链来了,你可以使用可爱的的std ::阵列与Boost继承!我会离开该研究作为练习读者。

Why can't you pass arrays as function arguments?

I have been reading this C++ book that says 'you can't pass arrays as function arguments', but it never explains why. Also, when I looked it up online I found comments like 'why would you do that anyway?' It's not that I would do it, I just want to know why you can't.

解决方案

Why can't arrays be passed as function arguments?

They can:

void foo(const int (&myArray)[5]) {
   // `myArray` is the original array of five integers
}

In technical terms, the type of the argument to foo is "reference to array of 5 const ints"; with references, we can pass the actual object around (disclaimer: terminology varies by abstraction level).

What you can't do is pass by value, because for historical reasons we shall not copy arrays. Instead, attempting to pass an array by value into a function (or, to pass a copy of an array) leads its name to decay into a pointer. (some resources get this wrong!)


Array names decay to pointers for pass-by-value

This means:

void foo(int* ptr);

int ar[10]; // an array
foo(ar);    // automatically passing ptr to first element of ar (i.e. &ar[0])

There's also the hugely misleading "syntactic sugar" that looks like you can pass an array of arbitrary length by value:

void foo(int ptr[]);

int ar[10]; // an array
foo(ar);

But, actually, you're still just passing a pointer (to the first element of ar). foo is the same as it was above!

Whilst we're at it, the following function also doesn't really have the signature that it seems to. Look what happens when we try to call this function without defining it:

void foo(int ar[5]);
int main() {
   int ar[5];
   foo(ar);
}

// error: undefined reference to `func(int*)'

So foo takes int* in fact, not int[5]!

(Live demo.)


But you can work-around it!

You can hack around this by wrapping the array in a struct or class, because the default copy operator will copy the array:

struct Array_by_val
{
  int my_array[10];
};

void func (Array_by_val x) {}

int main() {
   Array_by_val x;
   func(x);
}

This is somewhat confusing behaviour.


Or, better, a generic pass-by-reference approach

In C++, with some template magic, we can make a function both re-usable and able to receive an array:

template <typename T, size_t N>
void foo(const T (&myArray)[N]) {
   // `myArray` is the original array of N Ts
}

But we still can't pass one by value. Something to remember.


The future...

And since C++11 is just over the horizon, and C++0x support is coming along nicely in the mainstream toolchains, you can use the lovely std::array inherited from Boost! I'll leave researching that as an exercise to the reader.

这篇关于为什么不能数组作为函数的参数传递?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆