Estructuras de control
Las estructuras de control son elementos fundamentales en la programación que permiten controlar el flujo de ejecución de un programa. Estas estructuras permiten tomar decisiones, repetir bloques de código y manejar errores (eso último, con try y catch, está en Errores y excepciones).
En JARU, todas las estructuras de control, como if, else, elsif, while, for, etc., deben finalizar con la palabra clave end. Esto indica al compilador que ha llegado al final de la estructura de control. La utilización de end es necesaria para evitar errores sintácticos y para mantener una estructura de código limpia y fácil de entender. Las reglas de los paréntesis y de then están en Sintaxis básica.
Flujo if-then-else
La estructura de control if-then-else es una de las estructuras de control más básicas en la programación. Se usa para tomar decisiones según una condición. La sintaxis básica es la siguiente:
if (condicion) then
// código a ejecutar si la condición es verdadera
else
// código a ejecutar si la condición es falsa
end
La cláusula elsif es una extensión del if-then-else que permite evaluar varias condiciones en una sola estructura de control. Se ejecuta el primer bloque cuya condición se cumpla:
if (condicion1) then
// código a ejecutar si la condicion1 es verdadera
elsif (condicion2) then
// código a ejecutar si la condicion2 es verdadera
else
// código a ejecutar si ninguna condición anterior es verdadera
end
Flujo switch-case
La estructura de control switch-case es una forma de controlar el flujo de un programa mediante la selección de diferentes caminos en función de una variable o expresión. Es similar al uso de varias estructuras if-else anidadas, pero tiene la ventaja de ser más legible y fácil de mantener.
switch (variable o expresión)
case valor1:
// instrucciones
case valor2, valor3:
// instrucciones
default:
// instrucciones
end
La expresión se evalúa y se compara con cada uno de los valores case. Si se encuentra una coincidencia, se ejecutan las instrucciones asociadas a ese caso. Si no se encuentra ninguna coincidencia, se ejecutan las instrucciones del default.
func tipoDeDia(dia)
switch (dia)
case 1, 2, 3, 4, 5:
return "laborable"
case 6, 7:
return "fin de semana"
default:
return "no existe"
end
end
println(tipoDeDia(3)) // laborable
println(tipoDeDia(7)) // fin de semana
println(tipoDeDia(9)) // no existe
- No hay caída de un
caseal siguiente. Al acabar el bloque de uncase, elswitchtermina: no hace faltabreak, y tampoco sirve para eso (ver break y continue). - Un
caseadmite varios valores, separados por comas:case "A", "a":. - Los valores se comparan como con
==.1coincide con1.0, y las cadenas, por su contenido. Una lista, un mapa o un objeto solo coincide consigo mismo, no con otro que tenga lo mismo. - Los valores pueden ser expresiones: variables, constantes, enumerados (
case Estado.SALTANDO:) o cuentas. - Gana el primer
caseque coincide, en el orden en que están escritos.defaultsolo se ejecuta si no coincide ninguno, aunque esté escrito antes que loscase, y solo puede haber uno. - Si no coincide ninguno y no hay
default, no se ejecuta nada. - La expresión va entre paréntesis, y cada
casey eldefaultacaban en:.
Con cadenas:
var tecla = "a"
switch (tecla)
case "A", "a":
println("izquierda")
case "D", "d":
println("derecha")
default:
println("otra tecla")
end
Con switch (true), cada case puede ser una condición, y gana la primera que se cumple:
var puntos = 75
switch (true)
case puntos >= 90:
println("Sobresaliente")
case puntos >= 50:
println("Aprobado")
default:
println("Suspenso")
end
Bucle for
La estructura for en JARU se utiliza para realizar un bucle de manera controlada. La sintaxis básica es la siguiente:
for (inicialización; condición; incremento)
// cuerpo del bucle
end
La inicialización es la expresión que se ejecuta al principio del bucle; suele ser una variable que se utilizará como contador. La condición es una expresión que se evalúa en cada iteración del bucle: si es falsa, el bucle termina. El incremento es la expresión que se ejecuta al final de cada iteración del bucle.
for (var i = 1; i <= 10; i++)
println(i)
end
En este ejemplo, la inicialización es var i = 1, la condición es i <= 10, y el incremento es i++. Cada vez que el bucle se ejecuta, se imprime el valor de la variable i y se incrementa en 1.
Se puede crear un bucle infinito con for con la siguiente sintaxis:
for (;;)
// cuerpo del bucle
end
Ejemplos de uso de for
Iterar un número determinado de veces:
for (var i = 0; i < 10; i++)
println("Iteración ", i)
end
Iterar sobre una lista:
var miLista = [1, 2, 3, 4, 5]
for (var i = 0; i < 5; i++)
println("El elemento en la posición ", i, " es ", miLista[i])
end
Iterar en orden inverso:
for (var i = 10; i > 0; i--)
println("Iteración ", i)
end
For extendido
Una característica única de JARU es su estructura de control for extendida, que agrega funcionalidades de filtro y código alternativo para proporcionar una mayor flexibilidad a los programadores.
La declaración for extendida en JARU sigue la estructura siguiente:
for (var i = valor_inicial; i < valor_final; i = i + incremento; condicion_filtro)
// código a ejecutar cuando la condición del filtro es verdadera
elfor
// código alternativo a ejecutar cuando la condición del filtro es falsa
end
Análisis de la estructura
- Inicialización:
var i = valor_inicial;Aquí es donde se inicializa la variable de control del bucle. - Condición:
i < valor_final;Esta es la condición que se evalúa antes de cada iteración del bucle. - Actualización:
i = i + incremento;Esta es la operación que se realiza después de cada iteración del bucle. - Filtro:
condicion_filtroFuncionalidad única de JARU que permite establecer una condición adicional que debe cumplirse para que se ejecute el código dentro del bucle. - Código alternativo:
elforPermite especificar un bloque de código alternativo que se ejecutará cuando la condición del filtro no se cumpla. - Terminación:
endMarca el final del bloquefor.
Ejemplos de for extendido
// Bucle FOR con filtro (solo imprime los números pares)
for (var i = 0; i < 10; i = i + 1; i % 2 == 0)
println(i)
end
// Bucle FOR con filtro y alternativa (imprime "impar" para números impares)
for (var i = 0; i < 10; i = i + 1; i % 2 == 0)
println(i)
elfor
println("impar")
end
Casos de uso del for extendido
Procesar solo ciertos elementos:
var lista = [1, 2, 3, 4, 5, 6]
for (var i = 0; i < lista.size(); i++; lista[i] % 2 == 0)
println(lista[i])
end
Manejar excepciones o condiciones especiales:
var datos = [10, -3, 25]
for (var i = 0; i < datos.size(); i++; datos[i] >= 0)
println("Procesando ", datos[i])
elfor
println("Dato no válido en el índice: ", i)
end
Bucles anidados con características extendidas:
var usuarios = [
{"nombre": "Ana", "transacciones": [50, 5000]},
{"nombre": "Luis", "transacciones": [20]}
]
for (var i = 0; i < usuarios.size(); i++)
var transacciones = usuarios[i]["transacciones"]
for (var j = 0; j < transacciones.size(); j++; transacciones[j] > 1000)
println("Transacción fraudulenta del usuario ", usuarios[i]["nombre"])
elfor
println("Transacción correcta: ", transacciones[j])
end
end
El for extendido es especialmente útil cuando necesitas procesar colecciones de datos con condiciones complejas, evitando tener que anidar múltiples estructuras if dentro del bucle.
Bucle foreach
La estructura de control foreach en JARU se utiliza para recorrer elementos de una colección, como una lista, un mapa o un array. La sintaxis básica es la siguiente:
foreach (var elemento in coleccion)
// código a ejecutar para cada elemento
end
Donde elemento es una variable temporal que toma el valor de cada uno de los elementos de la colección en cada iteración del bucle. El cuerpo del bucle se ejecuta para cada elemento de la colección.
var lista = [1, 2, 3, 4, 5]
foreach (var numero in lista)
println(numero) // Muestra 1, 2, 3, 4 y 5
end
En este caso, la variable numero toma el valor de cada elemento de la lista en cada iteración, y el código dentro del bloque foreach se ejecuta para cada elemento.
El ciclo se detiene automáticamente una vez que se han recorrido todos los elementos de la colección.
Qué recorre foreach en cada tipo (listas, mapas, arrays y cadenas) y cómo cambiar los elementos desde el bucle está en Recorrerlos con foreach.
Bucle while
La estructura de control while en JARU es un bucle que se ejecuta mientras se cumpla una condición dada. La condición es evaluada al principio de cada iteración, y si es verdadera, el cuerpo del bucle se ejecuta. Si la condición es falsa, el bucle se detiene y se continúa con la siguiente línea de código.
while (condicion)
// Bloque de código a ejecutar
end
Si se quiere un bucle infinito con while, lo único que hay que hacer es que la condición sea true:
while (true)
// Bloque de código a ejecutar
end
Ejemplo:
var i = 0
while (i < 10)
println("La variable i tiene el valor ", i)
i += 1
end
En este ejemplo, la condición es i < 10, por lo que el bucle se ejecuta 10 veces, imprimiendo el valor de la variable i en cada iteración.
Es importante tener cuidado de incluir una forma de detener el bucle, ya sea cambiando la condición dentro del cuerpo del bucle o usando una estructura de control adicional; si no, el bucle se ejecutará indefinidamente.
Bucle until
El bucle until en JARU se utiliza para repetir un bloque de código hasta que se cumpla una determinada condición.
until (condicion)
// bloque de código
end
En este código, la condicion es una expresión booleana que se evalúa antes de cada iteración del bucle. Si la condición es falsa, el bloque de código dentro del bucle se ejecutará y luego se volverá a evaluar la condición. Este proceso continuará hasta que la condición sea verdadera, momento en el cual se saldrá del bucle.
Ejemplo que imprime los números del 1 al 10:
var i = 1
until (i > 10)
println(i)
i++
end
Otro ejemplo, una cuenta atrás desde un número hasta cero:
var numero = 10
until (numero == 0)
println(numero)
numero = numero - 1
end
println("¡Despegue!")
Diferencia entre while y until
Tanto until como while son estructuras de control de flujo que se utilizan para implementar bucles. La principal diferencia está en la forma en que se evalúa la condición de salida del bucle:
- En
until, el bucle se ejecuta hasta que la condición especificada es verdadera - En
while, el bucle se ejecuta mientras la condición sea verdadera
Es importante tener en cuenta que el bloque de código dentro del bucle debe modificar la condición de alguna manera para evitar un bucle infinito. De lo contrario, el bucle se ejecutará indefinidamente.
Salir de un bucle: break y continue
breaksale del bucle: el programa sigue en la línea de después de suend.continuesalta a la vuelta siguiente. En unfor, pasa antes por el incremento (i++); enwhileyuntil, vuelve a mirar la condición; enforeach, pasa al elemento siguiente.
Valen en for (también en el for extendido), foreach, while y until.
for (var i = 1; i <= 10; i++)
if (i % 2 == 0) then
continue // se salta los pares
end
if (i > 7) then
break // y para al pasar de 7
end
print(i, " ")
end
println()
1 3 5 7
Para buscar algo y dejar de buscar en cuanto aparece:
var nombres = ["Ana", "Luis", "Eva", "Raúl"]
var posicion = -1
for (var i = 0; i < nombres.size(); i++)
if (nombres[i] == "Eva") then
posicion = i
break
end
end
println("Eva está en la posición ", posicion) // Eva está en la posición 2
- Con bucles anidados, solo afectan al de dentro: un
breaken el bucle interior no sale del exterior. - Dentro de un
switch, afectan al bucle que lo contiene.breakno sale delswitch, sino del bucle:
var ordenes = ["avanza", "gira", "salta", "para", "avanza"]
foreach (var orden in ordenes)
switch (orden)
case "para":
break // sale del foreach, no solo del switch
case "salta":
continue // pasa a la orden siguiente
default:
println("Hago: ", orden)
end
end
println("Fin")
Hago: avanza
Hago: gira
Fin
- Fuera de un bucle no compilan, con el error «Cannot use 'break' outside of a loop.». Tampoco valen en una función a la que se llama desde un bucle: tienen que estar dentro del propio bucle. Este
switchno está en ningún bucle:
var opcion = 1
switch (opcion)
case 1:
println("uno")
break // no compila: no hay ningún bucle
end