2015-05-28 15 views
5

Sto passando attraverso l'esercitazione this sulla programmazione C. Dice:Istruzione switch: la logica è diversa in C v/s. altri linguaggi come Java?

L'istruzione di commutazione è in realtà completamente diversa (dalle altre lingue) ed è davvero una "tabella di salto". Invece di espressioni booleane casuali, è possibile inserire solo espressioni che generano numeri interi e questi numeri interi vengono utilizzati per calcolare i salti dalla parte superiore dell'interruttore alla parte che corrisponde a tale valore. Ecco un codice che analizzeremo per comprendere questo concetto di "jump tables".

Ma, casi di un'istruzione switch deve essere confrontato fino a quando viene trovata una corrispondenza (altrimenti di default viene restituito.)

Come è diverso da più istruzioni if-else, allora? O è solo uno zucchero sintattico? Mi sto perdendo qualcosa di importante qui?

+3

L'articolo si collega a spiega esattamente come un'istruzione switch può essere ottimizzato per utilizzare una tabella di salto, piuttosto che una catena di confronti. Hai letto questo? –

+0

In realtà è così che viene implementato in Java e sospetto che altri linguaggi siano basati su C. –

+0

La citazione si riferisce a Ruby come diversa. –

risposta

3

Sembrerebbe che il modo in cui è implementato dipende dal compilatore. How Switch case Statement Implemented or works internally?

ma in generale un'istruzione switch ha una pre-condizione che permette al compilatore di ottimizzare lo diversa da solo se le dichiarazioni, che è che la voce che si sta confrontando contro è sempre un tipo intero (char/int/lungo).

Altri linguaggi consentono di utilizzare primitive che possono essere valutate in fase di compilazione come variabili di istruzione switch (stringa in C#).

Ma in generale, a parte la potenziale accelerazione (e il fall-through che può accadere se non si interrompe), non c'è differenza comportamentale da un gruppo di if.

2

L'implementazione Java è analoga a quella di GCC 4.8.javac compila a:

  • tableswitch se la tabella è compatto, che è O (1)
  • lookupswitch se non, che è un O (log (n)) ricerca binaria

Un'analoga tecnica è usata da GCC:

  • O (1) jump tabella se compatto con *%rax
  • O (log (n)) altrimenti se la ricerca binaria altrimenti

Dove la definizione di compatte sono disponibili all'indirizzo:

Per osservare ciò, basta decompilare i casi di test minimi:

  • in Java con javap
  • in C con objdump -S

esempio Compact:

switch (i) { 
    case 0: 
     j = 0; 
    break; 
    case 1: 
     j = 1; 
    break; 
    case 2: 
     j = 2; 
    break; 
    case 3: 
     j = 3; 
    break; 
    case 4: 
     j = 4; 
    break; 
    case 5: 
     j = 5; 
    break; 
}; 

esempio non compatta:

switch (i) { 
    case 0: 
     j = 0; 
    break; 
    case 1: 
     j = 1; 
    break; 
    case 0x10: 
     j = 2; 
    break; 
    case 0x100: 
     j = 3; 
    break; 
    case 0x1000: 
     j = 4; 
    break; 
    case 0xFFFFFFF: 
     j = 5; 
    break; 
};