2010-03-12 13 views
8

jakie zachowanie mogę się spodziewać, kiedy uruchomić ten kod:Java zrobić, gdy, podczas

będzie zachowywał się jak:

do { 
    while(testA) { 
     // do stuff 
    }  
} while(testB); 

Lub:

if(testA) { 
    do { 
     // do stuff 
    } while(testA && testB); 
} 

Albo coś zupełnie niespodziewany?

Zadaję to pytanie, ponieważ uważam, że jest to dość niejednoznaczne, a dla innych osób szukających na ten temat, nie, ponieważ jestem leniwy, aby go przetestować.

+12

Zachowanie, którego należy się spodziewać, to to, że współpracownik uderza Cię kijem. – voyager

+0

@voyager Na szczęście nie mam żadnych współpracowników, na których należy uważać; Niemniej dziękuję za poradę! – Pindatjuh

Odpowiedz

6

Jest to odpowiednik pierwszego bloku:

do { 
    while(testA) { 
     // do stuff 
    }  
} while(testB); 

odpowiednimi częściami Java grammar podczas analizowania tego są:

DoStatement: 
    do Statement while (Expression) ; 

Statement: 
    WhileStatement 

WhileStatement: 
    while (Expression) Statement 

Statement: 
    Block 

Block: 
    { BlockStatements_opt } 

Widać, że kompilator Javy będzie analizować ten jako do <WhileStatement> while (Expression) ;. To jedyny prawidłowy sposób analizy kodu, który napisałeś.

Należy pamiętać, że nie ma żadnej specjalnej reguły do ​​parsowania tej konstrukcji. Po prostu jest to mylące dla człowieka do czytania ze względu na niezwykły sposób zapisu pętli do-while.W normalnym użyciu do-while jest zawsze zapisywane jako do { ... } while z jawnymi nawiasami klamrowymi.

1

Odpowiedź jest # 1. Będzie kontynuował pętlę tak długo, jak długo będzie spełniony testB, ale nie wykona kodu, jeśli testA nie zostanie spełniony.

+0

Jest to prawna składnia (JDK 1.6). Dlaczego więc miałby to być nielegalny kod? Proszę wytłumacz. – Pindatjuh

+0

Masz rację, testowałem to, a odpowiedź brzmi # 1. Edytowałem swoją odpowiedź. –

1

"do {} while();" jest jednym konstruktem, a "while(){}" jest kolejnym. Nie ma czegoś takiego jak "do while"; nieumyślnie je zagnieżdżasz i wykorzystujesz fakt, że {} jest opcjonalne dla pojedynczych instrukcji.

Innymi słowy, jest to składnia prawna:

do System.out.println("Hello World") while (true); 

I podobnie jak w if -statements, blok jest traktowany jako pojedynczej instrukcji.

To znaczy, twoja pierwsza możliwa odpowiedź jest właściwa, gdzie „while(){}” jest jednym non-nawias rzeczą wewnątrz zewnętrznej „do {} while();

1

Zachowuje się jak

do { 
    while(testA) { 
     // stuff 
    } 
} while(testB); 

So , ten blok kodu jest analizowany w następujący sposób:

zrobić {blok kodu} podczas gdy testB jest prawdziwy. Gdzie {blok kodu} jest wewnętrznym, podczas gdy.

To z pewnością nieco rzadkością, aby napisać kod tak :)

0

Nie sądzę, kod ten jest legalny.

do while(testA) { 

     // do stuff 

    } while(testB); 
+0

To jest. Spróbuj i zobacz. –

3

To działa, ale zachowanie zależy od warunków, które testujesz. Na przykład. ten kod:

int i = 2; 
    int j = 4; 
    do while(j > 0) { 
     i--; j--; 
     System.out.println("i:" + i + " j:" + j); 
} while(i > 0); 

wyjścia:

i:1 j:3 
i:0 j:2 
i:-1 j:1 
i:-2 j:0 

Więc jak to działa:

while(j>0) { 

} 

Zważywszy, wymieniając nazwy zmiennych:

do while(i > 0) { 
    //.. same as above 
} while(j > 0); 

Wyjście jest:

i:1 j:3 
i:0 j:2 

Wygląda na to, że zachowuje się tak samo jak w pierwszym przypadku (tj pierwsza chwila jest rozważana), ale tutaj, aplikacja się nie kończy!


Podsumowanie:
W momencie testA jest niezadowolony już i testB jest również niezadowolony, kod działa jak normalny while(testA){} pętli.
Ale: Jeżeli w momencie testA jest nie jest już spełniony, testBjest nadal spełnione, pętla jest nie wykonywane dłużej i skrypt jest nie kończące. Dotyczy to tylko sytuacji, gdy warunek "zewnętrznej" pętli musi zostać zmieniony wewnątrz pętli.

Aktualizacja: i po przeczytaniu innej odpowiedzi, zdaję sobie sprawę, że to jest właśnie zachowanie zagnieżdżonych do-while - while pętli.
W każdym razie, lekcja uczy się: nie używaj tego rodzaju składni, ponieważ może Cię to zmylić;)

+0

Nie kończy się, ponieważ po osiągnięciu 0 pętla wewnętrzna już nie działa - i dlatego j nigdy nie może osiągnąć 0. –

+0

Interesujące, to oczywiście dlatego, że zewnętrzna pętla 'do while' będzie pętla, ale zawartość tego 'do while' nie zapętla się, ponieważ wewnętrzna pętla nie spełnia warunku! Dziękuję za testy. – Pindatjuh

Powiązane problemy