C

C

Tutorial C: Control iterativo

Aprende el control iterativo en C con bucles while y for. Domina su uso, sintaxis y casos prácticos para mejorar tu programación.

Aprende C y certifícate

Bucle while

El control iterativo es fundamental en la programación para ejecutar un bloque de código repetidamente. En C, el bucle while es una de las estructuras más básicas para implementar iteraciones.

Un bucle while ejecuta un bloque de código mientras una condición específica sea verdadera. La sintaxis del bucle while es sencilla:

while (condicion) {
    // Bloque de código que se ejecuta
    // mientras la condición sea verdadera
}

La condición es una expresión que se evalúa antes de cada iteración. Si la condición es verdadera (cualquier valor distinto de cero), el bloque de código dentro del bucle se ejecuta. Después de cada ejecución, la condición se evalúa nuevamente. Este proceso continúa hasta que la condición se vuelve falsa (cero).

Funcionamiento del bucle while

Veamos un ejemplo sencillo que muestra cómo funciona un bucle while:

#include <stdio.h>

int main() {
    int contador = 1;
    
    while (contador <= 5) {
        printf("Iteración número: %d\n", contador);
        contador++; // Incrementamos el contador
    }
    
    printf("Bucle finalizado\n");
    
    return 0;
}

En este ejemplo:

  1. Inicializamos la variable contador con el valor 1
  2. El bucle while verifica si contador es menor o igual a 5
  3. Si la condición es verdadera, imprime el valor actual y luego incrementa el contador
  4. Este proceso se repite hasta que contador llega a 6, momento en el que la condición se vuelve falsa

La salida del programa sería:

Iteración número: 1
Iteración número: 2
Iteración número: 3
Iteración número: 4
Iteración número: 5
Bucle finalizado

Componentes importantes

Para usar correctamente un bucle while, debemos considerar tres elementos clave:

  • Inicialización: Establecer valores iniciales antes del bucle
  • Condición: Expresión que determina si el bucle continúa
  • Actualización: Modificar variables dentro del bucle para eventualmente terminar la iteración

Si olvidamos la actualización, podríamos crear un bucle infinito:

int contador = 1;
    
while (contador <= 5) {
    printf("Esto se imprimirá infinitamente\n");
    // Falta contador++, por lo que la condición siempre será verdadera
}

Variante: bucle do-while

C también ofrece una variante llamada do-while, que garantiza que el bloque de código se ejecute al menos una vez antes de evaluar la condición:

do {
    // Bloque de código
    // Se ejecuta al menos una vez
} while (condicion);

Veamos un ejemplo práctico:

#include <stdio.h>

int main() {
    int numero = 10;
    
    do {
        printf("El valor es: %d\n", numero);
        numero -= 2;
    } while (numero > 0);
    
    printf("Bucle finalizado\n");
    
    return 0;
}

Este programa imprimirá:

El valor es: 10
El valor es: 8
El valor es: 6
El valor es: 4
El valor es: 2
Bucle finalizado

La diferencia clave es que en un bucle do-while, el bloque de código se ejecuta primero y luego se evalúa la condición.

Casos de uso prácticos

El bucle while es especialmente útil en situaciones donde:

  • No conocemos de antemano el número exacto de iteraciones
  • Necesitamos continuar hasta que se cumpla una condición específica
  • Procesamos entrada de usuario hasta recibir un valor determinado

Veamos un ejemplo que lee números hasta que el usuario introduce un cero:

#include <stdio.h>

int main() {
    int numero;
    int suma = 0;
    
    printf("Introduce números (0 para terminar):\n");
    
    // Leemos el primer número
    scanf("%d", &numero);
    
    while (numero != 0) {
        suma += numero;
        printf("Introduce otro número (0 para terminar): ");
        scanf("%d", &numero);
    }
    
    printf("La suma total es: %d\n", suma);
    
    return 0;
}

Este programa suma todos los números introducidos hasta que el usuario ingresa un 0.

Control de flujo dentro del bucle

Dentro de un bucle while, podemos usar las instrucciones break y continue para controlar el flujo:

  • break: Sale inmediatamente del bucle
  • continue: Salta a la siguiente iteración

Ejemplo con break:

#include <stdio.h>

int main() {
    int i = 1;
    
    while (i <= 10) {
        printf("%d ", i);
        
        if (i == 5) {
            printf("\nEncontrado el 5, saliendo del bucle\n");
            break; // Sale del bucle cuando i es 5
        }
        
        i++;
    }
    
    return 0;
}

Salida:

1 2 3 4 5 
Encontrado el 5, saliendo del bucle

Ejemplo con continue:

#include <stdio.h>

int main() {
    int i = 0;
    
    while (i < 10) {
        i++;
        
        if (i % 2 == 0) {
            continue; // Salta el resto del bucle si i es par
        }
        
        printf("%d ", i); // Solo imprime números impares
    }
    
    return 0;
}

Salida:

1 3 5 7 9

Bucles anidados

También podemos anidar bucles while para trabajar con estructuras más complejas:

#include <stdio.h>

int main() {
    int fila = 1;
    
    while (fila <= 3) {
        int columna = 1;
        
        while (columna <= 3) {
            printf("(%d,%d) ", fila, columna);
            columna++;
        }
        
        printf("\n");
        fila++;
    }
    
    return 0;
}

Este programa genera una matriz de coordenadas:

(1,1) (1,2) (1,3) 
(2,1) (2,2) (2,3) 
(3,1) (3,2) (3,3) 

Los bucles anidados son útiles para trabajar con datos multidimensionales como matrices o para generar patrones.

Consideraciones de rendimiento

Aunque los bucles while son muy versátiles, debemos tener cuidado con:

  • Bucles infinitos: Siempre asegúrate de que la condición eventualmente se vuelva falsa
  • Condiciones complejas: Las condiciones muy complejas pueden afectar el rendimiento
  • Actualización de variables: Verifica que las variables en la condición se actualicen correctamente

Un bucle while bien diseñado debe tener una condición clara y un mecanismo de actualización que garantice su terminación.

Bucle for

El bucle for es una estructura de control que permite ejecutar un bloque de código un número específico de veces. A diferencia del bucle while, el bucle for está diseñado para situaciones donde conocemos de antemano el número de iteraciones o tenemos un patrón claro de incremento.

La sintaxis del bucle for en C es:

for (inicialización; condición; actualización) {
    // Bloque de código que se ejecuta
    // mientras la condición sea verdadera
}

Este bucle consta de tres partes principales separadas por punto y coma:

  • Inicialización: Se ejecuta una sola vez al principio
  • Condición: Se evalúa antes de cada iteración
  • Actualización: Se ejecuta después de cada iteración

Funcionamiento básico

Veamos un ejemplo sencillo que muestra cómo funciona un bucle for:

#include <stdio.h>

int main() {
    for (int i = 1; i <= 5; i++) {
        printf("Número: %d\n", i);
    }
    
    printf("Bucle finalizado\n");
    
    return 0;
}

En este ejemplo:

  1. Inicializamos la variable i con el valor 1
  2. Verificamos si i es menor o igual a 5
  3. Si la condición es verdadera, ejecutamos el bloque de código
  4. Después de cada iteración, incrementamos i
  5. El proceso continúa hasta que i llega a 6

La salida del programa sería:

Número: 1
Número: 2
Número: 3
Número: 4
Número: 5
Bucle finalizado

Componentes del bucle for

Analicemos cada componente del bucle for con más detalle:

  • Inicialización: Puede contener múltiples expresiones separadas por comas, aunque lo más común es inicializar una variable contador.

  • Condición: Es una expresión que se evalúa antes de cada iteración. Si es verdadera (distinta de cero), el bucle continúa; si es falsa (cero), el bucle termina.

  • Actualización: Modifica las variables (generalmente el contador) después de cada iteración. Puede contener múltiples expresiones separadas por comas.

Cada una de estas partes es opcional, aunque normalmente se incluyen todas:

#include <stdio.h>

int main() {
    int i = 1;  // Inicialización fuera del bucle
    
    for (; i <= 5; ) {  // Condición sin inicialización ni actualización
        printf("Valor: %d\n", i);
        i++;  // Actualización dentro del bloque
    }
    
    return 0;
}

Variaciones del bucle for

El bucle for es muy flexible y permite diferentes variaciones:

Múltiples variables

Podemos inicializar y actualizar múltiples variables:

#include <stdio.h>

int main() {
    for (int i = 0, j = 10; i < j; i++, j--) {
        printf("i = %d, j = %d\n", i, j);
    }
    
    return 0;
}

Salida:

i = 0, j = 10
i = 1, j = 9
i = 2, j = 8
i = 3, j = 7
i = 4, j = 6

Incrementos diferentes

No estamos limitados a incrementar de uno en uno:

#include <stdio.h>

int main() {
    printf("Números pares del 0 al 10:\n");
    
    for (int i = 0; i <= 10; i += 2) {
        printf("%d ", i);
    }
    
    return 0;
}

Salida:

Números pares del 0 al 10:
0 2 4 6 8 10

Bucle for descendente

También podemos contar hacia atrás:

#include <stdio.h>

int main() {
    printf("Cuenta regresiva:\n");
    
    for (int i = 10; i > 0; i--) {
        printf("%d... ", i);
    }
    
    printf("¡Despegue!\n");
    
    return 0;
}

Salida:

Cuenta regresiva:
10... 9... 8... 7... 6... 5... 4... 3... 2... 1... ¡Despegue!

Bucles for anidados

Al igual que con los bucles while, podemos anidar bucles for para trabajar con estructuras más complejas:

#include <stdio.h>

int main() {
    int filas = 3;
    int columnas = 4;
    
    printf("Tabla de multiplicar %dx%d:\n", filas, columnas);
    
    for (int i = 1; i <= filas; i++) {
        for (int j = 1; j <= columnas; j++) {
            printf("%2d ", i * j);
        }
        printf("\n");
    }
    
    return 0;
}

Salida:

Tabla de multiplicar 3x4:
 1  2  3  4 
 2  4  6  8 
 3  6  9 12 

Los bucles anidados son especialmente útiles para:

  • Procesar matrices y arrays multidimensionales
  • Generar patrones y figuras
  • Resolver problemas que requieren comparar cada elemento con todos los demás

Control de flujo dentro del bucle for

Al igual que en el bucle while, podemos usar las instrucciones break y continue para controlar el flujo:

#include <stdio.h>

int main() {
    for (int i = 1; i <= 10; i++) {
        // Saltamos los múltiplos de 3
        if (i % 3 == 0) {
            continue;
        }
        
        printf("%d ", i);
        
        // Terminamos al llegar a 7
        if (i == 7) {
            printf("\nEncontrado el 7, saliendo del bucle");
            break;
        }
    }
    
    return 0;
}

Salida:

1 2 4 5 7 
Encontrado el 7, saliendo del bucle

Bucle for infinito

Aunque no es una práctica recomendada, a veces necesitamos crear un bucle infinito intencionalmente:

#include <stdio.h>
#include <stdlib.h>

int main() {
    for (;;) {
        printf("Este es un bucle infinito\n");
        printf("Presiona Ctrl+C para salir\n");
        
        // En un programa real, aquí habría una condición de salida
        break;  // Añadido para evitar un bucle realmente infinito en este ejemplo
    }
    
    return 0;
}

En un bucle for infinito, omitimos todas las expresiones, dejando solo los punto y coma. En aplicaciones reales, estos bucles suelen incluir una condición de salida dentro del bloque (como un break basado en alguna condición).

Ejemplos prácticos

Cálculo de factorial

#include <stdio.h>

int main() {
    int numero = 5;
    int factorial = 1;
    
    for (int i = 1; i <= numero; i++) {
        factorial *= i;
    }
    
    printf("El factorial de %d es %d\n", numero, factorial);
    
    return 0;
}

Salida:

El factorial de 5 es 120

Dibujar un triángulo con asteriscos

#include <stdio.h>

int main() {
    int altura = 5;
    
    for (int i = 1; i <= altura; i++) {
        // Imprimir espacios
        for (int j = 1; j <= altura - i; j++) {
            printf(" ");
        }
        
        // Imprimir asteriscos
        for (int k = 1; k <= 2 * i - 1; k++) {
            printf("*");
        }
        
        printf("\n");
    }
    
    return 0;
}

Salida:

    *
   ***
  *****
 *******
*********

Verificar si un número es primo

#include <stdio.h>
#include <stdbool.h>

int main() {
    int numero = 17;
    bool es_primo = true;
    
    if (numero <= 1) {
        es_primo = false;
    } else {
        for (int i = 2; i * i <= numero; i++) {
            if (numero % i == 0) {
                es_primo = false;
                break;
            }
        }
    }
    
    if (es_primo) {
        printf("%d es un número primo\n", numero);
    } else {
        printf("%d no es un número primo\n", numero);
    }
    
    return 0;
}

Salida:

17 es un número primo

Ámbito de las variables en el bucle for

En C99 y versiones posteriores, podemos declarar variables dentro de la inicialización del bucle for. Estas variables solo existen dentro del ámbito del bucle:

#include <stdio.h>

int main() {
    // La variable i solo existe dentro del bucle
    for (int i = 0; i < 5; i++) {
        printf("Dentro del bucle: i = %d\n", i);
    }
    
    // Esto causaría un error de compilación:
    // printf("Fuera del bucle: i = %d\n", i);
    
    return 0;
}

Esta característica ayuda a evitar conflictos de nombres y hace que el código sea más limpio y seguro.

Cuándo usar cada uno

Elegir entre un bucle while y un bucle for es una decisión importante que afecta la legibilidad y eficiencia de tu código. Aunque ambos pueden resolver los mismos problemas, cada uno tiene situaciones donde resulta más apropiado.

Usa bucle while cuando:

  • Desconoces el número de iteraciones de antemano. El bucle while es ideal cuando la condición de terminación depende de factores que no puedes predecir al inicio del programa:
#include <stdio.h>

int main() {
    int numero;
    
    printf("Introduce un número positivo: ");
    scanf("%d", &numero);
    
    while (numero > 0) {
        printf("%d ", numero);
        numero /= 2; // Dividimos por 2 en cada iteración
    }
    
    return 0;
}
  • Necesitas validar entrada de usuario hasta que sea correcta:
#include <stdio.h>

int main() {
    int opcion = 0;
    
    while (opcion < 1 || opcion > 3) {
        printf("Selecciona una opción (1-3): ");
        scanf("%d", &opcion);
        
        if (opcion < 1 || opcion > 3) {
            printf("Opción no válida. Inténtalo de nuevo.\n");
        }
    }
    
    printf("Seleccionaste la opción %d\n", opcion);
    
    return 0;
}
  • La condición debe evaluarse al principio y podría no ejecutarse ninguna vez:
#include <stdio.h>

int main() {
    int valor = 10;
    
    // Si valor es negativo, el bucle no se ejecuta
    while (valor < 0) {
        printf("Este código nunca se ejecutará si valor es 10\n");
        valor--;
    }
    
    return 0;
}
  • Prefieres separar la inicialización, condición y actualización para mayor claridad o cuando necesitas usar las variables fuera del bucle:
#include <stdio.h>

int main() {
    int contador = 0;
    int suma = 0;
    
    while (contador < 5) {
        suma += contador;
        contador++;
    }
    
    printf("Suma: %d, Contador final: %d\n", suma, contador);
    
    return 0;
}

Usa bucle do-while cuando:

  • Necesitas ejecutar el código al menos una vez independientemente de la condición:
#include <stdio.h>

int main() {
    int opcion;
    
    do {
        printf("\nMenú Principal\n");
        printf("1. Ver datos\n");
        printf("2. Modificar datos\n");
        printf("3. Salir\n");
        printf("Selecciona una opción: ");
        scanf("%d", &opcion);
        
        // Procesar la opción...
        
    } while (opcion != 3);
    
    return 0;
}
  • Quieres validar entrada asegurándote de que el usuario introduce al menos un valor:
#include <stdio.h>

int main() {
    int numero;
    
    do {
        printf("Introduce un número positivo: ");
        scanf("%d", &numero);
        
        if (numero <= 0) {
            printf("Error: El número debe ser positivo.\n");
        }
    } while (numero <= 0);
    
    printf("Has introducido: %d\n", numero);
    
    return 0;
}

Usa bucle for cuando:

  • Conoces exactamente cuántas iteraciones necesitas:
#include <stdio.h>

int main() {
    // Imprimir los primeros 5 números
    for (int i = 1; i <= 5; i++) {
        printf("%d ", i);
    }
    
    return 0;
}
  • Trabajas con secuencias o rangos definidos:
#include <stdio.h>

int main() {
    // Imprimir números pares del 2 al 10
    for (int i = 2; i <= 10; i += 2) {
        printf("%d ", i);
    }
    
    return 0;
}
  • Recorres estructuras de datos como arrays:
#include <stdio.h>

int main() {
    int numeros[5] = {10, 20, 30, 40, 50};
    int suma = 0;
    
    for (int i = 0; i < 5; i++) {
        suma += numeros[i];
    }
    
    printf("La suma es: %d\n", suma);
    
    return 0;
}
  • Necesitas inicializar múltiples variables o realizar múltiples actualizaciones en cada iteración:
#include <stdio.h>

int main() {
    for (int i = 0, j = 10; i <= j; i++, j--) {
        printf("i = %d, j = %d\n", i, j);
    }
    
    return 0;
}

Comparación directa con ejemplos

Para ilustrar mejor las diferencias, veamos el mismo problema resuelto con ambos tipos de bucles:

Problema: Sumar los números del 1 al 5.

Solución con while:

#include <stdio.h>

int main() {
    int i = 1;
    int suma = 0;
    
    while (i <= 5) {
        suma += i;
        i++;
    }
    
    printf("La suma es: %d\n", suma);
    
    return 0;
}

Solución con for:

#include <stdio.h>

int main() {
    int suma = 0;
    
    for (int i = 1; i <= 5; i++) {
        suma += i;
    }
    
    printf("La suma es: %d\n", suma);
    
    return 0;
}

Consideraciones de rendimiento

En términos de rendimiento, no hay diferencias significativas entre for y while en C. El compilador genera código máquina similar para ambos. La elección debe basarse en la claridad y legibilidad del código, no en consideraciones de velocidad.

Reglas prácticas para decidir

Para elegir el bucle más adecuado, puedes seguir estas reglas prácticas:

  1. Si conoces el número exacto de iteraciones → usa for
  2. Si la iteración depende de una condición impredecible → usa while
  3. Si necesitas ejecutar el código al menos una vez → usa do-while
  4. Si necesitas acceder al contador fuera del bucle → considera while
  5. Si el bucle tiene una estructura clara de inicialización, condición y actualización → usa for

Casos especiales

  • Bucles infinitos: Aunque pueden implementarse con ambos, la forma más clara es:
// Con for
for (;;) {
    // Código que se ejecuta indefinidamente
    // Debe incluir una condición de salida con break
}

// Con while
while (1) {
    // Código que se ejecuta indefinidamente
    // Debe incluir una condición de salida con break
}
  • Bucles sin cuerpo: Cuando toda la lógica está en la condición o actualización:
// Con for (más claro en este caso)
for (int i = 0; i < 10; i++);  // No hace nada, solo incrementa i

// Con while (menos claro)
int i = 0;
while (i++ < 10);  // Equivalente pero menos explícito

Convertibilidad entre bucles

Es importante recordar que cualquier bucle for puede reescribirse como un bucle while y viceversa. La elección depende principalmente de la claridad y las convenciones del proyecto:

// Estos dos bucles son funcionalmente idénticos
for (int i = 0; i < 5; i++) {
    printf("%d ", i);
}

int i = 0;
while (i < 5) {
    printf("%d ", i);
    i++;
}

Recomendaciones finales

  • Consistencia: Mantén un estilo coherente en todo tu código
  • Simplicidad: Elige el bucle que haga tu código más fácil de entender
  • Contexto: Considera las convenciones del proyecto o equipo
  • Legibilidad: Prioriza la claridad sobre la brevedad

Elegir el bucle correcto no solo hace que tu código sea más legible, sino que también comunica mejor tus intenciones a otros programadores que puedan leer o mantener tu código en el futuro.

CONSTRUYE TU CARRERA EN IA Y PROGRAMACIÓN SOFTWARE

Accede a +1000 lecciones y cursos con certificado. Mejora tu portfolio con certificados de superación para tu CV.

30 % DE DESCUENTO

Plan mensual

19.00 /mes

13.30 € /mes

Precio normal mensual: 19 €
63 % DE DESCUENTO

Plan anual

10.00 /mes

7.00 € /mes

Ahorras 144 € al año
Precio normal anual: 120 €
Aprende C online

Todas las lecciones de C

Accede a todas las lecciones de C y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Accede GRATIS a C y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  • Comprender la sintaxis y funcionamiento básico del bucle while.
  • Aprender a usar el bucle do-while y sus diferencias con while.
  • Conocer la estructura y variantes del bucle for.
  • Saber cuándo utilizar cada tipo de bucle según el contexto.
  • Aplicar control de flujo dentro de bucles con break y continue.