C++ 声明对int数组的引用时,为什么必须是对const指针的引用?
注意:我使用的是g++编译器(我听说它非常好,应该非常接近标准)C++ 声明对int数组的引用时,为什么必须是对const指针的引用?,c++,arrays,pointers,reference,constants,C++,Arrays,Pointers,Reference,Constants,注意:我使用的是g++编译器(我听说它非常好,应该非常接近标准) 假设您已经声明了一个整数数组: int a[3] = { 4, 5, 6 }; 现在让我们假设您真的想要声明对该数组的引用(不管为什么,除了Bjarne说该语言支持它之外) 案例1——如果您尝试: int*& ra = a; int*const&rca = a; //wish I knew where the spaces should go (but my other post asking about
假设您已经声明了一个整数数组:
int a[3] = { 4, 5, 6 };
现在让我们假设您真的想要声明对该数组的引用(不管为什么,除了Bjarne说该语言支持它之外)
案例1——如果您尝试:
int*& ra = a;
int*const&rca = a; //wish I knew where the spaces should go (but my other post asking about this sort of protocol got a negative rank while many of the answers got ranked highly -- aha! there are stupid questions!)
然后编译器犹豫了一下,说:
"invalid initialization of non-const reference of type `int*&' from a temporary of type `int*'"
首先,为什么“a”是一个临时变量(即,它在内存中没有位置?)
不管怎样,好吧,每当我看到一个非常量错误,我都会尝试加入一个常量
案例2——如果您尝试:
int*& ra = a;
int*const&rca = a; //wish I knew where the spaces should go (but my other post asking about this sort of protocol got a negative rank while many of the answers got ranked highly -- aha! there are stupid questions!)
然后一切都很酷,它编译了,你得到了一个数组的引用
案例3——下面是另一个需要编译的东西:
int* justSomeIntPointer = a; //LINE 1
int*& rpa = justSomeIntPointer; //LINE 2
这还提供了对原始数组的引用
所以我的问题是:静态声明数组的名称在哪一点
成为常数指针?我似乎记得int数组的名称也是指向int的指针,但我不记得它曾经是指向int的const-pointer
案例1似乎失败了,因为声明的引用(ra)不是指向常量指针,这可能意味着“a”已经是指向int的常量指针
看起来案例2是可行的,因为声明的引用(rca)已经是常量指针指向int
案例3也有效,这很简单,但为什么呢?假定指向int的指针(即数组名“a”)在什么时候变成常量指针?它是在您将其分配给int*(第1行)时发生的,还是在您将该int*分配给int*&(第2行)时发生的
希望这是有意义的。谢谢。a是一个临时变量,因为您使用malloc或new在堆栈上而不是在堆上声明了它。静态声明数组的名称在什么时候变成常量指针?我似乎记得int数组的名称也是指向int的指针,但我不记得它曾经是指向int的const-pointer 因为您在cpp文件中写入了这些值,所以它是常量 您只需使用:
const int *pToArray = a;
或
int*
是指针类型,而不是数组类型。这就是为什么它不会绑定到a
,它的类型是int[3]
int* const& ra = a;
有效,因为它相当于
int* const& ra = (int*)a;
也就是说,概念上在赋值的右侧创建一个临时指针,然后将该临时指针绑定到ra
。因此,最终,这并不比:
int* ra = a;
其中,ra
实际上是指向数组第一个元素的指针,而不是数组的引用
声明对数组的引用非常简单:
typedef int array_type[3];
array_type& ra = a;
这不是一个简单的方法:
typedef int array_type[3];
array_type& ra = a;
int (&ra)[3] = a;
auto& ra = a;
C++11简易方法:
typedef int array_type[3];
array_type& ra = a;
int (&ra)[3] = a;
auto& ra = a;
静态声明数组的名称在什么时候变成常量指针?我似乎记得int数组的名称也是指向int的指针,但我不记得它曾经是指向int的const-pointer 这是一个正确的问题!如果您了解数组到指针的衰减是何时发生的,那么您就安全了。简单地说,有两件事需要考虑:
- 当尝试任何类型的“复制”时都会发生衰减(因为C不允许直接复制数组)
- 衰变是一种转换,可以在允许转换的任何时候发生:当类型不匹配时
模板通过值(T)
,则passby\u值(a)
实际上将传递一个int*
,因为不能复制int[3]
类型的数组
至于第二个,你已经看到了它的作用:在第二个例子中,当int*const&
不能绑定到int[3]
,但可以绑定到一个临时的int*
,转换就发生了。非常大的错误(也是一个非常好的面试问题)大多数人认为数组的名称等同于指针。事实并非如此。这个错误导致了C程序中的许多错误,尤其是链接错误,并且它们很难调试。区别在于:数组的名称是指针,是结构的第一个元素,数组。但是,数组名称的类型不是pointertype,而是arraytype。另一方面,指针只是指向一个事物的指针,没有其他信息。指针的类型是指针类型。arraytype还有一些其他属性,比如它知道它是否在堆栈上;因此,“临时”。本例中的临时错误来自一个阻止将临时变量分配给引用的检查。const关键字将关闭该检查。另一方面,指针类型没有“临时”的概念。现在假设您想要欺骗编译器,并为堆栈中的某个对象分配引用。在这种情况下,需要将其设置为指针。怎么做
int*&ra=&a[0]
在上述情况下,首先获取值,然后使用&(address of operator)生成pointerType。现在,pointertype没有关于其是否在堆栈上(临时变量)的信息。但是,这将引用指向数组第一个元素的指针。(因此只是指针类型,而不是arraytype)如果确实需要对数组的引用,则应使用以下命令:
int a[3] = { 4, 5, 6 };
int (&ra)[3] = a;
您试图用
int*&
创建的是指向int的指针的引用。这不是同一类型。当您使用无法更改的值(数组地址)初始化引用时,您必须声明指针常量(而不是整数)。您有一个整数数组:
int a[3] = { 4, 5, 6 };
现在,这一行:
int*& ra = a;
创建对指针的引用。由于创建了临时指针(从数组a转换而来),编译器会抱怨,因为标准禁止将临时指针分配给