如果数组是通过引用传递的,为什么我应该使用 int(&)[]?[复制]

If arrays are passed by reference, why should I use int(&)[]? [duplicate]

提问人:Francesco Derme 提问时间:9/6/2023 最后编辑:Peter MortensenFrancesco Derme 更新时间:9/18/2023 访问量:2058

问:

考虑:

#include <iostream>
using namespace std;

void Change(int arr[3]) {
    for (int i = 0; i < 3; i++) {
        arr[i] = 1;
    }
}

int Test() {
    int arr[3] = { 0, 0, 0 };

    for (int i = 0; i < 3; i++) {
        cout << arr[i] << endl;
    }

    Change(arr);

    for (int i = 0; i < 3; i++) {
        cout << arr[i] << endl;
    }

    return 0;
}

由于数组默认作为指向其第一个元素的指针传递,而不是被复制,因此在函数中更改数组元素的值实际上会导致在函数调用者中更改数组元素的值,这就是上述代码输出的原因

0
0
0
1
1
1

如果是这样的话,那么为什么有人需要传递如下数组呢?

void Change(int (&arr)[3])

我知道需要括号才能使参数成为对数组的引用而不是引用数组,但是我能获得什么?

C++ 引用传递值 传递函数声明

评论

0赞 Klaus 9/6/2023
您可以更改指针以寻址其他数组或数组位置?如果不需要,则无需在此处使用 ref。
4赞 Friedrich 9/6/2023
使用对 or 的 or 可变引用,您将同时获得可读性和健壮性。conststd::vectorstd::array
0赞 HolyBlackCat 9/6/2023
可以说更糟。您不能再传递给它,也不能再传递给更大数组的一部分。传递可以解决这个问题,但与普通指针相比的好处是值得怀疑的。int (&arr)[3]std::array<int, 3>std::span<int, 3>
0赞 Konrad Rudolph 9/6/2023
@HolyBlackCat 除了(功能齐全)的替代方案不是普通指针,而是指针 + 大小,即使这样,您也放弃了编译时断言大小是正确的。
1赞 HolyBlackCat 9/6/2023
@KonradRudolph 如果你想要断言,可能是更好的选择,因为它在给定一个数组时会检查大小,但同时可以给定一个子数组或更大的数组,或者 .spanstd::array

答:

43赞 Vlad from Moscow 9/6/2023 #1

此函数声明:

void Change(int arr[3])

由编译器调整为:

void Change(int *arr)

因此,该函数对传递数组的大小一无所知。

如果像这样声明函数:

void Change(int ( &arr )[3])

然后在函数中,您可以使用例如标准函数获取数组的大小,或者获取其第一个和最后一个迭代器,例如 和。此外,您可以通过引用将数组传递给模板函数,该模板函数通过引用接受其参数,类似于传递任何容器。std::size()std::begin(arr)std::end(arr)

另一个优点是编译器将检查是否传递了所需大小的数组,并且函数的用户不能将空指针传递给函数。