Sesión 5: Ciclos (iteración) en C#

Cómo repetir sin duplicar código: for, while, contadores y acumuladores

Navegación: | Home End | F pantalla completa

Agenda

¿Qué veremos exactamente?

A partir de esta sesión trabajaremos las soluciones principalmente en C#. El pseudocódigo se usará como apoyo para entender la lógica, pero el entregable será el programa.

Bloque A — Fundamento

  • Qué es iterar y por qué no se “copian y pegan” pasos.
  • Partes de un ciclo: inicialización, condición, bloque y progreso.
  • Errores típicos: ciclo infinito, off-by-one, acumuladores mal ubicados.

Bloque B — Aplicación

  • for: cuando sabes cuántas repeticiones necesitas.
  • while: cuando repites hasta que ocurra algo (centinela o condición).
  • Contador vs acumulador: “cuántos” vs “cuánto”.

Meta: que puedas justificar tu solución con una traza y casos borde.

Fundamento

¿Qué problema resuelve un ciclo?

La idea central

Un ciclo es una estructura de control que ejecuta un conjunto de instrucciones más de una vez de forma controlada.

La motivación real no es “ahorrar escritura”, sino lograr que la solución funcione para N datos sin que tu algoritmo cambie.

Si el enunciado dice “para cada…”, “todos los…”, “hasta que…”, casi siempre estás frente a un ciclo.

Señales de que te falta iteración

  • Tu solución solo funciona para 2 o 3 valores “porque eso fue lo que probaste”.
  • Duplicaste el mismo bloque cambiando apenas el nombre de una variable.
  • No puedes explicar qué pasaría si mañana fueran 1000 entradas.

Programar bien: diseñar un proceso general, no “resolver un ejemplo”.

Fundamento

Las 4 piezas que todo ciclo necesita

1) Inicialización Ej: total=0; i=1 2) Condición ¿se repite o se detiene? 3) Bloque leer, sumar, contar... 4) Progreso i++ o cambia el estado

Si falta el progreso (o está mal), el ciclo puede no terminar.

Cómo pensar un ciclo sin perderte

Antes de escribir código, responde estas preguntas:

  • ¿Qué variable controla la repetición? (un i, una opción del menú, un estado)
  • ¿Cuál es la condición de parada exacta? (por ejemplo: i > N, o entrada == -1)
  • ¿Qué cambia en cada vuelta para acercarte a parar? (i++, leer de nuevo, actualizar estado)
  • ¿Qué debe quedar listo al final? (suma, promedio, máximo, conteo)

Esto reduce el 80% de errores antes de ejecutar.

C#

for: cuando sabes cuántas repeticiones necesitas

Explicación

Un for es ideal cuando el problema te da un número N o un rango claro. En ese caso, el contador (por ejemplo i) avanza de forma predecible.

Léelo así: “inicia i”, “mientras se cumpla la condición”, “ejecuta el bloque”, “luego avanza i”.

  • Inicialización: int i = 1
  • Condición: i <= N
  • Progreso: i++

Código base

for (int i = 1; i <= N; i++) { // 1) Leer/Calcular algo // 2) Actualizar acumuladores/contadores // 3) (Opcional) Validar y corregir }

Off-by-one: revisa si tu i debe iniciar en 0 o 1, y si la condición es < o <=.

C#

while: cuando repites hasta que ocurra una condición

Explicación

Un while es útil cuando no sabes cuántas iteraciones habrá. En vez de contar vueltas, controlas la repetición por una condición de parada.

Ejemplos típicos: “mientras el usuario quiera continuar”, “hasta que la entrada sea válida”, “hasta encontrar un elemento”.

Clave: en cada vuelta debe ocurrir algo que haga que la condición cambie, o no terminará.

Código base

while (condicion) { // Bloque del ciclo // Debe existir progreso: // - actualizar variable de control // - o volver a leer // - o cambiar el estado }

Si “se cuelga”, casi siempre es porque la condición nunca cambia.

Herramientas

Contador vs acumulador (la dupla más usada)

Contador

Un contador modela “cuántas veces ocurre algo”. Empieza en 0 y normalmente sube de 1 en 1.

  • Cuántas notas son < 3.0
  • Cuántos intentos hizo el usuario
  • Cuántos datos están fuera de rango
int debajoDeTres = 0; if (nota < 3.0m) { debajoDeTres++; }

Acumulador

Un acumulador modela “cuánto llevo”. Suma valores para obtener un total.

  • Suma de notas para promedio
  • Total de ventas
  • Consumo total (kWh)
decimal suma = 0m; suma += nota; // suma = suma + nota

Regla de oro: declara contadores/acumuladores antes del ciclo. Si los declaras dentro, se reinician en cada iteración y tu resultado final quedará mal.

Ejemplo

Ejemplo 1 (for): estadísticas de N notas

Problema: leer N notas (0.0 a 5.0) y calcular: (1) promedio, (2) cuántas están por debajo de 3.0, (3) máxima.

Casos borde que debes pensar: N=0 (no hay notas), nota=3.0 exacto, nota=0.0 o 5.0.

Decisiones de diseño (explicadas)

  • El promedio solo existe si N > 0 (evita división por cero).
  • Para máxima: puedes inicializar con la primera nota si N>0, o usar una “bandera”.
  • Valida rango 0..5 para evitar datos imposibles.

Hoy el foco es el ciclo; la validación completa con reintento la trabajamos como mejora.

C# (claro y directo)

Console.Write("N: "); int N = int.Parse(Console.ReadLine()!); decimal suma = 0m; int debajoDeTres = 0; decimal max = 0m; bool hayDatos = false; for (int i = 1; i <= N; i++) { Console.Write($"Nota {i} (0..5): "); decimal nota = decimal.Parse(Console.ReadLine()!); // (Validación mínima opcional) // if (nota < 0m || nota > 5m) { ... } suma += nota; if (nota < 3.0m) debajoDeTres++; if (!hayDatos) { max = nota; hayDatos = true; } else if (nota > max) { max = nota; } } if (N > 0) { decimal promedio = suma / N; Console.WriteLine($"Promedio: {promedio}"); Console.WriteLine($"Debajo de 3.0: {debajoDeTres}"); Console.WriteLine($"Máxima: {max}"); } else { Console.WriteLine("No hay datos (N=0)."); }
Ejemplo

Ejemplo 2 (while): centinela para terminar

Problema: el usuario ingresa consumos. Cuando ingresa -1, se termina y se muestran: cantidad de consumos válidos y el total acumulado.

La regla importante es lógica: el centinela -1 es una señal de fin, no un dato del conjunto. Por eso NO se suma ni se cuenta.

Patrón mental

  • Leer un valor inicial (para poder evaluar la condición).
  • Mientras no sea el centinela: procesar, luego volver a leer.
  • Al final: imprimir resultados.

Este patrón evita “leer dos veces” o mezclar el centinela con datos reales.

C#

decimal total = 0m; int cantidad = 0; Console.Write("Consumo (-1 para terminar): "); decimal x = decimal.Parse(Console.ReadLine()!); while (x != -1m) { total += x; cantidad++; Console.Write("Consumo (-1 para terminar): "); x = decimal.Parse(Console.ReadLine()!); } Console.WriteLine($"Cantidad: {cantidad}"); Console.WriteLine($"Total: {total}");
Verificación

Traza: cómo demuestras que tu ciclo está bien

Qué es una traza

Es una simulación manual que muestra cómo cambian las variables en cada iteración. No es “repetir el código”: es registrar el estado de variables clave.

En ciclos, la traza te ayuda a detectar: (1) si se suma/contabiliza lo correcto, (2) si el progreso está bien, (3) si la condición corta donde debe.

Ejemplo (centinela)

Iteración x total (antes) total (después) cantidad
1100101
2510152
Fin-1(no se procesa)152

Pregunta obligatoria: ¿en qué parte del código podría colarse el -1 si lo escribes diferente?

Calidad

Errores comunes (y cómo evitarlos)

1) Ciclo infinito

Pasa cuando la condición nunca cambia. Ejemplo: lees el valor una vez y nunca vuelves a leer, o el contador no incrementa.

while (x != -1m) { // ERROR: si aquí no vuelves a leer x, nunca cambia }

Solución: garantiza progreso (leer de nuevo / i++ / cambiar estado).

2) Off-by-one

Pasa cuando haces una iteración de más o de menos por iniciar mal i o por usar < en vez de <=.

// ¿quieres N datos? for (int i = 1; i <= N; i++) { ... } // N iteraciones // ¿quieres índices 0..N-1? for (int i = 0; i < N; i++) { ... } // N iteraciones

Solución: decide el rango (1..N o 0..N-1) y mantén coherencia.

Recomendación práctica: cuando un ciclo “no da”, no reescribas a ciegas. Haz una traza de 2–3 iteraciones y verás exactamente dónde falló la lógica.

C#

Entrada robusta (TryParse) para no “romper” el programa

Qué problema resuelve

Console.ReadLine() devuelve texto. Si el usuario escribe letras cuando esperas un número, Parse lanza error y el programa termina.

Con TryParse, puedes detectar el error, mostrar un mensaje y pedir el dato otra vez.

Esto eleva el estándar del curso: no solo “funciona”, también es resistente a entradas reales.

Patrón recomendado

static int LeerEntero(string mensaje) { while (true) { Console.Write(mensaje); string s = Console.ReadLine() ?? ""; if (int.TryParse(s, out int n)) return n; Console.WriteLine("Entrada inválida. Intente de nuevo."); } } static decimal LeerDecimal(string mensaje) { while (true) { Console.Write(mensaje); string s = Console.ReadLine() ?? ""; if (decimal.TryParse(s, out decimal x)) return x; Console.WriteLine("Entrada inválida. Intente de nuevo."); } }
Actividad

Entrega en clase: consumos de energía

Enunciado: leer N consumos (kWh) y calcular:

  • Total consumido (acumulador).
  • Cuántos consumos fueron > 200 (contador).
  • Promedio (si N>0; si N=0, define una salida segura).

Tu solución debe explicar: qué variables usas, por qué son contadores o acumuladores, y cómo verificaste con mínimo 2 pruebas.

Requisitos de entrega

  • C# consola (for recomendado).
  • 2 casos de prueba: normal + borde (por ejemplo N=0 o consumo=200 exacto).
  • Una traza corta (al menos 2 iteraciones) que evidencie cambios en total y conteo.

Pista (estructura)

int N = LeerEntero("N: "); decimal total = 0m; int mayores200 = 0; for (int i = 1; i <= N; i++) { decimal c = LeerDecimal($"Consumo {i}: "); total += c; if (c > 200m) mayores200++; } if (N > 0) { decimal promedio = total / N; Console.WriteLine($"Total: {total}"); Console.WriteLine($">200: {mayores200}"); Console.WriteLine($"Promedio: {promedio}"); } else { Console.WriteLine("N=0: no hay consumos."); }
Cierre

Ticket de salida (5 min)

  1. En una frase: ¿qué diferencia hay entre contador y acumulador?
  2. Escribe un ejemplo donde usarías for y uno donde usarías while (con una frase de por qué).
  3. Propón 1 caso borde para la actividad de consumos y explica qué valida.

La calidad no se demuestra con “a mí me dio”. Se demuestra con: variables bien elegidas, ciclo bien controlado y pruebas que cubren bordes.

Navegación: | Home End | F pantalla completa · En celular: swipe o botones

Fin

Lo que debes poder hacer al salir

Competencia práctica

  • Elegir entre for y while según el enunciado.
  • Construir contadores y acumuladores sin reiniciarlos por error.
  • Evitar división por cero y manejar N=0 de forma segura.
  • Explicar tu solución con una traza corta.

Para la próxima

  • Validación más formal: reintento con TryParse.
  • Más ejercicios con máximos/mínimos y condiciones combinadas dentro del ciclo.