为什么我们不能将 int array[] 传递给 hoo(int* &p)?

Why can't we pass int array[] to hoo(int* &p)?

本文关键字:int hoo 不能 我们 array 为什么      更新时间:2023-10-16

在我的理解中,int array[]={1,2,3,4,5}中的array只是指向array的第一个元素的指针。这意味着可以将array分配给类型为 int* 的指针ptr

hoo中的参数int* &p将通过引用传递参数。这意味着我们可以更改传递的参数以指向hoo中的另一个值。

void hoo(int* &p, int n)
{
    for (int i = 0; i < n; i++)
        cout << p[i] << endl;
}
int main()
{
    int array[] = { 1,2,3,4,5 };
    // I can do this
    int* ptr = array;
    hoo(ptr, 5);
    // but not this.
    //hoo(array, 5);
}

问题

为什么我们不能在没有ptr的情况下将 int array传递给hoo

在我的理解中,int array[]={1,2,3,4,5}中的数组只是指向数组第一个元素的指针。

这是不正确的。数组是数组,指针是指针。它们是具有不同属性的不同类型。它们经常被混淆,因为数组具有这样一个属性,即它将急切地衰减到指向其第一个元素的指针。

hoo(array, 5);尝试将array转换为int*但该转换的结果是右值,不能绑定到非const引用。例如,如果您更改hoo以采用const引用,它将编译良好:

void hoo(int* const &p, int n) { }
int main()
{
    int array[] = { 1,2,3,4,5 };
    hoo(array, 5);
}

在这种情况下,您无法更改p指向的内容,从而使引用的使用毫无意义。

当函数采用int* &参数时,即对指向int指针的(非移动)引用 - 那么需要有一个真正的指针变量,该引用所引用。它不能是临时指针值。因此,您不能执行以下操作:

int x;
hoo(&x, 123);

因为没有指针变量可以引用 - 只是临时的。你的int[5]本质上是一样的.实际上任何地方都没有int*变量 - 只有 5 int 秒。当你array传递给hoo()时,C++对该标识符所做的是数组到指针的衰减:它实际上传递&(array[0])。所以就像前面的情况一样,这不会编译。

其他答案已经解释了这个问题。我想建议改变编码实践。

使用void hoo(int* &p, int n)作为函数声明是非常非常古老的风格。使用模板,可以让编译器推断大小并获取对数组的引用,从而避免使用指针的需要。

template <size_t N>
void hoo( int (&p)[N]) // The argument is a reference to an array of N elements.
{
    for (int i = 0; i < N; i++)
        cout << p[i] << endl;
}

对函数的调用变得自然。

int array[] = { 1,2,3,4,5 };
hoo(array);

如果您的函数也需要能够支持动态分配的数组,则可以按如下方式重载该函数。

void hoo(int* p, size_t N)
{
    for (int i = 0; i < N; i++)
        cout << p[i] << endl;
}
template <size_t N>
void hoo( int (&p)[N]) // The argument is a reference to an array of N elements.
{
    hoo(p, N);
}