If-Else V.S. Interruptor final de flujo

8

Me preguntaba si las sentencias if-else, son como una sentencia switch que tiene tiene una sentencia break.

if( boolean_expression_1 )
  statement_1
else if( boolean_expression_2 )
  statement_2
else 
  default_statement

Es lo mismo que:

switch( controlling_expression )
{
case: ( boolean_expression_1 )
{
     statement_1
     break;
}
case: ( boolean_expression_2 )
{
     statement_2
     break;
}
default:
{
     default_statement
}
    
pregunta Chris Okyen 21.09.2012 - 23:45

5 respuestas

6
  

Me preguntaba si las declaraciones if-else, son como una instrucción switch que no tiene una instrucción break.

Eso es al revés. Tipo de.

Una secuencia if, else if, ... else en la que todas las pruebas son todas pruebas de igualdad simples en la misma variable de la forma (variable == value) o ((variable == value1) || (variable == value2) ...) se puede convertir en una instrucción switch en esa variable. Las pruebas de (variable == value) se convierten en case value: , y el cuerpo de if (o else if ) se convierte en el cuerpo del caso, pero debe agregar una declaración break al final del cuerpo del caso. Las pruebas ((variable == value1) || (variable == value2) ...) se convierten en una secuencia de casos de la forma case value1: case value2: ... case valuen: Una secuencia if con pruebas más complejas es, en general, distinta de una instrucción de cambio.

Si cada caso en una instrucción de cambio termina con break , esa instrucción de cambio siempre se puede reescribir como una secuencia if, else if, .... Esta conversión de un cambio a una secuencia if también es posible cuando la caída se limita a cosas tales como case A: case B: ... case N: do_something(); break; La caída a través de la cual un cuerpo no vacío cae a otro cuerpo no vacío no se puede convertir directamente a una secuencia if.

    
respondido por el David Hammen 22.09.2012 - 00:17
3

Aunque pensar en un bloque if-else como una declaración de cambio sin interrupción puede ser una abstracción útil para un nuevo programador, no es una comparación perfecta.

El interruptor probablemente esté más relacionado con "goto". Por supuesto, Java no tiene Goto, pero el lenguaje se construyó sobre ideas de otros lenguajes como C que sí lo tenía. Las etiquetas de "caso" y "predeterminadas" no son realmente diferentes a cualquier otro objetivo de salto para una instrucción goto, por lo que el comportamiento esperado sería continuar ejecutando la siguiente línea de código dentro del bloque (toda la instrucción de cambio es el bloque) . Esto se explica con más detalle en una de las respuestas de una pregunta relacionada: ¿Por qué tenemos que usar el interruptor break in? Así que terminamos con el caso de que necesite una declaración de break para decirle a su programa que ha terminado de ejecutar este bloque. Podría usar break en otros tipos de declaraciones, como un ciclo for o while de manera similar.

En lenguajes como java que usan cortocircuito, en un bloque if-elseif-else, si la condición para el primer caso de la sentencia if es verdadera, las condiciones de bloqueo if y else de otra manera no serán evaluadas. Después de un tiempo, se espera que encuentre un bloque de llaves entre código {} o una sola declaración. Por definición, de lo contrario significa "de lo contrario" o que la condición anterior no era cierta, sería un poco contradictorio dejar que el código se caiga.

    
respondido por el Jessica Brown 22.09.2012 - 00:23
1

Los lenguajes de programación a menudo proporcionan muchas construcciones diferentes que le permiten expresar una lógica similar con una sintaxis diferente.

Las declaraciones de

if / else no "caen" una a la otra incondicionalmente; la palabra clave else evita que se evalúen otras condiciones else-if solo cuando break al final de un bloque de casos lo saca de un interruptor, sin embargo, creando un conjunto de if s independiente (sin usar else ) hará que cada condición if se evalúe por sí sola.

De manera general, al eliminar la palabra clave break del final de los bloques case , el flujo de ejecución incondicionalmente seguirá cayendo al siguiente caso hasta que se produzca un quiebre / retorno / goto se encuentra o se ha llegado al final del bloque de conmutación.

Hay (raramente) situaciones en las que la conmutación de casos de conmutación se considera útil; sin embargo, es más común, y generalmente más idiomático, querer que cada bloque de caso se trate por sí solo.

if-else y switch-case son construcciones que le permiten expresar la selección (toma de decisiones) en un lenguaje de programación; a veces, la elección entre los dos depende del estilo personal, otras veces existen razones de peso para elegir una sobre la otra: existe una opción similar al elegir para -vs- mientras que para expresar la repetición.

    
respondido por el Ben Cottrell 22.09.2012 - 00:07
0

La respuesta es no: la instrucción if no es como una instrucción switch sin interrupción. Comencemos con esta parte de su pregunta:

  

si boolean_expression_1 era verdadero, ¿comprobaría si boolean_expression_2 es verdadero?

Podemos encontrar la respuesta con este programa. El truco es que llamamos a un método como boolean_expression y usamos System.out.println () para ver si el método se ejecuta. De esta manera sabemos si la expresión fue evaluada. Aquí está el programa:

public class IfElseExample {

    private static boolean booleanExpression1() {
        System.out.println("Expression 1 is being evaluated.");
        return true;
    }

    private static boolean booleanExpression2() {
        System.out.println("Expression 2 is being evaluated.");
        return true;
    }

    public static void main(String[] args) {
        if (booleanExpression1()) 
            System.out.println("Statement 1 is executed");
        else if (booleanExpression2()) 
            System.out.println("Statement 2 is executed");
        else
            System.out.println("Default statement is executed");
    }

}

Verás que la segunda expresión booleana no se evalúa. Es probable que este comportamiento se vuelva más comprensible si coloca algunos paréntesis (lo cual es un buen hábito en la mayoría de los casos):

    if (booleanExpression1()) { 
        System.out.println("Statement 1 is executed");
    } else {
        if (booleanExpression2()) {
            System.out.println("Statement 2 is executed");
        } else {
            System.out.println("Default statement is executed");
        }
    }

Esta es la forma en que el compilador ve su cadena de if original. Como puede ver ahora, el segundo "si" es una declaración única y, como tal, no se encuentra en el mismo nivel que la primera declaración "si". Si encadenas más sentencias if, se anidarán aún más.

También preguntó por qué la instrucción switch necesita una instrucción break. Esto se debe a que la instrucción switch no se implementa internamente con una cadena de instrucciones if (tampoco la instrucción if está basada en instrucciones switch). Usted podría esperar que

        switch(controllingExpression()) {
            case 42: System.out.println("A");
                        case 43: System.out.println("B");
            default : System.out.println("z");
        }

se traduce por el compilador en algo como:

if (controllingExpression() == 42) {
    System.out.println("A");
} else if (controllingExpression() == 43) {
    System.out.println("B");
} else {
    System.out.println("z");
}

Este no es el caso. En su lugar, utiliza una instrucción de salto oculta:

int x = numberOfStatementsToSkipFor(controllingExpression());
skip x // hidden skip the next x statements byte code instruction
System.out.println("A");
System.out.println("B");
System.out.println("z");

El método numberOfStatementsToSkipFor () devuelve 0 para 42, 1 para 43 y 2 para todo lo demás. Ahora queda claro por qué este programa podría producir

A
B
z

o

B
z

o simplemente

z

pero nunca

A
B

sin la 'z'. Pero claramente sería bueno si pudiéramos hacer esto. Y podemos usar break que se traduce en otra declaración de omisión. Así que si pones romper en todas las ramas de caso

switch(controllingExpression()) {
    case 42: {
        System.out.println("A");
        break;
    }
    case 43: {
        System.out.println("B");
        break;
    }
    default : System.out.println("z");
}

el compilador producirá esto:

int x = numberOfStatementsToSkip(controllingExpression());
skip x; // hidden skip the next x statements byte code instruction
System.out.println("A");
skip 3; //"B" + skip + "z"
System.out.println("B");
skip 1;
System.out.println("z");
    
respondido por el scarfridge 22.09.2012 - 14:42
0

Para responder a la pregunta editada (con los saltos)

Evaluarían las declaraciones de la misma manera, solo si las condiciones para ingresar a cada bloque son las mismas.

Para responder a la pregunta subjetiva, de

  

ofrece un ángulo de pensamiento de similitudes preservadas y también lo que son (diferentes / iguales) en el fondo

La comparación de los dos te distrae de lo que cada uno fue diseñado para expresar rápidamente.

Un switch centraliza sintácticamente la comparación para que puedas seguir el flujo en función de sus casos.

Mientras que if describe una condición única para ingresar un bloque.

Básicamente, el código simplemente "lee" de manera diferente.

Por ejemplo, tienes un word en tu cabeza y quieres buscarlo en el diccionario.

Un interruptor leería como: mantén la letra inicial en tu cabeza y luego hojea el alfabeto y luego ríndete si no comienza con esa letra.

Mientras que un montón de bloques if-else se leerían como: ¿empieza la palabra con una letra? repetido muchas veces, luego renunciar.

Si está tratando de explicar cómo funciona un conmutador a un nuevo programador (que está familiarizado con if bloques, podría ser más fácil explicarlo como:

if( boolean_expression_1 ) {
  statement_1;
  return;
}

if( boolean_expression_2 ) {
  statement_2;
  return;
}

default_statement;
return;

Ahora, el ejemplo anterior rompe lo que normalmente se enseña en las escuelas, pero regresar temprano y regresar a menudo a veces es más fácil leer, y tan rápido en una pila basada en vm.

Debería haber optimizaciones para los conmutadores en las primitivas, por lo que la elección de qué bloque de control usar se debe basar en lo que está comparando.

Recuerde que las largas declaraciones switch y if tienden a ser muy detalladas, difíciles de mantener y también degradan el rendimiento a medida que se deben verificar más condiciones.

Es posible que desee considerar un Hash de clases / funciones anónimas o un patrón de comando, en lugar de bloques de control largos con muchas condiciones.

Los hash y el patrón de comando permiten que el código se realice más rápido y mejora la capacidad de mantenimiento del código.

    
respondido por el Brian 23.10.2012 - 06:33

Lea otras preguntas en las etiquetas