Подтвердить что ты не робот

Существуют ли случаи, когда while/do-while необходимо использовать вместо for?

Это долгая дискуссия между мной и моим учителем. Может ли быть ситуация, когда вместо цикла while/do - while можно использовать <<20 > цикл не может? Другими словами, существует ли конкретный случай, когда a for -loop не будет работать вместо цикла while; while/do - while каким-либо образом "отличным" от for?

4b9b3361

Ответ 1

Нет, такой ситуации нет. Каждый цикл do - while может быть записан в терминах while -loop (путем выполнения тела один раз перед циклом) и наоборот. В свою очередь, каждый while -loop

while (X) {
    ...
}

может быть записано как

for (; X;) {
    ...
}

то есть. мы опускаем инициализацию и инструкцию инкремента. Мы также можем конвертировать из for обратно в while путем правильного размещения инициализации и приращения.

Короче говоря, всегда можно преобразовать из одного варианта цикла в любой из двух других. for -loops просто дает вам возможность ограничить область действия переменной управления циклом и делать любое увеличение в верхней части. Само собой разумеется, что во многих случаях один конкретный вариант цикла имеет смысл использовать больше, чем другие; каждый из них имеет свои конкретные варианты использования.

Также обратите внимание, что fun не просто заканчивается циклами: он также позволяет преобразовать каждый цикл в рекурсивную функцию и наоборот (хотя на практике могут быть ограничения для этого, например, цикл, который работал нормально, при преобразовании в рекурсивную функцию, создает ошибку).


[I] s while/do - while каким-либо образом "отличным" от for?

Это не так. Например, байт-код следующих двух фрагментов идентичен:

int x = 0;
while (x < 10) {
    x++;
}

и

int x = 0;
for (; x < 10;) {  // or: for (; x < 10; x++) {}
    x++;
}

оба становятся:

   0: iconst_0      
   1: istore_1      
   2: goto          8
   5: iinc          1, 1
   8: iload_1       
   9: bipush        10
  11: if_icmplt     5
  14: return 

В комментариях о for -each были разговоры о том, что они могут быть по существу отличными от других типов циклов. Это абсолютно неверно; for - все петли представляют собой чистый синтаксический сахар вокруг итераторов (или цикл по массивам). Каждый цикл for -each также может быть преобразован в каждый из других типов циклов. Вот пример:

for (String s : l) {  // l is a list of strings
    System.out.println(s);
}

и

String s;
Iterator<String> iter = l.iterator();  // l is a list of strings
while (iter.hasNext()) {
    s = iter.next();
    System.out.println(s);
}

оба становятся:

  24: invokeinterface #33,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
  29: astore_3      
  30: goto          50
  33: aload_3       
  34: invokeinterface #39,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
  39: checkcast     #19                 // class java/lang/String
  42: astore_2      
  43: getstatic     #45                 // Field java/lang/System.out:Ljava/io/PrintStream;
  46: aload_2       
  47: invokevirtual #51                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
  50: aload_3       
  51: invokeinterface #57,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
  56: ifne          33

Ответ 2

Нет, вы всегда можете переписать цикл for как цикл while, и все время выглядите как цикл for.

<init>
while (condition) {
...
<increment>
}

эквивалентно:

for (<init>; <condition>; <increment>) {
...
}

Ответ 3

Другие ответы уже рассмотрели эквивалентность между циклами while и циклом for. То есть

while(<expr>) {
  <body>
}

эквивалентно

for(;<expr>;) {
}

Обратите внимание, что подобное сокращение может быть выполнено с помощью цикла do - while. Любой цикл do - while

do {
  <body>
} while(<expr>);

функционально эквивалентно

for (boolean firstIter = true; firstIter || <expr>; firstIter = false) {
  <body>
}

Ответ 4

"Абсолютно"? Я бы сказал, нет. Однако тест после цикла aka do-while, в то время как в Java потребуется довольно запутанное условие "для". Это возвращает к логическому абсолюту: условие должно оценивать true или false.

Так что, хотя я не могу предусмотреть случай, когда компилятор не может манипулировать в выполнении правильной логики, я могу видеть в очень коротком порядке, где любой, кто поддерживает вашу программу, может захотеть, чтобы вы побили камнями (или, возможно, думаете, что уже были).

В соответствующей заметке вы ничего не можете сделать на Java, которая не может быть выполнена на машинных языках. Но есть много и много действительно хороших причин для отказа от использования машинного языка. Большинство из них одинаково применимы, когда вы пытаетесь получить "симпатичный" код. Все это весело и игры, пока вы не по телефону с сердитым клиентом в 0300, или с вашим боссом, или с обоими.