通过引用传递数组

265

如何通过引用来传递静态分配的数组?

void foo(int (&myArray)[100])
{
}

int main()
{
    int a[100];
    foo(a);
}
< p > (&myArray)[100] 是否有意义或者只是传递任何数组的引用的语法? 我不理解这里分开的括号,然后跟着大括号。谢谢。


函数参数是否存在Rvalue到Lvalue的关系? - John DB
可能是什么是引用数组参数的有用之处?的重复问题。 - AnT stands with Russia
5个回答

310

这是用于数组引用的语法 - 您需要使用 (&array) 来向编译器说明您想要一个数组的引用,而不是无效的引用数组 int & array[100];

编辑:有些澄清。

void foo(int * x);
void foo(int x[100]);
void foo(int x[]);

这三种声明方式表示的是同一个函数。它们都被视为接受一个 int * 参数,所以你可以将任何大小的数组传递给它们。

void foo(int (&x)[100]);

这仅接受包含100个整数的数组。您可以安全地在x上使用sizeof

void foo(int & x[100]); // error

这被解析为“引用数组”,这是不合法的。


为什么我们不能有一个引用的数组,例如 int a,b,c; int arr[3]={a,b,c}; - Vorac
10
啊哈,找到了为什么 - Vorac
2
有人可以解释一下为什么void foo(int & x[100]);被解析为“引用数组”吗?这是因为“由右至左”的规则吗?如果是的话,似乎与void foo(int (&x)[100]);被解析为“指向数组的引用”不一致。先谢谢了。 - zl9394
7
不正确的是从左到右,而是从内到外,[]比&绑得更紧。 - philipxy
1
这只接受100个整数的数组。你可以安全地在x上使用sizeof,这是一个很好的澄清要提到的。 - Erik

71

这只是必需的语法:

void Func(int (&myArray)[100])

传递一个名为myArray的参数作为引用,其中包含100个int的数组;

void Func(int* myArray)

传递一个数组。数组会退化为指针。因此您失去了大小信息。

void Func(int (*myFunc)(double))

传递一个函数指针,该函数返回一个 int 类型的值,并接受一个 double 参数。该参数名为 myFunc


1
我们如何将变量大小的数组作为引用传递? - Shivam Arora
@ShivamArora 你可以将函数模板化,并将大小作为模板参数。 - Martin York

32

这是一种语法结构。在函数参数int(&myArray)[100]中,括号包含&myArray是必要的。如果不使用它们,则会传递一个引用数组,这是因为下标运算符[]&运算符的优先级更高。

例如:int &myArray[100] // 引用数组

因此,通过使用类型构造()告诉编译器您想要一个引用到100个整数的数组。

例如:int (&myArray)[100] // 100个int数组的引用


1
如果你不使用它们,你将会传递一个“引用数组”,这当然是不存在的,所以你会得到一个编译错误。有趣的是,操作符优先级规则坚持默认情况下必须发生这种情况。 - underscore_d
有没有关于类型构造的更多教程? - iartist93
1
谢谢,我需要一个包括操作符优先级原因的解释,这样做的原因就有了意义。 - cram2208
@BugShotGG,非常感谢您提供了一个“哦,这就是导致问题的原因”的瞬间,因为您提到了运算符优先级。我想这是不可避免的,因为[]需要从左到右的结合性,而&需要从右到左,所以它们不能在同一级别。我想++/--需要在&上方,这样指针递增才能按预期工作。再次感谢。 - Erik

19
以下代码创建了一个通用函数,通过引用接受任何大小和类型的数组:
template<typename T, std::size_t S>
void my_func(T (&arr)[S]) {
   // do stuff
}

点此查看代码。


2
这篇文章详细介绍了如何使用该模式来制作安全的strcpy函数。链接:https://randomascii.wordpress.com/2013/04/03/stop-using-strncpy-already/。 - idbrii

6

数组默认通过指针传递。您可以尝试在函数调用中修改数组以便更好地理解。


3
数组不能通过值传递。如果函数接收指针,则数组会降解为指向其第一个元素的指针。我不确定您想表达什么意思。 - Ulrich Eckhardt
8
数组既不是按值传递,也不是按引用传递,它们是通过指针传递的。如果数组默认按引用传递,那么在其上使用sizeof将没有问题。但事实并非如此。当数组传入函数时,它们会衰变为指针。 - user3437460
3
数组可以通过引用传递或退化为指针来传递。例如,使用char arr[1]; foo(char arr[])时,arr会退化为指针;而使用char arr[1]; foo(char (&arr)[1])时,arr作为引用被传递。值得注意的是,前一种形式通常被认为是不良形式,因为维度丢失了。 - zl9394
1
“数组是通过指针传递的”这个描述听起来最好是不寻常的,对新手来说可能会很困惑。数组变量的名称是一个有效表达式,其值是数组的第一个成员的指针。如果您有一些函数foo(T* t),并且您有一个数组T a[N];,那么当您写foo(a);时,我认为更正确的说法是您正在传递一个指针,而不是传递一个数组,并且您正在通过值传递指针。 - Solomon Slow
1
@user3437460 回复旧评论,因为它有很多赞同:在C++中,数组可以通过引用传递。 - hyde
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接