Bucles en C — 3 programas reales con for, while y do…while
Los bucles en C práctica real es lo que toca ahora. En el artículo anterior vimos la teoría de for, while y do...while. Ahora abre gedit en Fedora y escribe el código mientras lees. Tres programas progresivos, cada uno usa el bucle más apropiado para su caso.
Recuerda el flujo:
gedit programa.c & gcc programa.c -o programa ./programa
Tabla de Contenidos
Bucles en C práctica — Programa 1: Validador de datos con do…while
Este es el caso de uso perfecto del do...while — siempre necesitas pedir al menos un dato antes de validarlo. Crea el archivo:
gedit validador.c &
#include <stdio.h>
int main() {
float nota;
int edad;
char opcion;
/* Validar nota con do...while */
printf("=== VALIDADOR DE DATOS ===\n\n");
do {
printf("Introduce una nota (0-10): ");
scanf("%f", ¬a);
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\n", nota);
/* Validar edad con do...while */
do {
printf("Introduce tu edad (0-120): ");
scanf("%d", &edad);
if (edad < 0 || edad > 120) {
printf("Error: edad fuera de rango\n");
}
} while (edad < 0 || edad > 120);
printf("Edad válida: %d\n\n", edad);
/* Validar opción s/n con do...while */
do {
printf("¿Confirmas los datos? (s/n): ");
scanf(" %c", &opcion);
if (opcion != 's' && opcion != 'n') {
printf("Error: introduce s o n\n");
}
} while (opcion != 's' && opcion != 'n');
if (opcion == 's') {
printf("\n✓ Datos confirmados\n");
printf("Nota: %.2f | Edad: %d\n", nota, edad);
} else {
printf("\n✗ Datos cancelados\n");
}
return 0;
}
Salida con entradas incorrectas y luego correctas:
=== VALIDADOR DE DATOS === Introduce una nota (0-10): -5 Error: la nota debe estar entre 0 y 10 Introduce una nota (0-10): 15 Error: la nota debe estar entre 0 y 10 Introduce una nota (0-10): 7.5 Nota válida: 7.50 Introduce tu edad (0-120): 150 Error: edad fuera de rango Introduce tu edad (0-120): 22 Edad válida: 22 ¿Confirmas los datos? (s/n): x Error: introduce s o n ¿Confirmas los datos? (s/n): s ✓ Datos confirmados Nota: 7.50 | Edad: 22
Fíjate en el patrón que se repite en los tres validadores, siempre es el mismo:
do {
/* 1. pedir dato */
/* 2. validar y avisar si es incorrecto */
} while (/* condición de dato incorrecto */);
Es el patrón más usado para cualquier entrada de datos. Memorízalo.
Bucles en C práctica — Programa 2: Calculadora de series numéricas
Este programa usa for para calcular series matemáticas, suma acumulada, factorial y números de Fibonacci.
gedit series.c &
#include <stdio.h>
int main() {
int n, i;
long suma, factorial;
int fib_anterior, fib_actual, fib_siguiente;
printf("=== CALCULADORA DE SERIES ===\n\n");
/* Pedir n con validación */
do {
printf("Introduce n (1-15): ");
scanf("%d", &n);
if (n < 1 || n > 15) {
printf("Error: n debe estar entre 1 y 15\n");
}
} while (n < 1 || n > 15);
/* Serie 1 — Suma acumulada: 1+2+3+...+n */
suma = 0;
for (i = 1; i <= n; i++) {
suma += i;
}
printf("\nSuma 1 a %d: %ld\n", n, suma);
printf("Fórmula: n*(n+1)/2 = %d\n", n*(n+1)/2);
/* Serie 2 — Factorial: n! */
factorial = 1;
for (i = 1; i <= n; i++) {
factorial *= i;
}
printf("\n%d! = %ld\n", n, factorial);
/* Serie 3 — Fibonacci hasta n términos */
printf("\nFibonacci (%d términos): ", n);
fib_anterior = 0;
fib_actual = 1;
printf("%d %d ", fib_anterior, fib_actual);
for (i = 2; i < n; i++) {
fib_siguiente = fib_anterior + fib_actual;
printf("%d ", fib_siguiente);
fib_anterior = fib_actual;
fib_actual = fib_siguiente;
}
printf("\n");
/* Serie 4 — Tabla de potencias */
printf("\nTabla de potencias de 2:\n");
long potencia = 1;
for (i = 0; i <= n; i++) {
printf("2^%2d = %ld\n", i, potencia);
potencia *= 2;
}
return 0;
}
Salida con n=6:
=== CALCULADORA DE SERIES === Introduce n (1-15): 6 Suma 1 a 6: 21 Fórmula: n*(n+1)/2 = 21 6! = 720 Fibonacci (6 términos): 0 1 1 2 3 5 Tabla de potencias de 2: 2^ 0 = 1 2^ 1 = 2 2^ 2 = 4 2^ 3 = 8 2^ 4 = 16 2^ 5 = 32 2^ 6 = 64
Tres cosas importantes de este programa:
Primero — usamos long para la suma y el factorial porque los valores crecen rápido. Con int el factorial de 15 da desbordamiento.
Segundo — combinamos do...while para la validación y for para los cálculos. Cada bucle en el lugar correcto.
Tercero — Fibonacci requiere tres variables — anterior, actual y siguiente. Es el patrón clásico de actualización dentro de un bucle.
Bucles en C práctica — Programa 3: Juego de adivinar el número con reintentos
En el artículo de condicionales hicimos la versión con un solo intento. Ahora con while podemos hacer la versión completa, el jugador tiene intentos ilimitados hasta acertar, con pistas en cada intento.
gedit adivina_completo.c &
#include <stdio.h>
int main() {
int secreto = 42;
int intento;
int intentos = 0;
int acertado = 0;
int diferencia;
printf("=== ADIVINA EL NÚMERO ===\n");
printf("Tengo un número entre 1 y 100\n");
printf("¡Tienes intentos ilimitados!\n\n");
while (!acertado) {
printf("Intento %d — Tu número: ", intentos + 1);
scanf("%d", &intento);
intentos++;
/* Calcular diferencia */
if (intento > secreto) {
diferencia = intento - secreto;
} else {
diferencia = secreto - intento;
}
/* Resultado del intento */
if (intento == secreto) {
acertado = 1;
} else if (intento > secreto) {
printf("Demasiado alto — ");
} else {
printf("Demasiado bajo — ");
}
/* Pista de proximidad */
if (!acertado) {
if (diferencia <= 3) {
printf("¡Muy cerca!\n");
} else if (diferencia <= 10) {
printf("Cerca\n");
} else if (diferencia <= 25) {
printf("Lejos\n");
} else {
printf("Muy lejos\n");
}
}
}
/* Resultado final */
printf("\n✓ ¡Correcto! El número era %d\n", secreto);
printf("Lo conseguiste en %d intento/s\n\n", intentos);
/* Puntuación */
printf("Puntuación: ");
if (intentos == 1) {
printf("¡Increíble! Adivinaste a la primera\n");
} else if (intentos <= 3) {
printf("Excelente — menos de 4 intentos\n");
} else if (intentos <= 7) {
printf("Bien — menos de 8 intentos\n");
} else {
printf("Puedes mejorar — %d intentos\n", intentos);
}
return 0;
}
Salida de una partida:
=== ADIVINA EL NÚMERO === Tengo un número entre 1 y 100 ¡Tienes intentos ilimitados! Intento 1 — Tu número: 50 Demasiado alto — Cerca Intento 2 — Tu número: 25 Demasiado bajo — Lejos Intento 3 — Tu número: 37 Demasiado bajo — Cerca Intento 4 — Tu número: 44 Demasiado alto — ¡Muy cerca! Intento 5 — Tu número: 42 ✓ ¡Correcto! El número era 42 Lo conseguiste en 5 intento/s Puntuación: Bien — menos de 8 intentos
Fíjate en el patrón del while aquí:
int acertado = 0; /* flag de control */
while (!acertado) { /* mientras NO acertado */
/* ... lógica del juego ... */
if (intento == secreto) {
acertado = 1; /* cambia el flag para salir */
}
}
Este patrón de flag de control es muy común, una variable entera que actúa como booleano para controlar cuándo sale el bucle. !acertado es equivalente a acertado == 0.
El patrón que debes llevarte
De los tres programas hay tres patrones distintos que debes interiorizar:
/* PATRÓN 1 — do...while para validación */
do {
printf("Pide dato: ");
scanf("...", &dato);
} while (/* dato no válido */);
/* PATRÓN 2 — for para series con n conocido */
acumulado = valor_inicial;
for (i = 1; i <= n; i++) {
acumulado = operacion(acumulado, i);
}
/* PATRÓN 3 — while con flag para condición variable */
int encontrado = 0;
while (!encontrado) {
/* lógica */
if (condicion_salida) {
encontrado = 1;
}
}
Visualízalo con Python Tutor
Copia este código en pythontutor.com seleccionando C:
#include <stdio.h>
int main() {
int i;
long factorial = 1;
for (i = 1; i <= 5; i++) {
factorial *= i;
printf("%d! = %ld\n", i, factorial);
}
return 0;
}
Observa cómo factorial se multiplica acumulativamente en cada iteración y cómo i avanza paso a paso.
Errores más comunes en estos programas
Error 1 — Condición invertida en do…while:
/* MAL — condición imposible */
do {
scanf("%f", ¬a);
} while (nota < 0 && nota > 10); /* nunca puede ser las dos */
/* BIEN */
} while (nota < 0 || nota > 10);
Error 2 — No inicializar el acumulador:
long factorial; /* contiene basura */
for (i = 1; i <= n; i++) {
factorial *= i; /* multiplica basura */
}
long factorial = 1; /* correcto */
Error 3 — Punto y coma después del while:
while (!acertado); /* bucle vacío infinito */
{
/* nunca se ejecuta */
}
Resumen y siguiente paso
En este artículo practicaste los tres bucles con programas reales. El patrón de do...while para validación, el for para series acumulativas y el while con flag para condiciones variables son los tres que más aparecen en IC2.
En el siguiente artículo encontrarás ejercicios propuestos con solución para practicar por tu cuenta.
Loops in C — 3 real programs with for, while and do…while
In the previous article we covered for, while and do…while theory. Now open gedit on Fedora and write the code as you read. Three progressive programs, each uses the most appropriate loop for its case.
Program 1 — Data validator with do…while
#include <stdio.h>
int main() {
float grade;
int age;
char option;
printf("=== DATA VALIDATOR ===\n\n");
do {
printf("Enter a grade (0-10): ");
scanf("%f", &grade);
if (grade < 0 || grade > 10) {
printf("Error: grade must be between 0 and 10\n");
}
} while (grade < 0 || grade > 10);
printf("Valid grade: %.2f\n\n", grade);
do {
printf("Enter your age (0-120): ");
scanf("%d", &age);
if (age < 0 || age > 120) {
printf("Error: age out of range\n");
}
} while (age < 0 || age > 120);
printf("Valid age: %d\n\n", age);
do {
printf("Confirm data? (y/n): ");
scanf(" %c", &option);
if (option != 'y' && option != 'n') {
printf("Error: enter y or n\n");
}
} while (option != 'y' && option != 'n');
if (option == 'y') {
printf("\n✓ Data confirmed\n");
printf("Grade: %.2f | Age: %d\n", grade, age);
} else {
printf("\n✗ Data cancelled\n");
}
return 0;
}
Expected output:
=== DATA VALIDATOR === Enter a grade (0-10): -5 Error: grade must be between 0 and 10 Enter a grade (0-10): 7.5 Valid grade: 7.50 Enter your age (0-120): 150 Error: age out of range Enter your age (0-120): 22 Valid age: 22 Confirm data? (y/n): x Error: enter y or n Confirm data? (y/n): y ✓ Data confirmed Grade: 7.50 | Age: 22
The repeating pattern, memorise it:
do {
/* 1. ask for data */
/* 2. validate and warn if wrong */
} while (/* data is invalid */);
Program 2 — Numeric series calculator
#include <stdio.h>
int main() {
int n, i;
long sum, factorial;
int fib_prev, fib_curr, fib_next;
printf("=== SERIES CALCULATOR ===\n\n");
do {
printf("Enter n (1-15): ");
scanf("%d", &n);
if (n < 1 || n > 15) {
printf("Error: n must be between 1 and 15\n");
}
} while (n < 1 || n > 15);
/* Sum 1+2+...+n */
sum = 0;
for (i = 1; i <= n; i++) {
sum += i;
}
printf("\nSum 1 to %d: %ld\n", n, sum);
printf("Formula: n*(n+1)/2 = %d\n", n*(n+1)/2);
/* Factorial n! */
factorial = 1;
for (i = 1; i <= n; i++) {
factorial *= i;
}
printf("\n%d! = %ld\n", n, factorial);
/* Fibonacci */
printf("\nFibonacci (%d terms): ", n);
fib_prev = 0;
fib_curr = 1;
printf("%d %d ", fib_prev, fib_curr);
for (i = 2; i < n; i++) {
fib_next = fib_prev + fib_curr;
printf("%d ", fib_next);
fib_prev = fib_curr;
fib_curr = fib_next;
}
printf("\n");
/* Powers of 2 */
printf("\nPowers of 2:\n");
long power = 1;
for (i = 0; i <= n; i++) {
printf("2^%2d = %ld\n", i, power);
power *= 2;
}
return 0;
}
Expected output with n=6:
=== SERIES CALCULATOR === Enter n (1-15): 6 Sum 1 to 6: 21 Formula: n*(n+1)/2 = 21 6! = 720 Fibonacci (6 terms): 0 1 1 2 3 5 Powers of 2: 2^ 0 = 1 2^ 1 = 2 2^ 2 = 4 2^ 3 = 8 2^ 4 = 16 2^ 5 = 32 2^ 6 = 64
Program 3 — Number guessing game with retries
#include <stdio.h>
int main() {
int secret = 42;
int guess, attempts = 0, correct = 0, difference;
printf("=== GUESS THE NUMBER ===\n");
printf("I have a number between 1 and 100\n\n");
while (!correct) {
printf("Attempt %d — Your number: ", attempts + 1);
scanf("%d", &guess);
attempts++;
if (guess > secret) {
difference = guess - secret;
} else {
difference = secret - guess;
}
if (guess == secret) {
correct = 1;
} else if (guess > secret) {
printf("Too high — ");
} else {
printf("Too low — ");
}
if (!correct) {
if (difference <= 3) printf("Very close!\n");
else if (difference <= 10) printf("Close\n");
else if (difference <= 25) printf("Far\n");
else printf("Very far\n");
}
}
printf("\n✓ Correct! The number was %d\n", secret);
printf("You got it in %d attempt/s\n\n", attempts);
printf("Score: ");
if (attempts == 1) printf("Incredible! First try\n");
else if (attempts <= 3) printf("Excellent — under 4 attempts\n");
else if (attempts <= 7) printf("Good — under 8 attempts\n");
else printf("Keep practising — %d attempts\n", attempts);
return 0;
}
Expected output:
=== GUESS THE NUMBER === I have a number between 1 and 100 Attempt 1 — Your number: 50 Too high — Close Attempt 2 — Your number: 25 Too low — Far Attempt 3 — Your number: 42 ✓ Correct! The number was 42 You got it in 3 attempt/s Score: Excellent — under 4 attempts
The three patterns to take away
/* PATTERN 1 — do...while for validation */
do {
printf("Enter data: ");
scanf("...", &data);
} while (/* data invalid */);
/* PATTERN 2 — for for series with known n */
accumulator = initial_value;
for (i = 1; i <= n; i++) {
accumulator = operation(accumulator, i);
}
/* PATTERN 3 — while with flag for variable condition */
int found = 0;
while (!found) {
/* logic */
if (exit_condition) found = 1;
}
Common mistakes
/* Mistake 1 — impossible condition in do...while */ } while (x < 0 && x > 10); /* impossible — use || */ /* Mistake 2 — uninitialised accumulator */ long factorial; /* garbage value */ factorial = 1; /* always initialise */ /* Mistake 3 — semicolon after while */ while (!correct); /* infinite empty loop */
