Specifiche delle dichiarazioni Switch e If

3

Perché abbiamo bisogno dell'istruzione switch se è presente l'istruzione if ? Perché non possiamo usare diversi if s come

if(a==1) do this1;
if(a==2) do this2;
...

invece di

switch (a) {
case(1): {do this1;break;}
case(2): {do this2;break;}
...
}

Il mio insegnante ha detto che la risposta è costruita su come funziona l'assemblatore, ma non ci ho mai lavorato.

Spiega, per favore, perché abbiamo sia switch che if ?

    
posta user114292 10.01.2014 - 09:11
fonte

3 risposte

18
  • switch è più conveniente da usare rispetto a una serie di if s: devi solo digitare l'espressione testata una volta e non devi digitare else if(...){} più volte. La leggibilità è la seconda proprietà del codice più importante dopo la correttezza, quindi è molto importante.
  • puoi facilmente esprimere che un caso ne sussume un altro con l'uso giudizioso o il non utilizzo di break tra i casi. Con if , non puoi facilmente esprimere che un blocco di codice deve essere eseguito per la condizione A e un altro per la condizione A o B.
  • switch su un piccolo valore integrale può essere implementato come una tabella di salto piuttosto che una serie di test. Ciò significa che il tempo di esecuzione della logica decisionale è costante anziché lineare. Nei loop interni, questo può fornire un'enorme accelerazione. (È teoricamente possibile per un compilatore costruire una tabella di salto da una serie di if s se può dimostrare che si comportano esattamente come farebbe un switch , ma questo è difficile da fare e costoso per il compilatore, ed è raramente. Utilizzando un switch esplicitamente afferma che stai facendo più test sulla stessa espressione, quindi è molto più facile rilevare il potenziale di questa ottimizzazione.)
risposta data 10.01.2014 - 09:19
fonte
2

Le sequenze di ifs sono fragili e una causa comune di errore. Le catene di if..else if sono anche peggio.

Ci sono tre cause principali di errore:

  1. Ristabilire la condizione di controllo
  2. Omissione di un'opzione o opzioni, in modo che non ci siano condizioni non soddisfatte, con conseguenze inaspettate per il codice.
  3. Inavvertitamente con condizioni di sovrapposizione.

Esempio di errore 1:

if (a == 0) ...
if (a = 1) ...
if (a == 2) ...

Guarda il secondo controllo. L'effetto è che se a non è zero, sarà sempre impostato su 1. Con un'istruzione switch non puoi farlo veramente; digiti la condizione solo una volta , in modo che tu possa sbagliare per tutto (che diventerà presto evidente) o giusto per tutto.

Il secondo e il terzo tipo di errore sono possibili con lo switch ma meno probabile, in primo luogo perché switch offre un'opzione predefinita e in secondo luogo perché il layout è molto più chiaro. Con ifs incatenati, digiti ripetutamente l'intero chec; con switch, è sufficiente digitare i valori previsti. Confronto:

if (objectX.checkFunc(x - y) == 0) ...
if (objectX.checkFunc(x - y) == 1) ...

a

switch(objectX.checkFunc(x - y) {
    case 0: ...
    case 1: ...
    default: ...
}

Ma la cosa più importante che ho detto in tutto questo è questa: digiti la condizione solo una volta . La duplicazione del codice è sempre un cattivo odore. Non ripeterti se hai un modo pulito per evitarlo.

Detto questo, non dimenticare l'istruzione break . La maggior parte delle altre lingue che hanno qualcosa come switch non consentono il fall-through; in quelle lingue, è molto più difficile avere condizioni di sovrapposizione nello switch piuttosto che in una sequenza di istruzioni if. In C / C ++ questo non è il caso; la caduta accidentale è l' errore più comune con switch.

    
risposta data 10.01.2014 - 11:13
fonte
-1

Concettualmente tutti pensiamo a una dichiarazione di commutazione come una serie di dichiarazioni if. Concettualmente, questo è il modo corretto di pensare all'istruzione switch.

Tuttavia, il compilatore ha più informazioni su cui lavorare quando compila un'istruzione switch. Quando si compila un'istruzione if, ciascuna istruzione if deve essere trattata in modo indipendente. Il compilatore non ha modo di determinare che una serie di istruzioni if siano correlate.

Ovviamente questo non è vero con un'istruzione switch. Il compilatore capisce perfettamente che ogni caso nell'interruttore è correlato l'uno all'altro. Il compilatore ora può generare codice più veloce di una serie di istruzioni if.

Ad esempio, non è raro che un compilatore generi un albero di ricerca binario per un insieme di casi sufficientemente ampio. In altri casi, il compilatore può generare una tabella di salto. I compilatori semplificheranno anche gli intervalli in modo che possa generare più facilmente una tabella di salto.

Il caso che fai notare qui potrebbe causare la generazione di una tabella di salto piuttosto che qualsiasi confronto. Il compilatore genererebbe un semplice controllo dell'intervallo per assicurarsi che i salti funzionino, quindi salta su un tavolo esattamente per l'istruzione corretta. Nessun confronto aggiuntivo e ogni caso richiede lo stesso tempo per l'esecuzione.

Quindi, l'istruzione switch fornisce al compilatore maggiori informazioni su cui lavorare, il che può portare a un codice ottimizzato (leggi più veloce) migliore.

    
risposta data 10.01.2014 - 17:51
fonte

Leggi altre domande sui tag