我还没有找到可以回答我感到困惑的部分的问题,如果有人回答了,我深表歉意。
我对这个 for 循环中发生的事情感到困惑,它是如何遍历地址的?
int arr[] = {1,2,3,4,5};
for(const int &arrEntry : arr){
cout << arrEntry << " ";
}
也许放置的位置&引起了混乱。请记住,C++ 并不关心您在哪里放置空格。由于 this:for (const int &arrEntry : arr)是在循环内使用的新变量的声明,因此在其名称左侧使用的意味着我们正在定义一个具有引用类型的对象,特别是对 a 的引用。这意味着在循环中,不是您正在循环的数据的副本,只是对它的引用。这意味着您无法更改其值。arrEntry&arrEntryconst intarrEntryconst
如果这不是一个声明,并且如果arrEntry之前定义过,那么表达式&arrEntry确实会采用arrEntry. 在循环体中,arrEntry已经定义了,所以你可以使用它的地址&arrEntry
int arr[] = {1,2,3,4,5};
for(const int &arrEntry : arr){
cout << arrEntry << " "; // prints a const int
cout << &arrEntry << " "; // prints a pointer to a const int
}
C++ 中基于范围的 for 循环实际上只是相当于以下内容的语法糖(由cppreference提供:
for (range_declaration : range_expression) loop_statement;
// is equivalent to:
{
auto && __range = range_expression ;
for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
在上面的代码块中,begin_expr和end_expr分别等价于std::begin(__range)和std::end(__range)。
因此,在 using 的情况下const int &arrEntry,arrEntry实际上是在“真实”(正常)for 循环内声明的,因此在每次迭代中,它都引用范围内的不同对象,就好像直接使用原始迭代器一样。
请注意,如果在正常的 for 循环之外声明这是不可能arrEntry的,因为引用不能重新指向以引用不同的对象。
要考虑的另一个重要(侧面)事实是range_expression在整个循环期间保持活动状态,这意味着您可以在那里使用纯右值(例如,调用一个std::vector<int>按值返回的函数。
在您的代码中,&arrEntry 是对 arr 的引用。这在基于 Ranged 的 For 循环中是隐含的。
for(const int &arrEntry : arr){
cout << arrEntry << " ";
}
您可以在没有参考的情况下执行此操作,结果是相同的。但请注意 arr 的值被复制到 arrEntry。
for(const int arrEntry : arr){
cout << arrEntry << " ";
}