4 Formas de Loops For em C++

por Fabio A. Mazzarino

Loop é uma construção básica em uma linguagem de programação estruturada, e o loop for uma das formas mais comuns. Em C++ temos 5 formas de implementar loops for.

1. Herança da Linguagem C

O primeiro tipo de for é o herdado da linguagem C, e na verdade é um while disfarçado. A sintaxe é a seguinte:

for (<INIT>; <CONDITION>; <ITERATION>)
    <EXPRESSIONS>

INIT é a expressão de inicialização, executada antes de iniciar o loop. Normalmente é uma atribuição a um ponteiro, ou um contador, sendo possível fazer mais de uma atribuição na mesma expressão, utilizando o operador ,. Ao deixar essa expressão em branco nenhum código não há nenhum tipo de execução antes de começar o loop.

CONDITION é a condição de manutenção do loop, enquanto a expressão for verdadeira continuará a ser executado. Ao deixar essa expressão em branco o loop não sairá senão através da interrupção através da palavra reservada break.

ITERATION é a expressão de iteração, sendo executada ao fim da execução do conteúdo do loop, antes de executar o teste de CONDITION. Normalmente é executado um incremento, decremento, ou iteração do loop. Deixar esta expressão em branco significa que não haverá nenhum tipo de execução antes do teste de CONDITION.

EXPRESSIONS é o conteúdo em si do loop, que será executado a cada ITERAÇÃO, normalmente entre chaves.

A sequência de execução, portanto, é a seguinte:

  1. INIT
  2. CONDITION, sair se for falso
  3. EXPRESSIONS
  4. ITERATION
  5. CONDITION, sair se for falso
  6. EXPRESSIONS
  7. ITERATION
  8. CONDITION

Ou seja, o for é equivalente a:

<INIT>
while (CONDITION) {
    <EXPRESSIONS>
    <ITERATION>
}

Já discutimos várias construções desse tipo de for no Lab C++ antes.

2. Iterators de Containers STL

Apesar de não ser exatamente uma forma de for, é uma construção muito comum quando utilizando STL. Quase todos os containers STL tem funções para manipulação de iterators derivados de std::iterator. Sua forma mais comum é a seguinte:

for (auto it = container.begin(); it != container.end(); it++)
    <EXPRESSIONS>

Note que nessa construção utilizamos a forma tradicional do loop for, porém as três expressões se valem de operações com std::iterator par percorrer todos os elementos do container.

3. STL std::for_each

Este loop também já foi abordado anteriormente no Lab C++. Basicamente é um loop de iteração em containers e arrays. Sua sintaxe é a seguinte:

std::for_each(<START>, <END>, <FUNCTION>); 

START é um std::iterator ou um ponteiro para o início do array. END é um std::iterator ou um ponteiro para o fim do array. Enquanto que FUNCTION é uma função, declarada ou anônima (lambda) que será executada para cada elemento entre START e END.

Portanto os dois códigos loops vão gerar a mesma saída:

char arr[5] = {'a', 'b', 'c', 'd', 'e'};
std::for_each(arr, arr + 5, [] (char c) { std::cout << c << " ";});
std::cout << std::endl;

std::list<char> lst(arr, arr + 5);
std::for_each(lst.begin(), lst.end(), [] (char c) { std::cout << c << " ";});
std::cout << std::endl;

Para saber mais sobre funções anônimas, ou funções lambdas, acesse este post anterior do Lab C++.

4. C++11 for com Iteráveis

Tal qual o for, ou foreach, de muitas linguagens scripts modernas C++ também implementa seu tipo de foreach. A sintaxe é a seguinte:

for (<DECL> : <RANGE>)
    <EXPRESSION>

DECL é a declaração de tipo do conteúdo iterado, ou seja, se RANGE é um array de caracteres, DECL é uma variável char. RANGE é um range de valores, seja um literal, um array ou um container iterável do STL.

Os exemplos abaixo vão entregar a mesma saída:

for (char c : {'a', 'b', 'c', 'd', 'e'})
    std::cout << c << " ";
std::cout << std::endl;

char arr[5] = {'a', 'b', 'c', 'd', 'e'};
for (char c : arr)
    std::cout << c << " ";
std::cout << std::endl;

std::list<char> lst(arr, arr + 5);
for (char c : lst)
    std::cout << c << " ";
std::cout << std::endl;

É possível utilizar modificadores de acesso e referência na declaração DECL, assim ao trocar char c por char& c, os valores de c que forem alterados serão refletidos no conteúdo.

Qual Utilizar?

O mais importante na hora de escolher qual opção de loop for utilizar é a facilidade de manutenção, e em raros casos performance. A manutenção de código C++ é mais custosa que a maioria das demais linguagens, portanto sempre deve ser levada em consideração.

Preocupe-se com a performance somente quando esta mostrar-se uma questão a ser considerada. No geral a linguagem C++ é escolhida por uma questão de performance, e normalmente suas construção tem bastante performance. Nos casos em que for necessário performance prefira as duas primeiras formas de loop, mais simples e mais otimizadas.