我读了C++ Primer:
如果我们想要更改字符串中字符的值,我们必须定义 循环变量作为引用类型(第2.3.1节,第50页)。记得那个 reference只是给定对象的另一个名称。 当我们使用时 引用作为我们的控制变量,该变量绑定到每个变量 顺序中的元素。使用引用,我们可以改变 引用绑定到的字符。
此外,他们给出了这段代码:
string s("Hello World!!!");
// convert s to uppercase
for (auto &c : s) // for every char in s (note: c is a reference)
c = toupper(c); // c is a reference, so the assignment changes the char
in s
cout << s << endl;
此代码的输出是HELLO WORLD !!!
我也读过:
无法重新引用引用以引用其他对象。 因为没有办法重新绑定引用,所以引用必须是 初始化。
问题:每次将引用变量c
绑定到字符串s的下一个字符时,此代码是否会导致重新绑定?
for (auto &c : s)
c = toupper(c);
答案 0 :(得分:5)
现有变量没有重新绑定,在每次迭代时,“旧”c消失,再次创建“新”c,初始化为下一个字符。 for
循环等同于:
{
auto it = begin(s);
auto e = end(s);
// until C++17: auto it = begin(s), e = end(s);
for(; it!=e; ++it) {
auto &c = *it;
c=toupper((unsigned char)c);
}
}
您可以看到,在每次迭代时,都会重新创建c
并重新初始化。
换句话说,在基于范围的for
循环的圆括号内声明的变量将循环体作为其范围。
答案 1 :(得分:4)
否。在for
循环中为每次迭代初始化一个新引用。
for (auto &c : s)
c = toupper(c);
相当于:
for (auto it = s.begin(); it != s.end(); ++it)
{
auto &c = *it;
c = toupper(c);
}
答案 2 :(得分:1)
考虑
char s[5] = {'h','e','l','l','o'};
for (int secret_index=0; secret_index<5; ++secret_index) {
char &c = s[secret_index];
c = toupper(c);
}
每次迭代都会初始化一个新引用(具有相同的变量名称)。也就是说,for循环在每次迭代时进入并离开范围。