2010-04-09 8 views
6
boolean r = false ; int s = 0 ; 
while (r == false) ; 
{ 
    s = getInt() ; 
    if (!(s>=0 && s<=2)) System.out.println ("try again not a valid response") ; 
    else r = true ; 
} 

Il testo non viene mai visualizzato anche se si immette un 3 o un 123 e il ciclo non termina mai. Cosa c'è di sbagliato qui?Cosa c'è di sbagliato in questo ciclo?

+0

Anche questo non è un ciclo infinito, quindi il tag 'infinite-loop' non ha senso. –

+3

In realtà è un ciclo infinito. 'while (r == false);' è un ciclo infinito che non fa nulla, dal momento che r è inizializzato su false. –

+7

Smetti di provare a mettere più cose su una linea. Più che altro, questo è ciò che ha causato il tuo problema. Una volta che hai l'abitudine di scrivere chiaramente, scoprirai che questo genere di cose accade molto meno. Imposta anche i tuoi avvisi in eclissi più in alto: dovrebbe aver indicato l'affermazione vuota. Non limitarti a risolvere questo problema, ma fissa le cause principali. –

risposta

32

Hai un punto e virgola dopo la condizione. Quando si utilizzano le parentesi graffe per specificare un blocco per il proprio while, non si utilizza un punto e virgola.

+2

davvero. questo è il problema – David

+5

Hehe ... 'while (r == false)/* DO NOTHING * /;' – Armstrongest

9

Rimuovere il carattere ';' dopo un po.

8

Altri hanno sottolineato il bug, ma il codice è spaventoso in altri modi che alla fine si inciampare:

if (!(s>=0 && s<=2)) System.out.println ("try again not a valid response") ; 
else r = true ; 

Questo è male perché si può facilmente intendere più di un'istruzione per l'esecuzione in caso di la clausola if o else. Utilizzare parentesi graffe ed evitare di mettere istruzioni condizionali su una sola riga:

if (!(s>=0 && s<=2)) 
{ 
    System.out.println ("try again not a valid response"); 
} 
else 
{ 
    r = true; 
} 

E 'più facile da leggere e molto meno probabile di introdurre difficili da vedere insetti.

+2

Non sono d'accordo sull'utilizzo di parentesi graffe. Se si tratta di una singola affermazione, è una singola affermazione. Come questione di stile, farò indentare ma non usare i curlies per le singole dichiarazioni ... comunque questa è una battaglia religiosa. – Armstrongest

+2

@Atomiton assolutamente, preferisco usarli tutto il tempo perché è probabile che torni e lo cambi a un certo punto, che è quando mi farò frottole se non li metto lì in primo luogo. Almeno mettili su una linea diversa - spero di essere d'accordo su questo :) –

+0

Non uso mai le parentesi graffe per una singola istruzione, e spesso torno e aggiungo altro, e non ho mai dimenticato per caso di aggiungere delle parentesi graffe e ho rovinato il mio flusso di controllo ... A meno che non abbia scritto python per un po 'e poi sia tornato in C, cioè. –

3

mentre (R == false)

dovrebbe essere

while (! R)

Nonostante quello che tutti gli altri ha detto circa il punto e virgola, che è quello che penso è sbagliato con esso :)

+1

'while while (r == false)' è più esplicito e leggibile. Suppongo che le persone potrebbero anche sostenere che dovrebbe essere "while (false == r)", ma lo odio. Ad ogni modo, non è che dovrebbe "cambiarlo" in '! R' perché' r' è un valore booleano quindi non importa in alcun modo, il che significa che è solo una questione di stile. –

+0

Seguendo coerentemente la convenzione 'r' e'!r' invece di 'r == false' e' r == true' evita l'errore di 'r = false' e' r = true' (che NON causerà un errore di compilazione in java). Se si desidera renderlo più esplicito e leggibile, rinominare 'r' in qualcosa come' continue' o 'found'. – ILMTitan

+1

continua è una parola chiave in modo da rendere un nome di variabile terribile. Hai ragione, però, cose come R e S sono nomi di variabili terribili. Usa un IDE moderno con completamento automatico e chiamalo come qualcosa di sensato, come fatto o trovato. – ajs410

3

+1 a Daniel DiPaolo. Ho pensato di pubblicare una risposta separata per fornire un chiarimento su perché è il caso.

Mentre i loop in Java possono essere scritti in due modi. Se c'è solo una riga al corpo del ciclo, è possibile scrivere in modo breve a mano:

while (true) 
    System.out.println("While loop"); 

Questo stamperà "While" sulla console fino a quando il programma termina. L'altra opzione è quella di specificare un corpo del ciclo tra parentesi graffe, come avete fatto in precedenza:

int i = 0; 
while (i < 10) { 
    System.out.println("i = " + i); 
    i++; 
} 

Questo stamperà "i = 0", "i = 1", ..., "i = 9" ciascuno su una linea separata.

Ciò che il codice che hai pubblicato confonde i due. Nel ciclo while, il parser Java si aspetta di trovare un'istruzione tra la condizione del ciclo while e il punto e virgola. Perché non trova una dichiarazione qui, il ciclo while viene eseguito, ma non fa nulla; non ha corpo Inoltre, poiché il ciclo non ha corpo, non vi è alcuna possibilità che la variabile r assuma un nuovo valore; la condizione è sempre valida e il loop non esce mai.

Se si dovesse negare la condizione nel ciclo while nel tuo esempio, vale a dire,

boolean r = false ; int s = 0 ; 
while (r != false) ; 
{ 
    s = getInt() ; 
    if (!(s>=0 && s<=2)) System.out.println ("try again not a valid response") ; 
    else r = true ; 
} 

(notare ho lasciato il punto e virgola erronea in là), si potrebbe scoprire che il vostro corpo del ciclo destinato avrebbe eseguito con precisione una volta, poiché il ciclo non funzionerebbe mai.

3

Oltre ad altri commenti, si dovrebbe anche cambiare il caso di

if (s < 0 || s > 2) 

E 'molto più comprensibile in questo modo.

+0

+1 Assolutamente, la negazione rende un compito ingrato leggere qualcosa che dovrebbe essere semplice. –

1

Risposta non correlata, vi consiglio davvero di seguire le linee guida sullo stile di Sun.

boolean r = false ; 
int s = 0 ; 
while (r == false) { 
    s = getInt() ; 
    if (!(s>=0 && s<=2)) { 
     System.out.println ("try again not a valid response") ; 
    } else { 
     r = true ; 
    } 
} 

Si potrebbe sbarazzarsi della variabile r e il if/else condizione di valutare se il risultato nel circuito è di per sé.

int s = 0; 

while((s = getInt()) < 0 || s > 2) { 
    System.out.println("Try again, not a valid response"); 
}