Condicionales con MobileProcessing

Las sentencias condicionales moderan el flujo de ejecución de un programa según la ocurrencia de ciertas condiciones específicas, es decir, le permiten al desarrollador determinar que porciones de código se ejecutan según las circunstancias.

La sentencia condicional mas simple es el if (si de suposición), permite realizar este tipo de decisión mencionado anteriormente. Su sintáxis es la siguiente.

if (expresión)
{
// bloque de código.
}

// Siguiente instrucción.

Si la expresión al ser evaluada retorna un valor afirmativo (true) el bloque de código es ejecutado, de lo contrario (retornó false), el control del programa continúa su ejecución en la siguiente instrucción. Por ejemplo.

if (divisor != 0)
{
cociente = dividendo / divisor;
}

El código anterior realiza la división entre dividendo y divisor almacenando su resultado en la variable cociente, realizando previamente la verificación que divisor no sea cero ya que la división por cero no se encuentra definida. En el caso de que el divisor sea cero, no se ejecutará la operación.

El condicional if permite también especificar que debe suceder en el caso en que la condición del condicional no sea aceptada, es decir, determinar que código se debe ejecutar cuando la expresión del condicional al ser evaluada retornó false mediante la instrucción else (de lo contrario).

saludo = "Buenos dias";

if(hora < 12)
{
tipo = "AM";
}
else
{
tipo = "PM";
saludo = "Buenas tardes";
}

Según el ejemplo anterior se le asignará el valor de "AM" a la variable tipo si el valor almacenado en la variable hora es menor de 12 (condición), de lo contrario se le asignará el valor de "PM" y a la variable saludo se le asignará el valor de "Buenas tardes".

Para casos como el anterior, en los que el código a ejecutarse en los bloques de if o del else cuentan con una única línea de código pueden obviarse las llaves de agrupación del bloque ({ ... }). Téngase en cuenta este detalle toda vez que bien puede llevar a confusiones. Según esto, la siguiente representación del código anterior es equivalente.

if(hora < 12)
tipo = "AM";
else
{
tipo = "PM";
saludo = "Buenas tardes";
}

Nótese como no aplica para el bloque else ya que este contiene mas de una línea de código.

Lo más común es que las expresiones evaluadas en los condicionales estén basadas en la comparación de valores, tal y como se han hecho los ejemplos hasta ahora:

  • Si el divisor es diferente de cero: divisor != 0.
  • Si la hora es menor que 12: hora < 12.

Para esto son utilizados los operadores relacionales los cuales son descritos a continuación.

Igual a A == B Es verdadero si A es igual a B, es falso de lo contrario.
Diferente de A != B Es verdadero si A es diferente de B, es falso de lo contrario.
Menor que A < B Es verdadero si A es menor que B, es falso de lo contrario.
Menor o igual que A <= B Es verdadero si A es menor o es igual que B, es falso de lo contrario.
Mayor que A > B Es verdadero si A es mayor que B, es falso de lo contrario.
Mayor o igual que A >= B Es verdadero si A es mayor o es igual que B, es falso de lo contrario.

Las expresiones evaluadas por la estructura condicional se pueden componer utilizando los operadores básicos del álgebra booleana: Y (and), O (or) y NO (not).

Los operadores AND y OR son binarios, es decir, requieren de dos parámetros, mientras que el operador NOT requiere de un único parámetro. Estos operadores permiten componer la expresión booleana resultante a patir de articular múltiples expresiones con ellos, calculándose el resultado a partir de sus tablas de verdad.

La conjunción o AND indica que las dos expresiones deben ser verdaderas para que la expresión resultante así lo sea, de lo contrario, es decir, si una de las dos falla, el resultado será falso. Se representa con el operador &&.

if(expresión1 && expresión2)
// Código #1
else
// Código #2

El código #1 sólo se ejecutará en el caso en que expresión1 y expresión2, ambas, sean verdaderas. En caso de que falle (sea falsa) una de las dos, se ejecutará el código #2.

La disyunción u OR indica que al menos una de las expresiones, o las dos, deben ser verdaderas para que la expresión resultante así lo sea, en caso contrario, es decir las dos sean falsas, el resultado será falso. Se representa con el operador ||.

if(expresión1 || expresión2)
// Código #1
else
// Código #2

El código #1 se ejecutará bien sea porque expresión1 es verdadera, porque expresión2 es verdadera o porque ambas, expresión1 y expresión2 son verdaderas. En caso contrario se ejecutará el código #2. Nótese como la conjunción es mas restrictiva que la disyunción, para la primera ambas expresiones deben evaluarse de manera positiva mientras que para la segunda sólo es importante que se cumpla al menos una de ellas.

La negación o NOT es una booleana cuya finalidad consiste en negar (convertir en su complemento) al valor proporcionado. Es decir, la negación de true es false y la negación de false es true. Se representa con el operador !.

if(! expresion)
// Código #1
else
// Código #2

El código #1 se ejecutará si y sólo si la expresión es falsa, de lo contrario se ejecutará el código #2.

Como se mencionó anteriormente, es posible componer expresiones booleanas complejas a partir de la unión de múltiples expresiones mas simples con estos operadores.

if(producto_listo &&
!producto_descompuesto &&
(producto_en_almacen || producto_en_tienda))
{
// Vender el producto a los clientes.
}
else
// Solicitar la producción del producto.

En este ejemplo se decide si el producto puede ser vendido directamente a los clientes o si por el contrario deberá ser solicitada su producción. Para que sea vendido se deberán satisfacer tres condiciones sin las cuales no podrá ser vendido.

  1. Que el producto se encuentre listo.
  2. Que no se encuentre descompuesto.
  3. Que haya existencia ya sea en almacén o en la tienda.

Como las condiciones 1, 2 y 3 son de obligatorio cumplimiento están unidas ente sí por conjunciones, el requerimiento #3 da la opción de que el producto se encuentre ya sea en el almacén o en la tienda, por ello se encuentra unido con una disyunción. Si falla una de ellas se deberá realizar la solicitud del producto.

Existe un caso particular en el uso de las sentencias condicionales if que pueden ser resumidas mediante el uso del operador if ternario el cual reproduce la misma funcionalidad del condicional en una sola línea de código. Considérese el siguiente caso.

String calificacion = "";

if (nota >= 3)
calificacion = "Aprobado";
else
calificacion = "Reprobado";

println ("El examen ha sido " + calificacion);

El condicional basado en el resultado de la variable nota determina el valor de la variable calificación según la comparación con un valor conocido. Este condicional puede reescribirse de la siguiente manera utilizando la versión ternaria.

String calificacion = (nota >= 3) ? "Aprobado" : "Reprobado";

Nótese que la expresión anterior cuenta con los mismos elementos que la versión completa pero dispuestos con la siguiente estructura.

valor = (expresión) ? valor_en_caso_afirmativo : valor_en_caso_contrario;

Esta versión simplificada de la sentencia condicional es útil para este caso cuando la función de la condición es la de filtrar una expresión para determinar el valor que se involucrará en una asignación.

Existe una variación interesante para los operadores booleanos de conjunción (&&) y disyunción (||) y son sus versiones sin optimización & y | respectivamente.

Se dice que los operadores && y || se encuentran optimizados ya que ellos se evalúan parcialmente si pueden inferir su resultado final con la información parcial.

  • La conjunción requiere que las dos expresiones que la componen sean verdaderas por este motivo si la primera expresión es falsa ya no hay motivo para evaluar la segunda.
  • La disyunción requiere que al menos una de las expresiones sea verdadera, si la primera es verdadera, ya no hay necesidad de evaluar la segunda.

Esta optimización que la mayoría de las veces permite ahorrar fracciones de milisegundos en los cálculos puede ser indeseada en ciertos casos específicos. Considérese el siguiente ejemplo.

int a = 0;
int b = 0;

boolean A()
{
a ++;
return false;
}

boolean B()
{
b ++;
return true;
}

void setup()
{
if(A() && B())
println("Sorpresa!");

println("a = " + a + "; b = " + b);
}

Las funciones A() y B() retornan los valores false y true respectivamente, por este motivo no esperamos que se muestre el mensaje Sorpresa! ya que la primera expresión de la conjución es false y por ello la ejecución del programa nunca ingresará a ese bloque de código, sin embargo la impresión final si tiene una variación debido a la optimización.

Se esperaría que al final de la ejecución los valores de a y b fueran 1, sin embargo por lo explicado anteriormente serán "a = 1; b = 0".

Igual sucede para la disyunción. Considerese la siguiente modificación al ejemplo anterior.

// ...
if(B() || A())
// ...

En este caso los valores resultantes serán "a = 0; b = 1", es decir, nunca se evaluó la expresión A().

Para evitar esta situación cuando sea necesario se deben utilizar los operadores análogos sin optimización. La siguiente modificación ejemplifica su uso bajo el cual se obtienen los valores inicialmente esperados.

// ...
if(A() & B())
// ...

El resultado de la impresión final es: "a = 1; b = 1". De igual manera sucederá para la disyunción con el operador |.

Otra facilidad para la realización de comparaciones según su finalidad es la siguiente. Considérese el siguiente caso.

if(mensaje == 4 )
moverJugadorIzquierda();
else
if(mensaje == 6 )
moverJugadorDerecha();
else
if(mensaje == 2 )
moverJugadorArriba();
else
if(mensaje == 8 )
moverJugadorAbajo();
else
println("Mensaje desconocido");

El código anterior basado en una serie de sentencias if-else anidadas garantiza que sólo uno de los bloques de código se va a ejecutar, para este caso, cuando mensaje sea cualquiera de los valores 2, 4, 6, 8 o sea desconocido (ninguno de los anteriores).

Este código puede reescribirse de una manera simplificada utilizando la sentencia switch de la siguiente manera.

switch(mensaje)
{
case 4:  moverJugadorIzquierda();
break;

case 6:  moverJugadorDerecha();
break;

case 2:  moverJugadorArriba();
break;

case 8:  moverJugadorAbajo();
break;

default: println("Mensaje desconocido");
break;
}

La sentencia switch tiene las características siguientes.

  • Puede ejecutarse sobre un número o un carácter el cual es realmente un valor ASCII entero. Para el caso de los carácteres debe recordarse que estos se encierran entre comillas simples: 'a', 'B', '7', etc.
  • Por cada opción de valor (case) de la variable filtrada se pueden ejecutar cuantas líneas de código como se requiera.
  • Cada bloque de código relacionado con cada opción debe terminarse con una sentencia de corte (break), de lo contrario se ejecutará el código de las distintas opciones secuencialmente hasta que se encuentre con un break o se termine la sentencia.
  • La opción default es opcional, es decir, no es obligatoria su definición y se ejecutará únicamente si ninguna de las opciones disponibles satisfacieron el valor de la variable filtrada.

Es posible proporcionar varios valores para una misma opción, es decir, indicar que se ejecute un bloque de código si la variable filtrada tiene alguno de los valores especificados, para esto se debe seguir la sintaxis siguiente.

// ...
case 1:  case 4:
moverJugadorIzquierda();
break;
// ...

Según la modificación realizada al ejemplo anterior, la función moverJugadorIzquierda() se llamará cuando el valor de la variable mensaje sea 1 o sea 4.

Leave a Reply

Your email address will not be published. Required fields are marked *