Bucles basados en rangos¶
Cuando iteramos sobre todos los elementos de una secuencia,
como ocurre a menudo con el contenedor vector
, indefectiblemente
usamos un bucle for
con las habituales características:
Inicialización de un contador en 0
Condición de finalización cuando el contador iguala el tamaño del contenedor
Incremento del contador en una unidad
for (size_t i = 0; i < v.size(); ++i)
En esos casos es más robusto y simple utilizar un formato de bucle especializado
en recorrer todos los elementos de una secuencia: un bucle for
especializado en rangos.
La sintaxis es la siguiente:
for (tipo elemento : identificador_secuencia)
La variable elemento
va tomando iteradamente los valores de la secuencia.
Esta variable elemento
es una copia del elemento del contenedor:
si dentro del bucle alteramos el valor de la variable elemento
,
el contenedor permanece inalterado.
Nota
Este tipo de bucles basados en recorrer los elementos de una secuencia están presentes en muchos lenguajes, siendo masivamente utilizados en el lenguaje Python. En C++ se incorporaron a partir de la versión 11 del estándar.
Veamos un ejemplo sin y con bucle for
por rango.
Suma de los elementos de un vector: sin usar for
por rango
#include <iostream>
#include <vector>
using namespace std;
double suma_elementos(const vector<double>&);
int main ()
{
vector<double> v{1, 2, 3, 4, 5};
double suma = suma_elementos(v);
cout << "La suma de los elementos es " << suma << endl;
}
double suma_elementos(const vector<double>& v)
{
double suma = 0.;
for (size_t i = 0; i < v.size(); ++i)
suma += v[i];
return suma;
}
Edita, compila y ejecuta el código
Suma de los elementos de un vector: usando for
por rango
#include <iostream>
#include <vector>
using namespace std;
double suma_elementos(const vector<double>&);
int main ()
{
vector<double> v{1, 2, 3, 4, 5};
double suma = suma_elementos(v);
cout << "La suma de los elementos es " << suma << endl;
}
double suma_elementos(const vector<double>& v)
{
double suma = 0.;
for (double x : v)
suma += x;
return suma;
}
Edita, compila y ejecuta el código
El especificador auto
¶
Definir inicializando una variable con el resultado de una expresión o con el valor devuelto por una función es una tarea recurrente en programación.
En ocasiones, por ser un tipo verboso, porque resulta más cómodo o porque es más robusto, es mejor que sea el compilador el que deduzca automáticamente el tipo asociado a una expresión o el valor devuelto por una función en el momento de definir inicializando una variable.
Para ello, basta especificar la variable a almacenar como auto
. En
el caso del bucle for
por rango, auto
dota
aún de mayor simplicidad a la construcción.
Veamos el ejemplo anterior, pero ahora usando masivamente auto
.
Suma de los elementos de un vector: usando for
por rango y auto
¶
#include <iostream>
#include <vector>
using namespace std;
double suma_elementos(const vector<double>&);
int main ()
{
vector<double> v{1, 2, 3, 4, 5};
auto suma = suma_elementos(v);
cout << "La suma de los elementos es " << suma << endl;
}
double suma_elementos(const vector<double>& v)
{
auto suma = 0.; // Deduce que es double porque 0. es un literal double
for(auto x : v)
suma += x;
return suma;
}
Edita, compila y ejecuta el código
En el siguiente ejemplo se muestra comparativamente dos versiones de una función que muestra por pantalla los valores de un vector.
void muestra_vector_v1(const vector<double>& v)
{
for (size_t i = 0; i < v.size(); ++i)
cout << v[i] << endl;
}
void muestra_vector_v2(const vector<double>& v)
{
for (auto x : v)
cout << x << endl;
}