El lenguaje de programación iJava (4)

Decisiones

Las instrucciones de todos los programas que hemos escrito hasta el momento se ejecutan una después de otra en el orden en que están escritas. Sin embargo, en muchas ocasiones necesitamos que se ejecuten unas instrucciones u otras dependiendo de alguna condición. Para expresar este tipo de alternativas en nuestro programa iJava cuenta con la estructura if-else.

La estructura if-else nos permite especificar dos conjuntos de instrucciones asociados a una condición de tal modo que si la condición se cumple se ejecute el primer conjunto de instrucciones y si no se cumple se ejecutará el segundo. Las condiciones las expresaremos utilizando operadores de comparación y de igualdad que veremos más adelante. El siguiente programa muestra cómo usar la estructura if-else para mostrar un texto u otro dependiendo de la edad del usuario.

void main() {
	int edad = readInteger("Dime cuántos años tienes");
	if (edad < 18) {
		println("Eres menor de edad");
	} else {
		println("Eres mayor de edad");
	}
}

En el programa anterior se puede ver cómo se hace una comparación entre dos números para ver cuál es mayor y cuál es menor. En este caso, si el resultado de la comparación es cierto, es decir, el valor de la variable edad es menor que 18 se ejecutará el bloque de código en el que hay una instrucción que muestra el mensaje "Eres menor de edad". En caso contrario se muestra la otra frase.

Además de comparar si un número es menor que otro usando <, también podemos comparar si un número es mayor que otro con el símbolo >, si es mayor o igual con >= y si es menor o igual con <=. Por otro lado es posible comprobar si dos valores, sean números o no, son iguales con == o si son distintos con !=.

El siguiente programa utiliza la estructura if-else para decidir si el número introducido por el usuario tiene algún premio suponiendo que se obtiene premio si se acierta el número generado aleatoriamente por el ordenador.

void main() {
	int secreto = round(random(10));
	int numero = readInteger("Dime cuál crees que es el número secreto entre 0 y 10");
	if (numero == secreto) {
		println("Acertaste");
	} else {
		println("Lo siento, era el " + secreto);
	}
}

Además de comparar dos valores también podemos crear expresiones lógicas combinando los resultados de comparaciones mediante las operaciones Y, O y NO lógicas. Los símbolos correspondientes a esos operadores son &&, || y ! respectivamente. El uso de paréntesis nos puede servir para escribir las expresiones de una forma que no sea ambigua.

El siguiente programa utiliza una expresión lógica como condición de la estructura if-else para decidir si el número introducido por el usuario tiene algún premio suponiendo que se obtiene premio si se acierta el número generado aleatoriamente por el ordenador o si el número elegido es una unidad menor que el correcto.

void main() {
	int secreto = round(random(10));
	int numero = readInteger("Dime cuál crees que es el número secreto entre 0 y 10");
	if (numero == secreto - 1 || numero == secreto) {
		println("Ganaste");
	} else {
		println("Lo siento, era el " + secreto);
	}
}

En los ejemplos que hemos visto hasta el momento se ha utilizado la estructura if-else completa, es decir, incluyendo el código a ejecutar cuando la condición es cierta y el código a ejecutar cuando no lo es. Sin embargo, es posible no indicar el código a ejecutar cuando la condición no es cierta. En este caso, podemos hablar de estructura if simple. Por ejemplo, el siguiente programa usa una estructura if simple para añadir una aclaración en un mensaje.

void main() {
	int secreto = round(random(10));
	println("El número secreto es: " + secreto);
	// Si el resto de dividir el número por dos es cero es que es par
	if (secreto % 2 == 0) {
		println("Y se trata de un número par");
	}
}

El resultado de una expresión en la que usamos operadores de comparación siempre será verdadero o falso. En iJava, como en otros lenguajes de programación, es posible utilizar variables que almacenen esos dos valores. Estas variables se denominan variables booleanas y para crearlas usaremos el tipo de dato llamado boolean. Además, para representar los conceptos verdadero y falso se utilizan dos palabras true y false respectivamente.

En siguiente programa genera diez números aleatorios entre 0 y 10 y cuenta el número de veces que aparece un número par. Al mismo tiempo determina si alguno de los números generados coincide con el 5.

void main() {
	int pares = 0;
	boolean encontrado = false;
	for ( int i = 1 ; i <= 10 ; i = i + 1 ) {
		int numero = round(random(10));
		if (numero % 2 == 0) {
			pares = pares + 1;
		}
		if (numero == 5) {
			encontrado = true;
		}
	}
	println("Números pares generados: " + pares);
	if (encontrado == true) {
		println("Al menos una vez ha salido 5");
	}
}

Fíjate como se han creado las variables pares y encontrado antes del bucle for dándoles un valor inicial de 0 y false respectivamente. Estas variables cambian de valor cuando en alguna iteración el número aleatorio generado y almacenado en la variable número es par o 5 respectivamente. Finalmente, al acabar el bucle for se usa la información almacenada en las variables para mostrar el resultado del programa.

Como ya hemos visto en la sección de animaciones iJava dispone de algunas variables predefinidas que nos permiten conocer la posición del ratón. También hay otra variable, de tipo booleano, que se llama mousePressed y su valor indica si el botón del ratón está pulsado o no. El siguiente programa muestra su uso

void dibuja() {
	// Si el botón del ratón está pulsado fondo blanco
	if (mousePressed == true) {
		background(255,255,255);
	} else {
		// Si no, fondo negro
		background(0,0,0);
	}
}

void main() {
	animate(dibuja);
}

Múltiples alternativas

Con las estructuras if e if-else podemos hacer que un programa sea capaz de ejecutar un trozo de código u otro según se cumpla o no una condición. Es decir, se elige de entre dos alternativas posibles pues una condición sólo puede ser cierta o falsa. En iJava existe también otra estructura llamada switch que nos permite expresar dos o más alternativas haciendo que el ordenador elija una de entre todas ellas. En el siguiente ejemplo se muestra el uso de switch para decidir qué operación matemática realizar en función del caracter indicado por el usuario.

void main() {
	int numero1 = readInteger("Escribe el primer número");
	char operacion = readChar("Escribe +, -, / o * para elegir la operación");
	int numero2 = readInteger("Escribe el segundo número");
	int resultado = 0;
	switch (operacion) {
		case '+':
			resultado = numero1 + numero2;
			break;
		case '-':
			resultado = numero1 - numero2;
			break;
		case '/':
			resultado = numero1 / numero2;
			break;
		case '*':
			resultado = numero1 * numero2;
			break;
		default:
			println("No se que hacer con " + operacion);
	}
	println("El resultado es " + resultado);
}

La estructura switch comienza con dicha palabra y una valor, variable o expresión encerrado entre paréntesis seguido de un bloque de código encerrado entre llaves. La expresión encerrada entre paréntesis es la que se utiliza para decidir y no puede ser ser de tipo booleano. Debe ser un número entero (tipo int), un carácter (tipo char) o un texto (tipo String). En este caso es una variable de tipo char que contiene el carácter que representa la operación a realizar y que previamente habrá indicado el usuario.

El código que va dentro del bloque del switch pondremos una etiqueta para cada alternativa que queramos considerar, es decir, para cada posible valor para el que queramos realizar ciertas instrucciones. Las etiquetas se indican con la palabra case seguida del valor concreto que debe ser un literal, es decir, un número, un carácter o un texto directamente escrito en el programa. La etiqueta termina con el símbolo de los dos puntos. Cuando switch se ejecuta primero compara el valor entre paréntesis con cada etiqueta y, si el valor obtenido coincide con el de alguna etiqueta, el flujo de programa salta a la instrucción en la que está puesta dicha etiqueta. Es decir, se empiezan a ejecutar las instrucciones encabezadas por dicha etiqueta. Si no hay ninguna que coincida, la estructura switch termina.

Se puede utilizar la etiqueta especial default: sin la palabra case delante, que marcará la instrucción dentro del switch a la que saltará el flujo de programa cuando ninguna de las otras etiquetas coincida con el valor que haya entre los paréntesis del switch.

También se puede utilizar la instrucción break; para hacer que el flujo de programa salte inmediatamente a la siguiente instrucción escrita tras la estructura switch. Esto resulta muy útil para evitar que, tras ejecutar la alternativa seleccionada, el flujo de programa continúe ejecutando las siguientes.

Repetir código mientras se cumpla una condición

En iJava, como en otros lenguajes, podemos hacer bucles cuyo número de repeticiones no sea fijo sino que dependa del cumplimiento de una condición. Lo normal es que dicha condición se cumpla inicialmente pero como consecuencia de la ejecución del código que se repite en cada iteración deje de cumplirse en algún momento y, por lo tanto, el bucle termine.

Por ejemplo, si quisiéramos que el ordenador generase un número aleatorio entre 0 y 10 y que, además, fuese par podríamos hacer que generara un número tras otro hasta que se cumpliera que el número es par. O dicho de otro modo, podríamos hacer que mientras que el número generado no fuera par se estuvieran generando nuevos números. Para hacer esto en iJava podemos usar la estructura do-while del siguiente modo.

void main() {
	int generados = 0;
	boolean encontrado = false;
	do {
		int numero = round(random(10));
		generados = generados + 1;
		if (numero % 2 == 0) {
			encontrado = true;
		}
	} while (encontrado == false);
	println("Números generados: " + generados);
	if (encontrado == true) {
		println("Al menos uno fue par");
	}
}

La estructura do-while comienza con la palabra do, a continuación escribimos el bloque de código que queremos que se repita encerrado entre dos llaves y terminamos con la palabra while seguida de la condición que se debe cumplir para volver a repetir el bucle encerrada entre paréntesis y seguida de un punto y coma.

Además de la estructura do-while también existe la estructura while. En este caso para escribir el bucle se pone primero la palabra while seguida de la condición entre paréntesis y a continuación el bloque de código que queremos que se repita mientras se cumpla la condición encerrado entre llaves. La diferencia principal entre do-while y while es que al usar la primera estructura tenemos un bucle que, como mínimo, se ejecuta una vez. Sin embargo, al usar la estructura while como la condición se comprueba primero, si esta es falsa desde el principio, puede ser que el bucle no se ejecute ninguna vez.

void main() {
	int numero = readInteger("Escribe el número de veces que quieres mostrar el mensaje");
	while (numero > 0) {
		println("Hola mundo!");
		numero = numero - 1;
	}
	println("Fin");
}

En el ejemplo anterior se muestran tantos mensajes "Hola mundo!" como diga el usuario, pero si el usuario dice 0 no hay que mostrar ningún mensaje. En este caso resulta necesario usar la estructura while pues en algunos casos no hay que hacer ninguna vez el bloque de código asociado al bucle.

Sigue aprendiendo en El lenguaje de programación iJava (5)