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

问题描述 投票:1回答:6

如果我运行代码

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到底是什么?

c++ loops range auto
6个回答
3
投票

在'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开始之前就已结束,因此它会在同一位置分配并获得相同的地址。您不能依靠它。


3
投票

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

#include <string>

template <typename T>
void tell_type(T&& x);


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

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

undefined reference to void tell_type<char>(char)

0
投票
for (auto& c : s) 

[c是字符的referencechar&

此循环大致等效于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])


0
投票

在此基于范围的for循环中

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

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

在循环中,将忽略对象c的分配值,并使用字符'?'重新分配对象。这样就输出了三个字符'?'

在此基于范围的for循环中

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

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

在此基于范围的for循环中

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

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


0
投票

当使用引用时,引用c是对字符串内字符的引用。

[不使用引用时,c是普通的char变量,它包含字符串中字符的copy

非引用变量为所有迭代提供相同指针的原因只是一个实现细节,在该细节中,编译器会在每次迭代中为变量c重新使用空间。


0
投票

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

c是一个变量。因为您使用了auto,所以将推断出它的类型。如果为string s="ARZ";,则推导类型将为char

大概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 = s;
    auto __begin = range.begin();
    auto __end = range.end();
    for ( ; __begin != __end; ++__begin) {
        auto c = *__begin;         // note here
        cout << (void*)&c << endl;
    }
}

0
投票

当使用引用时,引用c是对字符串内字符的引用。

[不使用引用时,c是普通的char变量,它包含字符串中字符的copy

© www.soinside.com 2019 - 2024. All rights reserved.