2010-07-10 8 views
18

Alcuni giorni fa ho avviato un rapido progetto open source e, quando alcuni compagni hanno guardato il codice su svn, uno di loro mi ha detto che usare l'istruzione break all'interno di un ciclo for è considerato dannoso e non dovrebbe essere fatto.La rottura di un ciclo "for" usando "break" è considerata dannosa?

ha aggiunto, però, che avrei trovato diversi casi di break istruzioni all'interno for loop sul codice sorgente del kernel di Linux, ma che era solo perché solo Linus Torvalds e Chuck Norris sono stati autorizzati a usarlo e nessun altro.

Cosa ne pensi? Non vedo alcun problema nell'uso di break all'interno di un ciclo for. A mio parere, l'emulazione del comportamento di break utilizzando variabili booleane o qualcosa di simile aggiunge un notevole overhead e rende il codice meno semplice.

Inoltre, non c'è spazio per il confronto con goto, perché break non può modificare arbitrariamente il flusso del programma da un punto all'altro. Lo fa goto.

+2

Domanda duplicata: http://stackoverflow.com/questions/216359/break-statements-in-the-real-world E un altro, chiuso come duplicato: http://stackoverflow.com/questions/616339/ is-break-evil –

+0

Penso che 'continue' sia considerato" dannoso ", nello stesso campionato di" goto "(entrambi possono essere utili, ma entrambi possono oscurare il codice). 'break' mi sta bene, personalmente. –

+2

Uso 'break' molto spesso, e' continue' abbastanza spesso pure. Penso che - e le stesse cose si applichino a molteplici esistenze, dichiarazioni di Delphi 'while', ecc. Ecc. - che nella maggior parte dei casi quando qualcuno dice" non usare il costrutto X ", allora lui/lei è non molto abituato a scrivere algoritmi complessi e/o che non ha molta esperienza nella lingua a portata di mano. Perché, se uno ha molta esperienza con la lingua a portata di mano, allora si sa come usare questo costrutto, e se uno spesso scrive algoritmi complessi, allora si ameranno tutti questi costrutti. –

risposta

42

Non vedo alcun problema con l'utilizzo delle interruzioni. Ci saranno sempre circostanze in cui si desidera interrompere l'elaborazione di un ciclo e l'utilizzo di un valore break; ha molto più senso (e lo rende più leggibile!) Rispetto all'impostazione del contatore di loop fino a un valore che farebbe fermare il ciclo alla successiva iterazione.

+7

Non vedo nulla con l'uso di goto. Ci saranno sempre circostanze in cui si desidera interrompere l'elaborazione di un ciclo molto annidato e l'utilizzo di goto; ha più senso (e lo rende più leggibile!) che avere valori booleani per dirti quando uscire dai loop. –

39

obbligatorio:

XKCD Goto

Il punto è che non si dovrebbe evitare puramente per motivi di cattiva pratica (o velociraptor), ma prendere in considerazione caso per caso.

Si tratta di chiarezza. Come hai detto, non devi mai usarlo, ma in alcuni casi promuove la leggibilità. È utile quando il ciclo di solito termina normalmente, ma in rari casi bisogna salvarlo. I loop che di solito (o sempre) interrompono sono più di un odore di codice (ma potrebbero comunque essere appropriati).

+11

+1 per fornire una buona risposta con questo fumetto. Ricordo di aver visto una risposta fortemente ribaltata che era questo fumetto e nient'altro, ugh. – Maulrus

1

Penso che dipenda dal contesto. Sebbene possa essere uno stile di codifica "cattivo" in alcune situazioni, non riesco a pensare a un caso in cui sarebbe dannoso.

In effetti, in alcuni casi lo consiglierei. Ad esempio, se stavi utilizzando una ricerca lineare, in ogni caso (ad eccezione del caso peggiore), uno break migliorerebbe la tua velocità. Penso che rompere il loop quando hai trovato il tuo ago sarebbe perfettamente accettabile, e sarebbe più leggibile che scherzare con la variabile loop (che potrebbe non essere utilizzata solo per il ciclo, a seconda del programma) o avvolgere il corpo del loop in un blocco if. (E l'altra opzione, un if che contiene continue, combina il peggiore dei due mondi:. Logica del ciclo di avvolgimento in un blocco if, e il povero stile di codifica inveito contro da persone come i tuoi amici che non amano break)

+0

Non dovresti raccomandare una rottura per motivi di prestazioni. I compilatori di solito possono ottimizzare le variabili di stato. – Artelius

+0

Punto giusto. Il punto che stavo cercando di fare era se, per esempio, sto eseguendo una ricerca lineare su un gran numero di elementi e trovo quello che sto cercando all'indice 2, preferirei di gran lunga smettere di guardare piuttosto che continuare a scorrere su i restanti elementi che so che non voglio D'altra parte, se so che avrò un gran numero di elementi, probabilmente non andrei per la ricerca lineare, comunque. –

20

Non solo non c'è alcun problema nell'usare break, direi che chiunque abbia detto che è "considerato dannoso" è assolutamente sbagliato.

break è una funzione del linguaggio utilizzata per interrompere un ciclo: è possibile utilizzare goto, ma in questo caso si incorre nell'ira (appropriata) del fumetto XKCD riportato di seguito. Potresti usare una bandiera nella condizione, ma ciò ostacola la leggibilità. break non è solo il modo più semplice, ma anche il modo più chiaro di uscire da un loop.Usalo come doveva essere usato.


Edit: Per ottenere un quadro più ampio qui: quando si sta scrivendo del codice, il principio guida di "Dovrei usare caratteristica del linguaggio X o Y" dovrebbero essere "in che modo si tradurrà in più codice elegante "? L'eleganza, nel codice, è più o meno un'arte, ma la definirei un buon equilibrio tra la leggibilità e l'efficienza algoritmica (leggi: non micro-ottimizzazioni). La leggibilità è determinata dalla lunghezza, dalla complessità del codice, ecc. Un boost di una sola riga :: bind può essere molto più difficile da leggere & di un loop di 3 linee.

Se una funzione di linguaggio può aiutare a scrivere codice che è più facile da capire mentre si fa il lavoro, quindi usarlo. Ciò si applica a break, goto, eccezioni C++, ecc. Non seguire una "X è (male | considerato dannoso)" alla cieca - applicare ogni volta buon senso e logica.

2

C'è un paradigma che ogni loop dovrebbe avere solo un punto di uscita (come una funzione dovrebbe avere solo un ritorno). Questo ha a che fare con la leggibilità. Troppi punti di uscita possono rendere il codice molto difficile da capire. Inoltre, è importante se si desidera eseguire la verifica del codice (ovvero provare matematicamente se il proprio codice è corretto).

Tuttavia, le linee guida sono spesso lì per aiutare, ma non sono rigide. Ci sono probabilmente situazioni in cui una pausa è meglio che non usarla. Quindi, si dovrebbe essere pragmatici al riguardo, ma comprendere la ragione di tali principi per creare un buon codice.

1

L'incremento del contatore del ciclo anziché l'interruzione comporta anche il completamento dell'esecuzione dell'iterazione del ciclo, che può essere o meno desiderabile.
Naturalmente, si potrebbe avvolgere il resto in una clausola if, e poi farlo di nuovo quando ti rendi conto che devi verificare se per interrompere il ciclo più volte, e in breve capire perché la gente usa break;

11

Non solo non c'è alcun problema con break, è anche OK to use goto quando break non è sufficiente. Non temere anche i ritorni multipli.

Tutto quanto sopra si applica solo se rende il codice più facile da capire *.

* E se il vostro PHB gli permette ...

1

suggerisco questo algoritmo, se si sta pensando di utilizzare una determinata tecnica.

  • Se si considera buona pratica:
    • usarlo.
  • Se è non considerata buona pratica:
    • utilizzarlo solo se si giudica che sia la migliore soluzione a lungo termine.
  • Se si considera il male :
    • utilizzarlo solo se si giudica che sia la migliore soluzione a lungo termine e si è estremamente fiducioso nel tuo giudizio. Attenzione: le cose che sono considerate malvagie tendono ad essere apparentemente ingannevoli.

Direi che break; come "buona pratica non". Usalo quando rende il codice più leggibile, riduce la possibilità di bug, non complica il debug, ecc.

+0

Io uso pausa tutto il tempo ... –

7

Penso che il tuo compagno sia pazzo. break è perfettamente accettabile, perfettamente leggibile e perfettamente mantenibile. Periodo.