c++ - 在“ for(auto c:str)”中,c到底是什么?




loops range (5)

如果我声明:

string s = "ARZ";

然后运行以下代码:

for (auto& c : s) {
  cout << (void*)&c << endl;
}

结果将分别对应于 s[0]s[1]s[2]

如果我删除 & 并运行:

for (auto c : s) {
  cout << (void*)&c << endl;
}

c 的地址始终相同。

大概 c 只是一个指向向量的指针,并且每个循环它的值都按 sizeof(char) ,但是我发现很难理解为什么我不需要编写 *c 来访问字符串char值。

最后,如果我运行:

for (auto c: s) {
  c='?';
  cout << c << endl;
}

它打印出3个问号。

我发现很难理解 c 到底是什么?


在“ for(auto c:str)”中,c到底是什么?

这是一个局部变量,其范围是整个 for 块,并且具有 char 类型。

for (auto c : str) { loop_statement }

相当于

{
    for (auto __begin = str.begin(), __end = str.end(); __begin != __end; ++__begin) {
        auto c = *__begin;
        loop_statement
    }
}

在某些实现中,在某些情况下,由于 c 的生存期在下一个迭代项 c 的生存期开始之前就结束了,因此它将在同一位置分配并获得相同的地址。 您不能依靠它。


在' for (auto c : str) '中,c到底是什么?

c是在range-for语句范围内具有自动存储的局部变量。 因为您使用了 auto 所以将推断出它的类型。 如果是 string str="ARZ"; ,则推导类型将为 char

大概c只是指向向量的指针

没有向量,并且c不是指针。 它是一个 char

了解作用范围可以帮助您。 这等效于执行以下操作(带前缀 __ 变量对于程序员来说是不可访问的;它们是循环行为的概念):

{
    auto && __range = range_expression;
    auto __begin = begin_expr;
    auto __end = end_expr;
    for (; __begin != __end; ++__begin) {
        range_declaration = *__begin;
        loop_statement
    }
} 

或者,在这种情况下:

{
    auto && __range = str;
    auto __begin = range.begin();
    auto __end = range.end();
    for ( ; __begin != __end; ++__begin) {
        auto c = *__begin;         // note here
        cout << (void*)&c << endl;
    }
}

请注意,如果使用 auto& ,则c将被推导为char的引用。 将addressof运算符应用于引用不会产生引用变量的地址,而是会产生引用对象的地址。 在这种情况下,引用的对象将是字符串中的字符。


在此基于范围的for循环中

for (auto c: s) {c='?'; cout << c << endl;}

因为字符串 s 的大小等于 3 所以进行了三次迭代。

在循环内,将忽略对象 c 的分配值,并使用字符 '?' 重新分配对象 。 所以三个字符 '?' 输出。

局部变量c的类型是 char ,它是类 std::string 的值类型。

在此基于范围的for循环中

for (auto& c : s) cout << (void*)&c << endl;

变量 c 具有一个引用类型,更确切地说是 char & 类型。 因此,在此循环中,将输出引用对象的地址。 也就是说,在此循环中,将输出字符串 s 的元素的地址。

在此基于范围的for循环中

for (auto c : s) cout << (void*)&c << endl;

输出相同局部变量 c 的地址。


如果您不知道类型,则可以让编译器告诉您:

#include <string>

template <typename T>
struct tell_type;


int main(){
    std::string s = "asdf";
    for (auto& c : s) { 
        tell_type<decltype(c)>();
    }
}

请注意,没有 tell_type 定义,因此将导致以下错误:

error: implicit instantiation of undefined template 'tell_type<char>'

同样

error: implicit instantiation of undefined template 'tell_type<char &>'

对于 for (auto& ... 循环。


for (auto& c : s) 

c 是对字符( char& )的 reference

此循环大致等效于C:

for (char* c=str; *c; ++c)
for (auto c : s)

c 是一个字符( char

此循环大致等效于C:

int i=0;
for (char c=str[i]; i<strlen(str); c=str[++i])




auto