c++ - with - Em 'for(auto c: str)' o que exatamente é c?




string to char c++ (5)

Em ' for (auto c : str) ' o que exatamente é c?

c é uma variável local com armazenamento automático no escopo da instrução range-for. Seu tipo será deduzido porque você usou o auto . No caso de string str="ARZ"; , o tipo deduzido será char .

Presumivelmente, c é apenas um ponteiro para o vetor

Não há vetor, ec não é um ponteiro. É um char .

Compreender o que o alcance para fazer pode ajudar. É equivalente a fazer o seguinte (as variáveis ​​prefixadas __ não são acessíveis ao programador; elas são conceituais para o comportamento do loop):

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

Ou, neste caso particular:

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

Observe que, se você usar auto& , c será deduzido como referência ao char. A aplicação do endereço do operador a uma referência não produzirá o endereço da variável de referência, mas o endereço do objeto referido. Nesse caso, o objeto referido seria o caractere dentro da string.

Se eu declarar:

string s = "ARZ";

E, em seguida, execute o seguinte código:

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

os resultados corresponderão aos endereços de s[0] , s[1] e s[2] respectivamente.

Se eu remover o & e executar:

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

o endereço de c é sempre o mesmo.

Presumivelmente, c é apenas um ponteiro para o vetor e seu valor avança por sizeof(char) em cada loop, mas acho difícil entender por que não sou obrigado a escrever *c para acessar os valores de string.

E finalmente, se eu correr:

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

Imprime 3 pontos de interrogação.

Estou achando difícil entender o que c realmente é?


Em 'for (auto c: str)' o que exatamente é c?

É uma variável local cujo escopo é todo o bloco for e tem o tipo char .

for (auto c : str) { loop_statement }

é equivalente a

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

Em algumas implementações, sob algumas condições, desde que a vida útil de c termine antes do início da vida útil de c da próxima iteração, ela é alocada no mesmo local e no mesmo endereço. Você não pode confiar nisso.


Quando você usa referências, a referência c é uma referência a um caractere dentro da string.

Quando você não usa referências, c é uma variável de char simples, que contém uma cópia do caractere na string.

O motivo pelo qual a variante sem referência fornece o mesmo ponteiro para todas as iterações é simplesmente um detalhe de implementação, em que o compilador reutiliza o espaço para a variável c dentro de cada iteração.


Se você não souber o tipo, deixe o compilador informar:

#include <string>

template <typename T>
struct tell_type;


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

Observe que não há definição para tell_type ; portanto, isso resultará em um erro na linha de:

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

E da mesma forma

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

para o loop for (auto& ...


for (auto& c : s) 

c é uma reference a um caractere ( char& )

Esse loop é aproximadamente equivalente a C:

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

c é um caractere ( char )

Esse loop é aproximadamente equivalente a C:

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




auto