简体   繁体   English

使用C ++ 11 Range for循环更改字符串中的字符

[英]Using a C++11 Range for loop to Change the Characters in a string

I read in C++ Primer : 我读了C ++ Primer

If we want to change the value of the characters in a string, we must define the loop variable as a reference type (§ 2.3.1, p. 50). 如果我们想要更改字符串中字符的值,我们必须将循环变量定义为引用类型(第2.3.1节,第50页)。 Remember that a reference is just another name for a given object. 请记住,引用只是给定对象的另一个名称。 When we use a reference as our control variable, that variable is bound to each element in the sequence in turn. 当我们使用引用作为控制变量时,该变量依次绑定到序列中的每个元素。 Using the reference, we can change the character to which the reference is bound. 使用引用,我们可以更改引用绑定的字符。

Further they give this code : 他们还提供了这段代码:

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;

The output of this code is HELLO WORLD!!! 这段代码的输出是HELLO WORLD !!!

I also read : 我也读过:

There is no way to rebind a reference to refer to a different object . 无法重新绑定引用以引用其他对象 Because there is no way to rebind a reference, references must be initialized. 由于无法重新绑定引用,因此必须初始化引用。

Question : Won't this code cause rebinding each time the reference variable c is binded to next character of string s ? 问题:每次将引用变量c绑定到字符串s的下一个字符时,此代码是否会导致重新绑定?

for (auto &c : s)   
    c = toupper(c); 

There's no rebinding of an existing variable, at each iteration the "old" c dies and the "new" c is created again, initialized to the next character. 没有现有变量的重新绑定,在每次迭代时“旧”c死亡并且再次创建“新”c,初始化为下一个字符。 That for loop is equivalent to: 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);
    }
}

where you see that, at each iteration, c is re-created and re-initialized. 在那里你看到,在每次迭代时, c被重新创建并重新初始化。

In other words, a variable declared inside the round parentheses of a range-based for loop has the body of the loop as its scope. 换句话说,在基于范围的for循环的圆括号内声明的变量将循环体作为其范围。

No. A new reference is initialized for each iteration in the for loop. 的新的参考被初始化为在每次迭代for循环。

for (auto &c : s)   
    c = toupper(c); 

is equivalent to: 相当于:

for (auto it = s.begin(); it != s.end(); ++it)
{
    auto &c = *it;
    c = toupper(c);
}

Consider 考虑

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);
}

A new reference (with the same variable name) is initialized on every iteration. 每次迭代都会初始化一个新引用(具有相同的变量名称)。 That is, the for loop enters and leaves the scope on every iteration. 也就是说,for循环在每次迭代时进入和离开作用域。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM