Como funciona o baseado em intervalo para matrizes simples?
Isso deve ser lido como " Diga-me o que faz um ranged-for (com matrizes)? "
Responderei supondo que - tome o seguinte exemplo usando matrizes aninhadas:
int ia[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (auto &pl : ia)
Versão do texto:
ia
é uma matriz de matrizes ("matriz aninhada"), contendo [3]
matrizes, cada uma contendo [4]
valores. O exemplo acima faz um loop ia
por seu 'intervalo' primário ( [3]
) e, portanto, faz um loop nos [3]
tempos. Cada circuito produz um dos ia
's [3]
valores primários a partir do primeiro e terminando com o último - Uma matriz contendo [4]
os valores.
- Primeiro loop:
pl
igual a {1,2,3,4}
- uma matriz
- Segundo loop:
pl
igual a {5,6,7,8}
- uma matriz
- Terceiro loop:
pl
igual a {9,10,11,12}
- uma matriz
Antes de explicarmos o processo, aqui estão alguns lembretes amigáveis sobre matrizes:
- Matrizes são interpretadas como ponteiros para seu primeiro valor - Usar uma matriz sem qualquer iteração retorna o endereço do primeiro valor
pl
devo ser uma referência porque não podemos copiar matrizes
- Com matrizes, quando você adiciona um número ao próprio objeto de matriz, ele avança muitas vezes e 'aponta' para a entrada equivalente - Se
n
for o número em questão, então ia[n]
é o mesmo que *(ia+n)
(Estamos desreferenciando o endereço das n
entradas forward) e ia+n
é o mesmo que &ia[n]
(estamos obtendo o endereço dessa entrada na matriz).
Aqui está o que está acontecendo:
- Em cada loop,
pl
é definido como uma referência a ia[n]
, n
igualando a contagem do loop atual a partir de 0. Então, pl
está ia[0]
na primeira rodada, na segunda é ia[1]
, e assim por diante. Ele recupera o valor por meio de iteração.
- O loop continua enquanto
ia+n
for menor que end(ia)
.
... E é isso.
Na verdade, é apenas uma maneira simplificada de escrever isso :
int ia[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (int n = 0; n != 3; ++n)
auto &pl = ia[n];
Se a sua matriz não estiver aninhada, esse processo se torna um pouco mais simples , pois não é necessária uma referência , porque o valor iterado não é uma matriz, mas um valor 'normal':
int ib[3] = {1,2,3};
for (auto pl : ib)
cout << pl;
for (int n = 0; n != 3; ++n)
cout << ib[n];
Algumas informações adicionais
E se não quisermos usar a auto
palavra - chave ao criar pl
? Qual seria a aparência disso?
No exemplo a seguir, pl
refere-se a um array of four integers
. Em cada loop pl
é dado o valor ia[n]
:
int ia[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (int (&pl)[4] : ia)
E ... É assim que funciona, com informações adicionais para afastar qualquer confusão. É apenas um for
loop 'abreviado' que conta automaticamente para você, mas não tem uma maneira de recuperar o loop atual sem fazer isso manualmente.
for
. Mas no momento em que o array se transforma em um ponteiro, as informações de tamanho são perdidas.