Ява пока, пока - PullRequest
       30

Ява пока, пока

8 голосов
/ 12 марта 2010

какое поведение я могу ожидать при запуске этого кода:

do while(testA) {

    // do stuff

} while(testB);

Будет ли он вести себя как:

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

Или:

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

Или что-то совершенно неожиданное?

Я задаю этот вопрос, потому что считаю его довольно неоднозначным, и для других людей, ищущих эту тему, не , потому что мне лень его проверять.

Ответы [ 6 ]

7 голосов
/ 12 марта 2010

Это эквивалентно вашему первому блоку:

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

Соответствующие части грамматики Java при синтаксическом анализе:

DoStatement:
    do Statement while ( Expression ) ;

Statement:
    WhileStatement

WhileStatement:
    while ( Expression ) Statement

Statement:
    Block

Block:
    { BlockStatements_opt }

Вы видите, что компилятор Java будет анализировать это как do <WhileStatement> while ( Expression ) ;. Это единственный действительный способ анализа написанного вами кода.

Имейте в виду, что у него нет специального правила для анализа этой конструкции. Человек просто начинает путать чтение из-за необычного способа написания цикла do-while. При обычном использовании do-while всегда пишется как do { ... } while с явными фигурными скобками.

3 голосов
/ 12 марта 2010

Это действительно работает, но поведение зависит от того, в каких условиях вы тестируете. Например. этот код:

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

выходы:

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

Так что работает как:

while(j>0) {

}

Принимая во внимание обмен имен переменных:

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

Вывод:

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

Похоже, что он ведет себя так же, как и в первом случае (то есть рассматривается первое время), но здесь приложение не завершается!


Резюме:
В то время, когда testA больше не удовлетворен больше и testB также не удовлетворен , код работает как обычный цикл while(testA){}.
Но: Если в момент, когда testA больше не удовлетворено , testB все еще удовлетворено , цикл равен не выполняется больше, и скрипт не заканчивается . Это применимо только в том случае, если необходимо изменить условие «внешнего» цикла внутри цикла.

Обновление: И после прочтения другого ответа, я понимаю, что это именно то, что поведение вложенного цикла do-while - while.
В любом случае, извлеченный урок: не используйте этот синтаксис, потому что он может сбить вас с толку;)

1 голос
/ 12 марта 2010

ведет себя как

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

Итак, этот блок кода анализируется следующим образом:

do {блок кода}, в то время как testB имеет значение true. Где {блок кода} - это внутреннее время.

Это, конечно, немного необычно писать такой код:)

1 голос
/ 12 марта 2010

"do {} while();" - это одна конструкция, а "while(){}" - это другая.

Нет такой вещи, как "do while";вы случайно вкладываете их и используете тот факт, что {} является необязательным для отдельных инструкций.

Другими словами, это допустимый синтаксис:

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

И, как в if-последовательности, блок обрабатывается как одно утверждение.

То есть, ваш первый возможный ответ - правильный, где "while(){}" - это единственная не заключенная в скобки вещь внутри внешнего "do {} while(); "

1 голос
/ 12 марта 2010

Ответ № 1. Он будет продолжать цикл до тех пор, пока удовлетворено testB, но не выполнит код, если testA не выполнено.

0 голосов
/ 12 марта 2010

Я не думаю, что этот код является законным.

do while(testA) {

        // do stuff

    } while(testB);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...