bucles en C for while guía

Bucles en C — for, while y do…while sin rodeos

Los bucles en C for while y do…while son las estructuras que te permiten repetir código. Si vienes de Python ya conoces for y while, pero en C la sintaxis es muy diferente y hay un tercero que Python no tiene: el do...while.

En este artículo vemos los tres, cuándo usar cada uno y los errores que más aparecen en IC2. Con ejemplos reales en gedit y Fedora.

Si todavía no tienes el entorno configurado sigue la guía de instalar gedit y gcc.

El bucle for en C — la mayor sorpresa viniendo de Python

El for de Python itera sobre secuencias, for x in lista. El for de C es completamente diferente, tiene tres partes separadas por ; dentro de los paréntesis:

for (inicialización; condición; actualización) {
    /* cuerpo del bucle */
}
  • Inicialización — se ejecuta una sola vez al principio
  • Condición — se evalúa antes de cada iteración — si es falsa el bucle termina
  • Actualización — se ejecuta al final de cada iteración

El equivalente en C del for i in range(5) de Python:

/* Python */
for i in range(5):
    print(i)
/* C */
int i;
for (i = 0; i < 5; i++) {
    printf("%d\n", i);
}

Equivalentes a range() de Python en C:

/* range(5) → 0,1,2,3,4 */
for (i = 0; i < 5; i++)

/* range(1, 6) → 1,2,3,4,5 */
for (i = 1; i <= 5; i++)

/* range(0, 10, 2) → 0,2,4,6,8 */
for (i = 0; i < 10; i += 2)

/* range(5, 0, -1) → 5,4,3,2,1 */
for (i = 5; i > 0; i--)

Declaración de la variable de control

En C89 (el estándar que se usa en IC2) la variable del bucle debe declararse antes del for, no dentro:

/* C89 — estándar IC2 */
int i;
for (i = 0; i < 10; i++) { ... }

/* C99 — se puede declarar dentro */
for (int i = 0; i < 10; i++) { ... }

Si gcc te da error al declarar dentro del for, compila con el flag -std=c99:

gcc -std=c99 programa.c -o programa

Ejemplos prácticos del for

#include <stdio.h>

int main() {
    int i;

    /* Tabla de multiplicar del 7 */
    printf("Tabla del 7:\n");
    for (i = 1; i <= 10; i++) {
        printf("7 x %2d = %2d\n", i, 7 * i);
    }

    /* Suma de 1 a 100 */
    int suma = 0;
    for (i = 1; i <= 100; i++) {
        suma += i;
    }
    printf("\nSuma 1-100: %d\n", suma);

    /* Cuenta atrás */
    printf("\nCuenta atrás: ");
    for (i = 10; i >= 1; i--) {
        printf("%d ", i);
    }
    printf("¡Ya!\n");

    return 0;
}

El bucle while

El while en C es muy similar al de Python, evalúa la condición antes de cada iteración y repite mientras sea verdadera:

while (condicion) {
    /* cuerpo */
}

La diferencia con Python es solo sintáctica, paréntesis obligatorios y llaves en vez de indentación:

/* Python */
while x < 10:
    x += 1

/* C */
int x = 0;
while (x < 10) {
    x++;
}

El while es ideal cuando no sabes cuántas iteraciones necesitas:

#include <stdio.h>

int main() {
    int numero, suma = 0, contador = 0;

    printf("Introduce números (0 para terminar):\n");

    scanf("%d", &numero);
    while (numero != 0) {
        suma += numero;
        contador++;
        scanf("%d", &numero);
    }

    if (contador > 0) {
        printf("Suma: %d\n", suma);
        printf("Media: %.2f\n", (float)suma / contador);
    } else {
        printf("No introdujiste ningún número\n");
    }

    return 0;
}

For vs While — cuándo usar cada uno

/* USA for cuando: */
/* - Sabes exactamente cuántas iteraciones necesitas */
/* - Iteras sobre un rango de números */
for (i = 0; i < n; i++) { ... }

/* USA while cuando: */
/* - No sabes cuántas iteraciones necesitas */
/* - La condición depende de entrada del usuario */
/* - Buscas algo en datos */
while (condicion_variable) { ... }

El bucle do…while — el que Python no tiene

El do...while es único en C, ejecuta el cuerpo al menos una vez antes de evaluar la condición:

do {
    /* cuerpo — siempre se ejecuta al menos una vez */
} while (condicion);

Comparado con while:

/* while — puede no ejecutarse nunca */
int x = 10;
while (x < 5) {
    printf("nunca\n");    /* no se ejecuta */
}

/* do...while — siempre ejecuta al menos una vez */
int x = 10;
do {
    printf("al menos una vez\n");    /* se ejecuta aunque x >= 5 */
} while (x < 5);

El caso de uso perfecto del do…while — validación de entrada

El do...while brilla cuando necesitas pedir datos al usuario y validarlos, siempre tienes que pedir al menos una vez:

#include <stdio.h>

int main() {
    float nota;

    /* Pedir nota hasta que sea válida */
    do {
        printf("Introduce una nota (0-10): ");
        scanf("%f", &nota);

        if (nota < 0 || nota > 10) {
            printf("Error: la nota debe estar entre 0 y 10\n");
        }
    } while (nota < 0 || nota > 10);

    printf("Nota válida: %.2f\n", nota);

    return 0;
}
 do...while validando entrada en Fedora

Sin do...while necesitarías una solución más fea:

/* Sin do...while — repetición de código */
printf("Introduce una nota (0-10): ");
scanf("%f", &nota);
while (nota < 0 || nota > 10) {
    printf("Error. Introduce una nota (0-10): ");
    scanf("%f", &nota);
}

Con do...while el código es más limpio y sin repetición.

break y continue — controlar el flujo del bucle

break termina el bucle inmediatamente:

int i;
for (i = 0; i < 10; i++) {
    if (i == 5) {
        break;    /* sale del bucle cuando i vale 5 */
    }
    printf("%d ", i);
}
/* salida: 0 1 2 3 4 */

continue salta al siguiente ciclo sin ejecutar el resto del cuerpo:

int i;
for (i = 0; i < 10; i++) {
    if (i % 2 == 0) {
        continue;    /* salta los pares */
    }
    printf("%d ", i);
}
/* salida: 1 3 5 7 9 */

Bucles anidados

Puedes poner bucles dentro de bucles, muy usado para matrices y tablas:

#include <stdio.h>

int main() {
    int i, j;

    /* Tabla de multiplicar completa */
    for (i = 1; i <= 5; i++) {
        for (j = 1; j <= 5; j++) {
            printf("%4d", i * j);
        }
        printf("\n");
    }

    return 0;
}

Salida:

   1   2   3   4   5
   2   4   6   8  10
   3   6   9  12  15
   4   8  12  16  20
   5  10  15  20  25

Cuando usas break en un bucle anidado solo sale del bucle más interno, no de todos.

El bucle infinito — y cómo salir

Un bucle sin condición de parada es infinito. A veces se hace intencionalmente:

while (1) {       /* condición siempre verdadera */
    /* ... */
    if (condicion_salida) {
        break;    /* única salida */
    }
}

for (;;) {        /* for vacío — también infinito */
    /* ... */
}

Si tu programa se queda colgado en un bucle infinito, pulsa Ctrl+C en la terminal para cancelarlo.

Los errores más comunes en IC2

Error 1 — Punto y coma después del for:

for (i = 0; i < 5; i++);    /* bucle vacío — el ; es el cuerpo */
{
    printf("%d\n", i);       /* se ejecuta solo una vez al final */
}

El ; después del for hace que el bucle sea vacío. Es el error más difícil de ver porque compila sin problemas.

Error 2 — No actualizar la variable en while:

int i = 0;
while (i < 5) {
    printf("%d\n", i);
    /* olvidé i++ → bucle infinito */
}

Error 3 — Condición incorrecta en do…while:

do {
    scanf("%f", &nota);
} while (nota < 0 && nota > 10);    /* nunca puede ser las dos a la vez */
/* correcto: while (nota < 0 || nota > 10) */

Visualízalo con Python Tutor

Copia este código en pythontutor.com seleccionando C:

#include <stdio.h>

int main() {
    int i;
    int suma = 0;

    for (i = 1; i <= 5; i++) {
        suma += i;
        printf("i=%d suma=%d\n", i, suma);
    }

    return 0;
}

Ejecuta paso a paso y observa cómo i se inicializa una vez, la condición se evalúa antes de cada iteración y la actualización i++ ocurre al final de cada ciclo.

Resumen rápido

/* FOR — número fijo de iteraciones */
int i;
for (i = 0; i < n; i++) {
    /* cuerpo */
}

/* WHILE — condición variable */
while (condicion) {
    /* cuerpo */
    /* actualizar variable */
}

/* DO...WHILE — al menos una ejecución */
do {
    /* cuerpo */
} while (condicion);    /* ; obligatorio al final */

/* BREAK — salir del bucle */
if (condicion) break;

/* CONTINUE — saltar al siguiente ciclo */
if (condicion) continue;

/* BUCLE INFINITO */
while (1) { ... }
for (;;) { ... }
/* Ctrl+C para cancelar */

/* ERRORES TÍPICOS */
/* for(i=0;i<5;i++);  → bucle vacío — ; después del for */
/* while sin actualizar variable → bucle infinito */
/* && en vez de || en do...while → condición imposible */

En el próximo artículo practicamos los tres bucles con programas reales, incluyendo la versión completa del juego de adivinar el número con reintentos.


Loops in C — for, while and do…while without complications

C loops are the structures that let you repeat code. If you come from Python you know for and while, but in C the syntax is very different and there’s a third one Python doesn’t have: do...while.

The for loop in C — the biggest surprise from Python

Python’s for iterates over sequences. C’s for has three parts separated by ;:

for (initialisation; condition; update) {
    /* body */
}

Python’s for i in range(5) in C:

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

range() equivalents:

/* range(5) */        for (i = 0; i < 5; i++)
/* range(1, 6) */     for (i = 1; i <= 5; i++)
/* range(0, 10, 2) */ for (i = 0; i < 10; i += 2)
/* range(5, 0, -1) */ for (i = 5; i > 0; i--)

Variable declaration

In C89 (IC2 standard) declare loop variable before the for:

int i;
for (i = 0; i < 10; i++) { ... }    /* C89 */
for (int i = 0; i < 10; i++) { ... } /* C99 — needs -std=c99 flag */

Practical for examples

#include <stdio.h>

int main() {
    int i;

    /* 7 times table */
    for (i = 1; i <= 10; i++) {
        printf("7 x %2d = %2d\n", i, 7 * i);
    }

    /* Sum 1 to 100 */
    int sum = 0;
    for (i = 1; i <= 100; i++) {
        sum += i;
    }
    printf("Sum 1-100: %d\n", sum);

    /* Countdown */
    for (i = 10; i >= 1; i--) {
        printf("%d ", i);
    }
    printf("Go!\n");

    return 0;
}

The while loop

while (condition) {
    /* body */
    /* update variable */
}

Ideal when you don’t know how many iterations you need:

int number, sum = 0, count = 0;
scanf("%d", &number);
while (number != 0) {
    sum += number;
    count++;
    scanf("%d", &number);
}

For vs While

/* USE for: known number of iterations, numeric range */
for (i = 0; i < n; i++) { ... }

/* USE while: unknown iterations, user input dependent */
while (variable_condition) { ... }

The do…while loop — what Python doesn’t have

Executes the body at least once before checking the condition:

do {
    /* always executes at least once */
} while (condition);

Perfect use case — input validation:

float grade;
do {
    printf("Enter a grade (0-10): ");
    scanf("%f", &grade);
    if (grade < 0 || grade > 10) {
        printf("Error: must be between 0 and 10\n");
    }
} while (grade < 0 || grade > 10);

break and continue

/* break — exit loop immediately */
for (i = 0; i < 10; i++) {
    if (i == 5) break;
    printf("%d ", i);    /* 0 1 2 3 4 */
}

/* continue — skip to next iteration */
for (i = 0; i < 10; i++) {
    if (i % 2 == 0) continue;
    printf("%d ", i);    /* 1 3 5 7 9 */
}

Nested loops

int i, j;
for (i = 1; i <= 5; i++) {
    for (j = 1; j <= 5; j++) {
        printf("%4d", i * j);
    }
    printf("\n");
}

Infinite loop

while (1) { ... }    /* always true */
for (;;) { ... }     /* empty for */
/* Press Ctrl+C to cancel */

Common mistakes

/* Mistake 1 — semicolon after for */
for (i = 0; i < 5; i++);    /* empty loop */
{ printf("%d\n", i); }       /* runs once after loop */

/* Mistake 2 — forgetting to update in while */
while (i < 5) {
    printf("%d\n", i);
    /* forgot i++ → infinite loop */
}

/* Mistake 3 — wrong condition in do...while */
do { ... } while (x < 0 && x > 10);    /* impossible */
/* correct: */ while (x < 0 || x > 10);

Quick summary

/* FOR */
int i;
for (i = 0; i < n; i++) { ... }

/* WHILE */
while (condition) { ...; update; }

/* DO...WHILE */
do { ... } while (condition);    /* ; mandatory */

/* BREAK / CONTINUE */
if (cond) break;       /* exit loop */
if (cond) continue;    /* skip to next iteration */

/* COMMON MISTAKES */
/* for(...);  → empty loop */
/* while without update → infinite loop */
/* && instead of || in do...while → impossible condition */

Publicaciones Similares

3 comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *