2009-07-23 13 views
15

Quando utilizzo le parentesi attorno al blocco di codice case in C++ per localizzare le variabili dovrei inserire break all'interno o all'esterno del blocco?dove inserire l'istruzione switch/case con blocchi

case FOO: // 'break' inside 
    { 
    int i; 
    doStuff(); 
    break; 
    } 

case BAR: // 'break' outside 
    { 
    int i; 
    doStuff(); 
    } 
    break; 

Grazie.

+0

potresti chiarire per favore, la domanda come è non ha senso ... –

+4

Penso che abbia perfettamente senso –

+0

Ha senso così com'è, ma un esempio di codice lo renderà comunque più chiaro – dmckee

risposta

19

È una questione di stile.

Vorrei mettere break all'esterno della parentesi graffa solo per renderlo più leggibile.

+5

Accetto. Non sono d'accordo (penso che sia più leggibile all'interno, ma questo è solo il mio stile: -0) –

2

Dipende veramente dalla logica del codice e dal modo in cui utilizza le parentesi graffe, ma per una risposta corretta, se ne metti una all'interno, prova a inserirle tutte all'interno.

14

Lo metti dove vuoi. Assicurati di rimanere coerente durante l'intero progetto. (Personalmente, l'ho messo fuori.)

+0

regole di coerenza! +1 – xtofl

+0

Consistenza +1 :-) –

+0

+1 I +1 ha rovinato la coerenza di @xtofl. @MartinYork;) –

4

Io di solito messo il break all'interno delle parentesi graffe, in questo modo:

switch (foo) { 
    case bar: { 
     int x = 5; 
     printf("%d\n", x); 
     break; 
    } 
    case baz: { 
     // ... 
     break; 
    } 
} 

Tuttavia, dal momento che è la mia regola sono libero per romperlo (no pun intended) ogni volta che voglio.

1

A mio parere è necessario evitare variabili locali e blocchi nelle istruzioni switch. Inoltre, dovresti evitare istruzioni di commutazione lunghe, complesse o anche a cascata. Ma nessuna regola senza eccezione ... Preferisco scrivere la frase break dopo il blocco.

4

Dovrebbe apparire dopo.

Ad esempio:

switch(value) 
{ 
    case 0: 
    { 
    // this ... 
    // that ... 
    // and the other ... 
    } 
    break; 
} 

testo a cura di sotto

Questo principalmente per migliorare la leggibilità e la manutenibilità ecco un esempio.

switch (value) 
{ 
    case 0: 
    // Do this... 
    // Do that... 
    break; 
    case 1: 
    //and the other... 
    break; 
} 

e

switch (value) 
{ 
    case 0: 
    // Do this... 
    // Do that... 
    if (ObjectWithinScope.Type == Fault) 
    break; 
    case 1: 
    //and the other... 
    break; 
} 

Ora confrontate con

switch (value) 
{ 
    case 0: 
    { 
    // Do this... 
    // Do that... 
    } 
    break; 
    case 1: 
    //and the other... 
    break; 
} 

e

switch (value) 
    { 
     case 0: 
     { 
     // Do this... 
     // Do that... 
     if (ObjectWithinScope.Type == Fault) 
     break; 
     } 
     case 1: 
     { 
     //and the other...   
     } 
     break; 
    } 

Quando si comincia a incontrare casi di istruzioni switch nidificate si può ottenere davvero molto confusa .

Solo un puntatore.

Ora alcuni di voi si stanno ancora chiedendo cosa sto ottenendo. Ecco qui. Un pezzo di codice legacy ha smesso di funzionare e nessuno è riuscito a capire perché.E tutto si riduceva ad un pezzo di codice strutturato come il seguente:

switch (value) 
    { 
     case 0: 
     { 
     // Do this... 
     // Do that... 
     if (ObjectWithinScope.Type == Fault) 
     break; 
     } 
     case 1: 
     { 
     //and the other...   
     } 
     break; 
    } 

c'è voluto molto tempo per definire questo codice, ma controllando i registri delle modifiche è stato originariamente come followws:

switch (value) 
    { 
     case 0: 
     { 
     // Do this... 
     // Do that... 
     if (ObjectWithinScope.Type == Fault) 
      // *** A line of code was here *** 
     break; 
     } 
     case 1: 
     { 
     //and the other...   
     } 
     break; 
    } 

Certo, il codice originale non era coerente con se stesso, ma avendo l'interruzione tra parentesi graffe il codice veniva compilato quando una riga di codice veniva cancellata per sbaglio. Se la rottura fosse stata al di fuori delle parentesi, allora non avrebbe avuto.

+7

"dovrebbe"? perché? –

+0

Inserendolo dopo la leggibilità del blocco e la manutenibilità del codice è più chiaro - Ho modificato la mia risposta per mostrare un caso in questione. – ChrisBD

1

Non importa se tu e il tuo team fate la stessa cosa in modo coerente. Anche in questo caso, non è un grosso problema se i membri del team lo fanno diversamente.

Personalmente preferisco dopo. Il ragionamento è che dà una certa separazione tra il meccanismo dell'istruzione switch (saltando, eseguendo cose e uscendo) e il codice all'interno delle parentesi che è puramente coinvolto nel "fare" del caso.

esempio:

switch(value) 
{ 
    case 0: 
     { 
      // code here 
     } 
     break; 

    default: 
     { 
      assert(!"unhandled value in switch"); 
     } 
     break; 
} 

Io uso solo {} per un caso se ha bisogno di variabili locali, ma se uso {} per ogni caso, li ho messi su tutti i casi.

Di solito definisco sempre un caso predefinito per affermare se esiste un valore imprevisto. È sorprendente quanto spesso uno di questi suoni il fuoco per ricordarti di un caso mancante.

0

è una questione di stile, ma ho messo dopo quanto ho capito la definizione come:

switch (variable) 
{ 
    case expression: 
     statement; 
     break; 
    default: 
     statement; 
     break; 
} 

cui affermazione è o un singolo comando o di un blocco. L'interruzione è separata da questa affermazione o blocco. E sì, aggiungo una pausa dopo l'impostazione predefinita anche se è superflua. Ho anche SEMPRE mettere le parentesi attorno alla dichiarazione. Troppe volte ho aggiunto una sola istruzione a solo per rompere l'ambito. E aggiungo l'interruzione al valore predefinito in quanto ho cambiato il valore predefinito: a caso espressione: e ho aggiunto qualcosa dopo di esso. Il codice difensivo è tuo amico.

Tuttavia, posso solo trovare la documentazione per la definizione stessa tramite Microsoft come:

selection-statement: 
    switch (expression) statement 

labeled-statement: 
    case constant-expression : statement 
    default : statement 

che indicherebbe che dovrebbe essere all'interno.

Tuttavia, penso che all'esterno sia più chiaro dal punto di vista dei lettori, ma è certamente soggettivo.

0

Poiché lo standard non ti limita a scegliere la posizione per l'istruzione break puoi scegliere quello che ti piace. Personalmente sto utilizzando il seguente stile:

switch (some_var) { 
     case 1: { 
      // lot of code here 
     } break; 
     case 2: /* one call */ break; 
     case 3: /* one call */ break; 
     case 4: { 
      // lot of code here again 
     } break; 
    } 
4

Tutti sono d'accordo che vogliamo distinguere chiaramente riconoscibile tra la macchina switch/case... e le azioni reali eseguite in ogni caso.

Perciò, a meno che non ci sia davvero quasi nulla succede in ogni caso (assegnazione semplice o giù di lì), suggerisco di usare il switch come un mero dispatcher, e delegare le cose 'reali' alle funzioni di supporto.Questo risolve automaticamente il problema delle variabili caso-locali e rende obsoleta la necessità di parentesi graffe.

switch(operation) { 
    case cnegation: r = -value; break; 
    case cinversion: r = 1./r; break; 
    case cfaculty: { 
    double r = value; 
    while(value != 1) 
     r *= --value; 
    } 
    break; 
} 

dovrebbe quindi diventare

switch(operation) { 
    case cnegation : r = negate (value) ; break; 
    case cinversion: r = invert (value) ; break; 
    case cfaculty : r = faculty(value) ; break; 
} 
0

C'è molto da dire per lo stile di un solo utilizzando uno dichiarazione per ogni caso, e mai usare le parentesi. Ad esempio:

 
switch(cond) { 
default: foo(); break; 
case 0: bar(); break; 
case 1: baz(); break; 
} 

Utilizzando questo stile, la tua domanda è discutibile.

+0

Perché il downvote? La domanda è puramente di stile, e questa è una risposta di stile? –

1

Non mi piace inserire alcun tipo di parentesi in un'istruzione switch. Personalmente, se si tratta di un'operazione complessa, mi piace metterla in una funzione. Non c'è nulla di più fastidioso di vedere una dichiarazione di commutazione in cui tra ogni "caso" ci sono centinaia di righe di codice e in più alcune di esse sono ripetute in vari casi, il che rende impossibile la manutenzione.

Ad esempio:

switch(blah) 
{ 
case 1: 
    // do one thing 
    break; 

case 2: 
    doManyThings(); 
    break; 

default: 
    // something 
    break; 
} 
+0

Avere una variabile locale all'interno dell'istruzione case non significa che ho un'istruzione complessa con un sacco di codice all'interno. – jackhab

0

reale Risposta: compilatore non se ne cura. È una questione di preferenza.

Li ho inseriti, come lo google style guide.

Se si utilizzano le parentesi graffe, mi piace che la parentesi graffa di apertura sia sulla stessa colonna della parentesi graffa di chiusura (che differisce da Google).

switch (var) { 
    case 0: 
    { 
    ...  
    break; 
    } 
    case 1: 
    { 
    ... 
    break; 
    } 
    default: 
    assert(false); 
} 
0

Il mio take ... Vedi qui sotto per un esempio.

Rientra in tutti i casi di un interruttore e la staffa di chiusura dell'interruttore sotto la parola chiave switch, proprio come si farebbe in un'istruzione if. Quando necessario, stessa regola per ciascuna istruzione case: parentesi aperte dopo la semicolonna che segue l'istruzione case e chiudendole sotto la parola chiave case, quindi indentare il contenuto di ciascuna delle istruzioni case compresa la parola chiave break.

mantenerlo coerente (indentazione e staffe tirocini) e breve (non più di 5-10 righe di codice per case dichiarazione. Progetti complessi sono falliti a causa del mal rientrati switch affermazioni con troppo codice in loro.

switch (number) { 

     case 1: 
      logFileStderr(VERBOSE, "MESSAGE: switch without brackets...\n"); 
      break; 

     case 2: { 
      logFileStderr(VERBOSE, "MESSAGE: switch with brackets...\n"); 
      break; 
     } 

     default: 
      logFileStderr(VERBOSE, "WARNING: Unknown option...\n"); 
      break; 
    } 
Problemi correlati