If-Else V.S. Cambia fine del flusso

8

Mi chiedevo se le istruzioni if if-else fossero come un'istruzione switch che ha un'istruzione break.

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

È lo stesso di:

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

5 risposte

6

I was wondering the if if-else statements, is like a switch statement that does not have a break statement.

Questo è indietro. Kind of.

Una sequenza if, else if, ... else in cui tutti i test sono tutti semplici test di uguaglianza sulla stessa variabile della forma (variable == value) o ((variable == value1) || (variable == value2) ...) può essere convertita in un'istruzione switch su quella variabile. I test (variable == value) diventano case value: e il corpo di if (o else if ) diventa il corpo del caso, ma è necessario aggiungere un'istruzione break alla fine del corpo del caso. I test ((variable == value1) || (variable == value2) ...) diventano una sequenza di casi della forma case value1: case value2: ... case valuen: An se la sequenza con test più complessi è in generale distinta da un'istruzione switch.

Se ogni caso in un'istruzione switch termina con break , tale istruzione switch può sempre essere riscritta come una sequenza if, else if, .... Questa conversione da un passaggio a una sequenza if è anche possibile quando fall through è limitata a cose come case A: case B: ... case N: do_something(); break; Fall through in cui un corpo non vuoto cade attraverso un altro corpo non vuoto non è direttamente convertibile in una sequenza if.

    
risposta data 22.09.2012 - 00:17
fonte
3

Anche se pensare a un blocco if-else come un'istruzione switch senza interruzioni potrebbe essere un'astrazione utile per un nuovo programmatore, non è un paragone perfetto.

Lo switch è probabilmente più simile a "goto". Certo, Java non ha Goto, ma il linguaggio è stato costruito su idee provenienti da altre lingue come C che ha fatto. Le etichette "case" e "default" non sono realmente diverse da qualsiasi altra destinazione di salto per un'istruzione goto, quindi il comportamento previsto sarebbe continuare ad eseguire la riga di codice successiva all'interno del blocco (l'intera istruzione switch è il blocco) . Questo è ulteriormente spiegato in una delle risposte a una domanda correlata: Perché dobbiamo usare break-in switch? Quindi finiamo con il caso che tu abbia bisogno di un'istruzione break per dire al tuo programma che hai finito di eseguire questo blocco. Potresti usare irrompere in altri tipi di istruzioni come un ciclo for o while allo stesso modo.

In linguaggi come java che usano cortocircuiti, in un blocco if-else-else, se la condizione per il primo caso dell'istruzione if è vera, le altre condizioni di blocco if e else non saranno valutate. Dopo un, se è previsto che troverai un blocco di parentesi graffe di codice {} o una singola istruzione. Per definizione, altrimenti significa "altrimenti" o che la condizione precedente non era vera, sarebbe un po 'contraddittorio lasciar cadere il codice.

    
risposta data 22.09.2012 - 00:23
fonte
1

I linguaggi di programmazione spesso forniscono molti costrutti diversi che ti permettono di esprimere una logica simile usando una sintassi diversa.

Le dichiarazioni

if / else non "falliscono" tra loro incondizionatamente; la parola chiave else impedisce qualsiasi ulteriore condizione di else-if valutata mentre break alla fine di un case-block ti fa uscire da un interruttore, creando tuttavia un set di% stand_one% co_de (senza usare if ) farà sì che ciascuna condizione else venga valutata autonomamente.

Coversly, la rimozione della parola chiave if dalla fine dei blocchi break farà sì che il flusso di esecuzione a incondizionatamente continui a cadere fino al caso successivo fino a un break / return / goto si incontra o è stata raggiunta la fine del blocco switch.

Ci sono (raramente) situazioni in cui il drop-through dei casi di commutazione è considerato utile; tuttavia è più comune, e solitamente più idiomatico, desiderare che ogni blocco del caso venga trattato da solo.

case e if-else sono entrambi costrutti che consentono di esprimere la selezione (processo decisionale) in un linguaggio di programmazione; a volte la scelta tra i due è legata allo stile personale, altre volte ci sono validi motivi per scegliere l'uno sull'altro - Una scelta simile esiste quando si sceglie per -vs- while per esprimere la ripetizione.

    
risposta data 22.09.2012 - 00:07
fonte
0

La risposta è no - l'if-statement non è come una dichiarazione di commutazione senza interruzione. Cominciamo da questa parte della tua domanda:

if boolean_expression_1 was true, would it check if boolean_expression_2 is true?

Possiamo trovare la risposta con questo programma. Il trucco è che noi chiamiamo un metodo come nostra espressione_bolea e usiamo System.out.println () per vedere se il metodo viene eseguito. In questo modo sappiamo se l'espressione è stata valutata. Ecco il programma:

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");
    }

}

Vedrai che la seconda espressione booleana non viene valutata. Questo comportamento diventa probabilmente più comprensibile se si inseriscono alcune parentesi (che è una buona abitudine nella maggior parte dei casi):

    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");
        }
    }

Questo è il modo in cui il compilatore visualizza la tua catena if originale. Come puoi vedere ora, il secondo "se" è una sua singola affermazione e come tale non si trova allo stesso livello della prima dichiarazione if. Se si concatenano più istruzioni if quelle che vengono nidificate ancora più in profondità.

Hai anche chiesto, perché l'istruzione switch necessita di un'istruzione break. Questo perché l'istruzione switch non è implementata internamente con una catena di if-statement (né l'if-statement basato su istruzioni switch). Potresti aspettarti che

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

viene tradotto dal compilatore in qualcosa di simile:

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

Questo non è il caso. Invece utilizza un'istruzione skip nascosta:

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");

Il metodo numberOfStatesmentsToSkipFor () restituisce 0 per 42, 1 per 43 e 2 per tutto il resto. Ora diventa chiaro il motivo per cui questo programma potrebbe produrre

A
B
z

o

B
z

o solo

z

ma mai

A
B

senza la 'z'. Ma chiaramente sarebbe bello se potessimo farlo. E possiamo usare break che viene tradotto in un'altra istruzione skip. Quindi se metti un'interruzione in tutti i rami del caso

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

il compilatore produrrà questo:

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");
    
risposta data 22.09.2012 - 14:42
fonte
0

Per rispondere alla domanda modificata (con le interruzioni)

Valuterebbero le dichiarazioni allo stesso modo, se e solo se le condizioni per inserire ogni blocco sono le stesse.

Per rispondere alla domanda soggettiva, di

gives an angle of thought of preserved similarities and also what they are ( different / alike ) deep down

Il confronto tra i due ti distrae da ciò che ciascuno è stato progettato per esprimere rapidamente.

Un switch sintetizza centralmente il confronto in modo da poter seguire il flusso in base ai suoi casi.

Mentre if descrive una singola condizione per inserire un blocco.

Fondamentalmente il codice "si legge" in modo diverso.

Ad esempio, hai un word nella tua testa e vuoi cercarlo nel dizionario.

Un interruttore dovrebbe leggere come segue: tieni la lettera iniziale nella tua testa, quindi sfoglia l'alfabeto, quindi rinuncia se non inizia con quella lettera.

Mentre un gruppo di blocchi if else dovrebbe leggere come segue: la parola inizia con la lettera? ripetuto molte volte, quindi rinunciare.

Se stai cercando di spiegare come funziona un interruttore su un nuovo programmatore (chi ha familiarità con i blocchi, potrebbe essere più semplice spiegarlo come:

if( boolean_expression_1 ) {
  statement_1;
  return;
}

if( boolean_expression_2 ) {
  statement_2;
  return;
}

default_statement;
return;

Ora l'esempio precedente rompe ciò che viene generalmente insegnato nelle scuole, ma tornare presto e tornare spesso a volte è più facile leggi e altrettanto veloce in un vm basato su stack.

Dovrebbero esserci ottimizzazioni per gli switch sulle primitive, quindi la scelta di quale controllo del blocco da usare dovrebbe essere basata su ciò che si sta confrontando.

Ricorda che le lunghe dichiarazioni switch e if tendono a diventare molto prolisse, difficili da mantenere e anche a peggiorare le prestazioni in quanto sarebbe necessario controllare più condizioni.

Potresti prendere in considerazione un Hash di classi / funzioni anonime o un modello di comando, invece di lunghi blocchi di controllo con molte condizioni.

Hash e pattern di comando consentono al codice di eseguire più velocemente e migliora la manutenibilità del codice.

    
risposta data 23.10.2012 - 06:33
fonte

Leggi altre domande sui tag