Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Regla 0x1003h: Utilizá el lazo for para iteraciones con rango o contador definido y while para lazos controlados por condiciones lógicas

Estructuras de control y flujo (0x10XX)

Universidad Nacional de Río Negro

0x1003h: Utilizá el lazo for para iteraciones con rango o contador definido y while para lazos controlados por condiciones lógicas

Enunciado normativo

DEBE usarse el lazo for cuando la cantidad de iteraciones sea conocida de antemano o esté gobernada por un contador o rango. DEBE reservarse el lazo while para iteraciones cuya condición sea puramente lógica o se conozca recién en tiempo de ejecución.

¿Por qué existe esta regla?

El problema

Cada lazo comunica una intención. El for dice “recorro un rango conocido” y reúne inicialización, cota e incremento en una sola línea; el lector ve todo el contrato de una vez. El while dice “repito mientras se cumpla una condición” y separa el avance del encabezado, porque el avance puede depender del cuerpo.

Usar el lazo equivocado esconde esa intención. Un for con condición compuesta o con cláusulas vacías es un while disfrazado; un while que cuenta iteraciones obliga a buscar el incremento dentro del cuerpo y es la causa habitual del lazo infinito por olvido.

Consecuencias de violarla

Tipo de consecuenciaEfecto concreto
Lazo infinitowhile de conteo al que se le olvida el incremento.
LegibilidadNo se distingue a simple vista si el lazo recorre un rango o espera un evento.
MantenibilidadCambiar la cota obliga a ubicar y tocar el cuerpo, no el encabezado.
Bug lógicoUn for con condición compuesta oculta varias condiciones de corte.

Fundamento en el estándar y en la cátedra

ISO/IEC 9899:2011 §6.8.5.3 describe el for como azúcar sintáctico de un while; son equivalentes en poder expresivo. La cátedra elige uno u otro por su valor comunicativo: for para conteos acotados, while para condiciones. Se alinea con 0x100Dh: Prohibición de condiciones de parada compuestas complejas en lazos for, que prohíbe cotas compuestas en el for.

Alcance y excepciones

Ejemplos exhaustivos

❌ Contraejemplo 1 — for para una condición lógica

for (int n = leer(); n != 0; n = leer())
{
    procesar(n);
}

Por qué falla: no hay contador ni rango; la cantidad de iteraciones se decide por el valor leído. El for fuerza a duplicar la lectura en la inicialización y en el incremento, y si el paso cambia hay que tocar dos lugares.

❌ Contraejemplo 2 — while usado para contar

int i = 0;
while (i < cantidad)
{
    total += valores[i];
}

Por qué falla: falta i++. El lazo nunca termina y accede siempre a valores[0]. El for habría impedido esa omisión porque el incremento es obligatorio en la sintaxis.

✅ Ejemplo conforme 1 — for para recorrer un rango

for (size_t i = 0; i < cantidad; i++)
{
    total += valores[i];
}

Inicialización, cota e incremento viven juntos; el recorrido se lee completo en el encabezado y no hay forma de olvidar el avance.

✅ Ejemplo conforme 2 — while para leer hasta centinela

int n = leer();
while (n != 0)
{
    procesar(n);
    n = leer();
}

La condición depende del dato leído, no de un contador; el while es la elección idiomática. El avance está en el cuerpo porque la lectura es la operación que define el corte.

⚠️ Casos límite

Cómo detectarla

HerramientaComandoSeñal
gaffgaff check archivo.cRegla 0x1003h: elección de lazo.
Revisión manualfor con condición compuesta o while sin avance.
gccgcc -Wall -Wextra -O2warning de variable puede quedar sin cambiar.

Checklist de autocontrol

Reglas relacionadas

Antipatrón: Modificación de variable de control dentro del cuerpo del for

Síntoma en el código del estudiante

El cuerpo del for altera la variable de control, que ya se modifica en el incremento del encabezado:

for (int i = 0; i < n; i++)
{
    if (condicion)
    {
        i += 2;
    }
}

Diagnóstico

Mecanismo del defecto

El for reserva la modificación del contador para su cláusula de incremento. Cuando el cuerpo también la modifica, hay dos dueños del avance: el lector no puede calcular cuántas iteraciones habrá mirando el encabezado, y una misma ejecución puede saltar pasos o retroceder sin que se vea.

Consecuencia observable

El número de iteraciones deja de estar determinado por i < n. Aparecen comportamientos tipo “recorrió la mitad” o “se pasó del límite”, y el acceso a valores[i] puede salirse del arreglo. El lazo se vuelve difícil de razonar y de probar.

Fundamento en el estándar C11

ISO/IEC 9899:2011 §6.8.5.3 permite modificar cualquier variable dentro del cuerpo, incluida la de control; la restricción es de diseño. La cátedra exige que el avance regular quede en el encabezado. Cuando el avance depende de condiciones dinámicas, la estructura adecuada es el while, donde el contador es parte de la lógica (regla 0x1003h).

Corrección idiomática

❌ Código con el antipatrón
for (int i = 0; i < n; i++)
{
    if (condicion)
    {
        i += 2;
    }
    procesar(valores[i]);
}
✅ Código refactorizado
int i = 0;
while (i < n)
{
    if (condicion)
    {
        i += 2;
    }
    else
    {
        i++;
    }
    procesar(valores[i]);
}

El while deja el avance en el cuerpo, que es donde realmente se decide. Ahora el lector sigue todos los cambios del contador en un mismo lugar.

Errores típicos al compilar o ejecutar

No hay error de compilación. El lazo puede:
- saltear elementos sin procesar,
- saltar el último índice,
- acceder a valores[i] con i >= n si el salto cruza la cota.

Con -fsanitize=address puede reportar stack-buffer-overflow en el acceso.

Checklist de verificación

Reglas relacionadas