cpp-bucle-basado-en-rangos

Qué es y cómo los bucles basados en rangos en C++

El bucle en rango en C++ es una estructura de control que permite iterar fácilmente sobre los elementos de una colección (como arrays, vectores o listas)

A diferencia de los bucles for, while, y do-while, el bucle en rango está diseñado específicamente para recorrer elementos de una colección sin necesidad de manejar índices explícitamente.

El bucle en rango ofrece varias ventajas sobre otros bucles tradicionales. La sintaxis es más clara y concisa (lo que facilita su comprensión y mantenimiento del código).

Además, al no depender de índices, se reduce la posibilidad de cometer errores al acceder a elementos de la colección.

Si quieres aprender más sobre Bucles
consulta el Curso de Introducción a la Programación leer más ⯈

Sintaxis básica

En C++, el bucle basado en rango tiene la siguiente sintaxis,

for (auto& elemento : colección)
{
    // Código a ejecutar para cada elemento de la colección
}
  • auto&: Especifica el tipo del elemento, y auto permite deducir automáticamente el tipo. El uso de & evita copias innecesarias de los elementos.
  • elemento: Es una variable que representa cada elemento de la colección en cada iteración.
  • coleccion: Es la colección sobre la que se itera (por ejemplo, un array, un vector).

Ejemplo básico

Veamos un ejemplo básico en el que usamos el bucle basado en rangos para imprimir los números en un arreglo:

#include <iostream>

int main() {
    int numeros[] = { 1, 2, 3, 4, 5 };

    for (int numero : numeros)
    {
        std::cout << numero << std::endl;
    }

    return 0;
}

En este ejemplo:

  • int numero : numeros recorre cada elemento en el arreglo numeros.
  • std::cout imprime cada número en la consola.

El resultado es que se imprimirán los números del 1 al 5 en la pantalla.

Modificación de elementos

En C++, el bucle basado en rangos permite modificar los elementos de la colección si se emplea una referencia:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> numeros = { 1, 2, 3, 4, 5 };

    for (int& numero : numeros) // Usar referencia para modificar
    {
        numero *= 2; // Doble el valor de cada elemento
    }

    for (const int& numero : numeros) // Iterar de nuevo para imprimir
    {
        std::cout << numero << std::endl;
    }

    return 0;
}

Colecciones personalizadas

Para usar el bucle basado en rangos con colecciones personalizadas deben ser iterables y proporcionar un iterador.

Las colecciones estándar en C++ (como std::vector, std::list, y std::array) ya cumplen con estos requisitos, pero para colecciones personalizadas, deberás implementar el operador begin() y end().

#include <iostream>
#include <vector>

int main() {
    std::vector<int> numeros = { 10, 20, 30, 40, 50 };

    for (int numero : numeros)
    {
        std::cout << numero << std::endl;
    }

    return 0;
}

Ejemplos prácticos

Recorrer un vector de números

Supongamos que tenemos un vector de números enteros y queremos imprimir cada uno de ellos en la consola. Utilizando el bucle basado en rangos, el código sería el siguiente:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> numeros = { 1, 2, 3, 4, 5 };

    for (const int& numero : numeros)
    {
        std::cout << numero << std::endl;
    }

    return 0;
}

Iterar sobre un Arreglo de Cadenas

Si tenemos un arreglo de cadenas y queremos realizar alguna operación sobre cada una de ellas, el bucle basado en rangos es la opción ideal:

#include <iostream>
#include <string>

int main() {
    std::string nombres[] = { "Juan", "María", "Pedro" };

    for (const std::string& nombre : nombres)
    {
        std::cout << nombre << std::endl;
    }

    return 0;
}

Suma de elementos en un vector

#include <iostream>
#include <vector>

int main() {
    std::vector<int> numeros = { 1, 2, 3, 4, 5 };
    int suma = 0;

    for (const int& numero : numeros)
    {
        suma += numero;
    }

    std::cout << "La suma de los números es: " << suma << std::endl;

    return 0;
}

Búsqueda de un elemento en un vector

#include <iostream>
#include <vector>

int main() {
    std::vector<int> numeros = { 10, 20, 30, 40, 50 };
    int buscar = 30;
    bool encontrado = false;

    for (const int& numero : numeros)
    {
        if (numero == buscar)
        {
            encontrado = true;
            break;
        }
    }

    if (encontrado)
    {
        std::cout << "El número " << buscar << " se encuentra en el vector." << std::endl;
    }
    else
    {
        std::cout << "El número " << buscar << " no se encuentra en el vector." << std::endl;
    }

    return 0;
}

Iteración sobre listas

El bucle basado en rangos también se puede usar para iterar sobre elementos en una lista:

#include <iostream>
#include <list>

int main() {
    std::list<int> numeros = { 10, 20, 30, 40, 50 };

    for (const int& numero : numeros)
    {
        std::cout << numero << std::endl;
    }

    return 0;
}

Iteración sobre colecciones personalizadas

Para colecciones personalizadas, asegúrate de que implementen los métodos begin() y end():

#include <iostream>
#include <vector>

class MiColeccion {
public:
    void agregar(int valor) {
        elementos.push_back(valor);
    }

    std::vector<int>::iterator begin() {
        return elementos.begin();
    }

    std::vector<int>::iterator end() {
        return elementos.end();
    }

private:
    std::vector<int> elementos;
};

int main() {
    MiColeccion coleccion;
    coleccion.agregar(1);
    coleccion.agregar(2);
    coleccion.agregar(3);

    for (int valor : coleccion)
    {
        std::cout << valor << std::endl;
    }

    return 0;
}

Estos ejemplos tienen el propósito de mostrar cómo utilizar el bucle basado en rangos No significa que sea la mejor forma de resolver el problema que abordan. Lo normal es que haya alternativas mejores