据我了解,array
中的int array[]={1,2,3,4,5}
只是指向array
第一个元素的指针。这意味着可以将array
分配给类型为ptr
的指针int*
。
int* &p
中的参数hoo
将通过引用传递该参数。这意味着我们可以更改传递的参数以指向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);
}
为什么在没有array
的情况下不能将int hoo
传递给ptr
吗?
答案 0 :(得分:7)
根据我的理解,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
指向的内容,从而使引用毫无意义。
答案 1 :(得分:3)
当一个函数接受一个t3 :: (m->n) -> (n->m) -> m->n
t3 x y = x.y.x
参数时,即对一个指向int* &
的指针的(非移动)引用-那么就需要一个真正的指针变量来该参考所指的。不能是临时指针值。因此,您不能执行以下操作:
int
因为没有指针变量要引用-只是临时变量。与您的int x;
hoo(&x, 123);
基本相同。实际上,任何地方都没有int[5]
变量-只有5个int*
。当您将int
传递给array
时,C ++对该标识符所做的就是array-to-pointer decay:它实际上传递了hoo()
。因此,就像前面的情况一样,它不会编译。
答案 2 :(得分:3)
其他答案已经说明了问题。我想建议更改编码惯例。
使用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);
}