Ir al contenido principal

Bucles: for, while y do-while

Los bucles son una de las estructuras de control más poderosas en programación. Nos permiten ejecutar un bloque de código repetidamente mientras se cumpla una condición específica, evitando así la necesidad de escribir el mismo código una y otra vez. Imagínate tener que escribir 100 líneas de código para mostrar los números del 1 al 100, cuando con un bucle puedes hacerlo en apenas 3 líneas.

En C#, disponemos de tres tipos principales de bucles: for, while y do-while. Cada uno tiene sus propias características y casos de uso específicos. Los bucles for son ideales cuando conocemos exactamente cuántas veces queremos repetir una acción, mientras que while y do-while son perfectos cuando la repetición depende de una condición que puede cambiar durante la ejecución.

Dominar estos bucles te permitirá crear programas más eficientes y elegantes, capaces de procesar grandes cantidades de datos, crear menús interactivos y automatizar tareas repetitivas.

El bucle for

El bucle for es probablemente el más utilizado cuando sabemos de antemano cuántas iteraciones necesitamos realizar. Su estructura es muy organizada y contiene toda la lógica de control en una sola línea.

Sintaxis del bucle for

for (inicialización; condición; incremento)
{
    // Código a ejecutar en cada iteración
}

Componentes del bucle for:

Componente Descripción Ejemplo
Inicialización Se ejecuta una sola vez al comenzar el bucle int i = 0
Condición Se evalúa antes de cada iteración. Si es false, el bucle termina i < 10
Incremento Se ejecuta al final de cada iteración i++

Ejemplos básicos del bucle for

using System;

class Program
{
    static void Main()
    {
        // Ejemplo 1: Contar del 1 al 10
        Console.WriteLine("Contando del 1 al 10:");
        for (int i = 1; i <= 10; i++)
        {
            Console.WriteLine($"Número: {i}");
        }
        
        // Ejemplo 2: Contar hacia atrás
        Console.WriteLine("\nCuenta regresiva:");
        for (int i = 5; i >= 1; i--)
        {
            Console.WriteLine($"Faltan: {i}");
        }
        Console.WriteLine("¡Despegue!");
        
        // Ejemplo 3: Incrementos de 2 en 2
        Console.WriteLine("\nNúmeros pares del 0 al 20:");
        for (int i = 0; i <= 20; i += 2)
        {
            Console.WriteLine($"Par: {i}");
        }
        
        // Ejemplo 4: Trabajar con caracteres
        Console.WriteLine("\nLetras del alfabeto (A-J):");
        for (char letra = 'A'; letra <= 'J'; letra++)
        {
            Console.WriteLine($"Letra: {letra}");
        }
    }
}

Aplicaciones prácticas del bucle for

using System;

class Program
{
    static void Main()
    {
        // Calculadora de suma acumulativa
        Console.WriteLine("Suma de números del 1 al 100:");
        int suma = 0;
        for (int i = 1; i <= 100; i++)
        {
            suma += i;
        }
        Console.WriteLine($"La suma total es: {suma}");
        
        // Tabla de multiplicar
        Console.WriteLine("\nTabla del 7:");
        for (int i = 1; i <= 10; i++)
        {
            int resultado = 7 * i;
            Console.WriteLine($"7 x {i} = {resultado}");
        }
        
        // Procesamiento de arrays
        int[] numeros = {10, 25, 33, 47, 52, 68, 71, 89, 93};
        Console.WriteLine("\nNúmeros del array:");
        for (int i = 0; i < numeros.Length; i++)
        {
            Console.WriteLine($"Posición {i}: {numeros[i]}");
        }
        
        // Búsqueda de elementos
        int valorBuscado = 47;
        bool encontrado = false;
        for (int i = 0; i < numeros.Length; i++)
        {
            if (numeros[i] == valorBuscado)
            {
                Console.WriteLine($"\n¡Encontrado! {valorBuscado} está en la posición {i}");
                encontrado = true;
                break; // Salimos del bucle cuando lo encontramos
            }
        }
        
        if (!encontrado)
        {
            Console.WriteLine($"\nEl valor {valorBuscado} no se encontró en el array");
        }
    }
}

El bucle while

El bucle while ejecuta un bloque de código mientras una condición sea verdadera. Es especialmente útil cuando no sabemos exactamente cuántas iteraciones necesitaremos, sino que dependemos de que se cumpla una condición específica.

Sintaxis del bucle while

while (condición)
{
    // Código a ejecutar mientras la condición sea true
    // Es importante modificar algo que afecte a la condición
}

Características importantes:

  • La condición se evalúa antes de ejecutar el código del bucle
  • Si la condición es false desde el principio, el bucle nunca se ejecuta
  • Debemos asegurarnos de que algo dentro del bucle modifique la condición, o tendremos un bucle infinito

Ejemplos del bucle while

using System;

class Program
{
    static void Main()
    {
        // Ejemplo 1: Contador simple
        Console.WriteLine("Contando con while:");
        int contador = 1;
        while (contador <= 5)
        {
            Console.WriteLine($"Iteración: {contador}");
            contador++; // ¡Importante! Modificamos la variable de control
        }
        
        // Ejemplo 2: Suma hasta llegar a un límite
        Console.WriteLine("\nSumando números hasta superar 50:");
        int suma = 0;
        int numero = 1;
        while (suma < 50)
        {
            suma += numero;
            Console.WriteLine($"Sumamos {numero}, total: {suma}");
            numero++;
        }
        
        // Ejemplo 3: Búsqueda en texto
        string texto = "Programar en C# es divertido";
        char letraBuscada = 'a';
        int posicion = 0;
        int contadorLetras = 0;
        
        Console.WriteLine($"\nBuscando la letra '{letraBuscada}' en: \"{texto}\"");
        while (posicion < texto.Length)
        {
            if (texto[posicion] == letraBuscada)
            {
                Console.WriteLine($"Encontrada en posición: {posicion}");
                contadorLetras++;
            }
            posicion++;
        }
        Console.WriteLine($"Total de '{letraBuscada}' encontradas: {contadorLetras}");
        
        // Ejemplo 4: Validación de entrada
        Console.WriteLine("\nIntroduce un número entre 1 y 10:");
        string entrada;
        int numeroValido;
        bool esValido = false;
        
        while (!esValido)
        {
            entrada = Console.ReadLine();
            if (int.TryParse(entrada, out numeroValido))
            {
                if (numeroValido >= 1 && numeroValido <= 10)
                {
                    esValido = true;
                    Console.WriteLine($"¡Perfecto! Has introducido: {numeroValido}");
                }
                else
                {
                    Console.WriteLine("El número debe estar entre 1 y 10. Inténtalo de nuevo:");
                }
            }
            else
            {
                Console.WriteLine("Eso no es un número válido. Inténtalo de nuevo:");
            }
        }
    }
}

El bucle do-while

El bucle do-while es similar al while, pero con una diferencia crucial: la condición se evalúa después de ejecutar el bloque de código, lo que garantiza que el código se ejecute al menos una vez.

Sintaxis del bucle do-while

do
{
    // Código a ejecutar
    // Se ejecuta al menos una vez, incluso si la condición es false
} while (condición);

Características importantes:

  • El código se ejecuta primero, luego se evalúa la condición
  • Se ejecuta al menos una vez, independientemente de la condición inicial
  • Muy útil para menús y validaciones donde necesitamos al menos una ejecución

Ejemplos del bucle do-while

using System;

class Program
{
    static void Main()
    {
        // Ejemplo 1: Menú interactivo
        int opcion;
        do
        {
            Console.WriteLine("\n=== MENÚ PRINCIPAL ===");
            Console.WriteLine("1. Ver información");
            Console.WriteLine("2. Realizar cálculo");
            Console.WriteLine("3. Configuración");
            Console.WriteLine("0. Salir");
            Console.WriteLine("Elige una opción:");
            
            string entrada = Console.ReadLine();
            int.TryParse(entrada, out opcion);
            
            switch (opcion)
            {
                case 1:
                    Console.WriteLine("Mostrando información...");
                    break;
                case 2:
                    Console.WriteLine("Realizando cálculo...");
                    break;
                case 3:
                    Console.WriteLine("Abriendo configuración...");
                    break;
                case 0:
                    Console.WriteLine("¡Hasta luego!");
                    break;
                default:
                    Console.WriteLine("Opción no válida. Inténtalo de nuevo.");
                    break;
            }
        } while (opcion != 0);
        
        // Ejemplo 2: Juego de adivinanza
        Random random = new Random();
        int numeroSecreto = random.Next(1, 11); // Número entre 1 y 10
        int intento;
        int numeroIntentos = 0;
        
        Console.WriteLine("\n¡Juego de adivinanza!");
        Console.WriteLine("He pensado en un número entre 1 y 10. ¿Puedes adivinarlo?");
        
        do
        {
            numeroIntentos++;
            Console.WriteLine($"Intento #{numeroIntentos}: Introduce tu número:");
            string entradaJuego = Console.ReadLine();
            int.TryParse(entradaJuego, out intento);
            
            if (intento < numeroSecreto)
            {
                Console.WriteLine("Muy bajo. Intenta con un número mayor.");
            }
            else if (intento > numeroSecreto)
            {
                Console.WriteLine("Muy alto. Intenta con un número menor.");
            }
            else
            {
                Console.WriteLine($"¡CORRECTO! Has adivinado en {numeroIntentos} intentos.");
            }
            
        } while (intento != numeroSecreto);
        
        // Ejemplo 3: Validación con repetición garantizada
        double saldo;
        do
        {
            Console.WriteLine("\nIntroduce tu saldo inicial (debe ser positivo):");
            string entradaSaldo = Console.ReadLine();
            
            if (!double.TryParse(entradaSaldo, out saldo))
            {
                Console.WriteLine("Por favor, introduce un número válido.");
                saldo = -1; // Forzamos que se repita
            }
            else if (saldo < 0)
            {
                Console.WriteLine("El saldo debe ser positivo.");
            }
            
        } while (saldo < 0);
        
        Console.WriteLine($"Saldo registrado correctamente: {saldo:C}");
    }
}

Comparación entre tipos de bucles

¿Cuándo usar cada tipo?

Tipo de bucle Cuándo usarlo Ejemplo de uso
for Cuando conoces el número exacto de iteraciones Procesar arrays, contadores, tablas de multiplicar
while Cuando la condición puede cambiar y no sabes cuántas iteraciones necesitas Búsquedas, procesamiento de datos hasta una condición
do-while Cuando necesitas ejecutar el código al menos una vez Menús, validaciones de entrada, juegos

Conversión entre bucles

Cualquier bucle puede convertirse en otro tipo. Aquí tienes ejemplos de la misma funcionalidad implementada con diferentes bucles:

using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("Contando del 1 al 5 con diferentes bucles:");
        
        // Con for
        Console.WriteLine("\nCon for:");
        for (int i = 1; i <= 5; i++)
        {
            Console.WriteLine($"For: {i}");
        }
        
        // Con while (equivalente)
        Console.WriteLine("\nCon while:");
        int j = 1;
        while (j <= 5)
        {
            Console.WriteLine($"While: {j}");
            j++;
        }
        
        // Con do-while (equivalente)
        Console.WriteLine("\nCon do-while:");
        int k = 1;
        do
        {
            Console.WriteLine($"Do-while: {k}");
            k++;
        } while (k <= 5);
    }
}

Bucles anidados

Los bucles pueden contener otros bucles dentro de ellos, lo que se conoce como bucles anidados. Son muy útiles para trabajar con estructuras bidimensionales como tablas o matrices.

using System;

class Program
{
    static void Main()
    {
        // Ejemplo 1: Tabla de multiplicar completa
        Console.WriteLine("Tablas de multiplicar del 1 al 5:");
        for (int tabla = 1; tabla <= 5; tabla++)
        {
            Console.WriteLine($"\nTabla del {tabla}:");
            for (int multiplicador = 1; multiplicador <= 10; multiplicador++)
            {
                int resultado = tabla * multiplicador;
                Console.WriteLine($"{tabla} x {multiplicador} = {resultado}");
            }
        }
        
        // Ejemplo 2: Patrón de asteriscos
        Console.WriteLine("\nPatrón de asteriscos:");
        for (int fila = 1; fila <= 5; fila++)
        {
            for (int columna = 1; columna <= fila; columna++)
            {
                Console.Write("* ");
            }
            Console.WriteLine(); // Nueva línea al final de cada fila
        }
        
        // Ejemplo 3: Búsqueda en matriz de texto
        string[] nombres = {"Ana", "Luis", "María", "Pedro", "Carmen"};
        char letraBuscar = 'a';
        int totalEncontradas = 0;
        
        Console.WriteLine($"\nBuscando la letra '{letraBuscar}' en todos los nombres:");
        for (int i = 0; i < nombres.Length; i++)
        {
            int contadorEnNombre = 0;
            for (int j = 0; j < nombres[i].Length; j++)
            {
                if (char.ToLower(nombres[i][j]) == letraBuscar)
                {
                    contadorEnNombre++;
                    totalEncontradas++;
                }
            }
            Console.WriteLine($"{nombres[i]}: {contadorEnNombre} veces");
        }
        Console.WriteLine($"Total en todos los nombres: {totalEncontradas}");
    }
}

Buenas prácticas con bucles

Evitar bucles infinitos

Un error común es crear bucles que nunca terminan. Asegúrate siempre de que:

// ❌ MAL - Bucle infinito
/*
int i = 0;
while (i < 10)
{
    Console.WriteLine(i);
    // ¡Olvidamos incrementar i!
}
*/

// ✅ BIEN - Bucle controlado
int i = 0;
while (i < 10)
{
    Console.WriteLine(i);
    i++; // Incrementamos la variable de control
}

Variables de control con nombres descriptivos

// ❌ Poco claro
for (int x = 0; x < 100; x++) { }

// ✅ Más claro
for (int indice = 0; indice < 100; indice++) { }
for (int numeroEstudiante = 1; numeroEstudiante <= totalEstudiantes; numeroEstudiante++) { }

Limitar la complejidad de bucles anidados

// ✅ Bucles anidados simples están bien
for (int fila = 0; fila < filas; fila++)
{
    for (int columna = 0; columna < columnas; columna++)
    {
        // Operación simple
    }
}

// ❌ Evitar demasiada complejidad - considera extraer a métodos

Resumen

Los bucles son herramientas fundamentales que nos permiten automatizar tareas repetitivas en nuestros programas. El bucle for es perfecto cuando conocemos exactamente cuántas iteraciones necesitamos, el while nos sirve cuando la repetición depende de una condición variable, y el do-while garantiza al menos una ejecución, ideal para menús y validaciones.

La elección del bucle adecuado depende del contexto específico de nuestro problema, aunque cualquier tipo de bucle puede convertirse en otro. Los bucles anidados nos permiten trabajar con estructuras más complejas, pero debemos usarlos con cuidado para mantener nuestro código legible. En el siguiente tema, exploraremos las instrucciones break y continue, que nos darán aún más control sobre el flujo de ejecución dentro de nuestros bucles.