Цикл for
Цикл for используется в случаях, когда необходимо несколько раз выполнить блок кода и точно известно количество этих повторений.
Общая форма цикла for:
for(инициализация; условие; итерация)*операторы*/ >
Пример цикла for:
public class ForTick < public static void main(String[] args) < for (int i = 0; i < 10; i++) < System.out.println("Тик " + i); >> >
В первом параметре обычно выбирают какую-то переменную, с помощью которой будет подсчитываться количество повторений цикла. Её называют счетчиком. Эту переменную обычно называют i . Счётчику задают некоторое начальное значение. Для цикла for не рекомендуется в цикле изменять индекс цикла.
Во втором параметре указывают некоторое ограничение на счётчик (указывают, до какого значения он будет изменяться).
В третьем параметре указывают выражение, изменяющее счётчик после каждого шага цикла. Обычно это инкремент или декремент, но можно использовать любое выражение, где счётчику будет присваиваться некоторое новое значение.
Перед каждым шагом цикла (но после инициализации) проверяется условие повторения, если оно истинно, то в очередной раз выполняется тело цикла. При этом, тело цикла может не выполниться ни разу, если условие будет ложным в момент первой же проверки.
В первом параметре можно через запятую инициализировать несколько переменных, как это показано в следующем примере:
Java: Цикл For
Цикл while идеален для ситуаций, когда количество итераций неизвестно заранее, например, при поиске простого числа.
Когда количество итераций известно, предпочтительнее использовать цикл for . Посмотрим реализацию переворота строки через цикл for :
public static String reverseString(String str) < var result = ""; // Счетчик увеличивается с помощью инкремента. // Об этой операции мы поговорим ниже. for (var i = 0; i < str.length(); i++) < result = str.charAt(i) + result; >return result; >
Этот код можно описать так:
В определении цикла for есть:
- Начальное значение счетчика. Этот код выполняется ровно один раз перед первой итерацией
- Предикат — условие повторения циклов. Выполняется на каждой итерации. Точно так же как и в while
- Описание изменения счетчика. Этот код выполняется в конце каждой итерации
В остальном принцип работы точно такой же, как у цикла while .
Задание
Сэмвелл обнаружил, что его сообщения перехватываются в замке «Близнецы» и там читаются. Из-за этого их атаки перестали быть внезапными. Немного подумав, он разработал программу, которая бы шифровала сообщения по следующему алгоритму. Она бы брала текст и переставляла в нем каждые два подряд идущих символа.
App.encrypt("move"); // "omev" App.encrypt("attack"); // "taatkc" // Если число символов нечётное // то последний символ остается на своем месте App.encrypt("go!"); // "og!"
Реализуйте статический метод App.encrypt() , который принимает на вход исходное сообщение и возвращает зашифрованное.
Упражнение не проходит проверку — что делать?
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
- Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Мой код отличается от решения учителя
Это нормально , в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Прочитал урок — ничего не понятно
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.
Цикл for
Конструкция for управляет циклами. Команда выполняется до тех пор, пока управляющее логическое выражение не станет ложным.
Цикл for является наиболее распространённым циклом в программировании, поэтому его следует изучить. Цикл for проводит инициализацию перед первым шагом цикла. Затем выполняется проверка условия цикла, и в конце каждой итерации происходит изменение управляющей переменной. Выглядит следующим образом:
for(инициализация; логическое выражение (условие); шаг (итерация)) команда
Любое из трёх выражений цикла (инициализация, логическое выражение или шаг) можно пропустить. Перед выполнением каждого шага цикла проверяется условие цикла. Если условие окажется ложным, то выполнение продолжится с инструкции, следующей за конструкцией for.
Помните, что выражение инициализации выполняется один раз, затем вычисляется условие, которое должно быть булевым выражением.
Как правило, цикл for используют для перебора. В качестве имени первой переменной часто используют i (сокр. от init), но вы можете использовать любое имя.
for (int x = 0; x < 9; x = x + 1) mInfoTextView.append("\nЗначение x: " + x);
Третье выражение в цикле - шаг, то есть, на какое значение нужно изменить переменную. Строго говоря, в таком виде (x = x + 1) современные программисты не пишут, так как есть укороченная форма записи (x++). Предыдущий пример можно переписать по другому:
for (int x = 0; x < 9; x++)
Эта запись является классической и правильной, если нам нужно посчитать от 0 до 8. Может возникнуть соблазн написать, например, так:
for (int x = 0; x
Результат будет таким же, но такой код нежелателен. Старайтесь писать традиционно. Особенно это проявляется при работе с массивами.
Увеличение значения переменной на единицу - весьма распространённый случай. Но это не является обязательным условием цикла, вы можете установить шаг и с помощью умножения, вычитания и других действий. Например, мы хотим вывести процесс уменьшения жизней у очень любопытной кошки:
for (int life = 9; life >= 0; life--) mInfoTextView.append("\nУ кошки осталось жизней: " + life);
Попробуйте потренироваться на кошках . Например, выводим чётные числа.
for (int x = 0; x < 9; x += 2) mInfoTextView.append(" " + x); // между кавычками пробел
0 2 4 6 8
Если нужно выполнить несколько операторов в цикле, то используют фигурные скобки.
for (int kitten = 1; kitten
В этом примере выполняется цикл с выводом числа подсчитанных котят, а также выводится текст в текстовом поле. Кстати, это один из примеров неправильного кода, когда в текстовом поле девять раз подряд выводится одна и та же строка. Мы этого не замечаем, но в реальности процессор выполняет лишнюю работу и второй оператор безусловно нужно вынести за пределы блока кода, который относится к циклу. Подобные ошибки очень часто встречаются у начинающих программистов, которые забывают, как работает цикл.
Когда мы объявляем переменную в первой части оператора for(int i = 0; . ), то область видимости переменной ограничена телом цикла и эта переменная не доступна на другом участке кода. Это подходящий вариант, если переменная больше нигде не используется. При этом переменная имеет область видимости и продолжительность существования, совпадающие с видимостью и продолжительностью жизни самого цикла. Вне цикла переменная прекратит своё существование.
Если управляющую переменную цикла нужно использовать в других частях приложения, то её не следует объявлять внутри цикла.
int i; // эта переменная нам понадобится не только в цикле for(i = 0; i < 10; i++)< // что-то делаем >// можем использовать переменную где-то ещё x = i + 10;
С другой стороны, если видимость переменной ограничена в пределах цикла, то не будет никакого конфликта, если вы будете использовать одинаковые имена переменных в разных циклах for, так как они не будут друг другу мешать.
Использование нескольких переменных
Иногда требуется указать несколько переменных в инициализационной части цикла. Для начала посмотрим на стандартный пример:
int a, b; b = 4; for(a = 1; a
В данном цикле используются две переменные. Можно включить обе переменные в оператор for, чтобы не выполнять обработку второй переменной вручную:
int a, b; for(a = 1, b = 4; a
Как видно из кода, запятая служит разделителем для двух переменных. Теперь оба разделённых запятой оператора в итерационной части цикла выполняются при каждом выполнении цикла. Данный код считается более эффективным, хотя на практике встречается редко.
Части цикла могут быть пустыми.
Оставим пустым первое выражение.
int i = 0; for(; i < 10; i++)< // что-то делаем mInfoTextView.append("\n" + i); >
В следующем примере нет инициализационного и итерационного выражения:
int i; boolean kind = false; i = 0; for( ; !kind; )
А можно вообще все три части оператора оставить пустыми:
В этом случае создаётся бесконечный цикл, который никогда не завершится. Практического смысла данный код не имеет.
Работа с массивами
С обычными числами обычно не работают в цикле for. Гораздо чаще цикл используют при работе с массивами.
Основная разница между ними, что массив может состоять из неупорядоченных чисел, а число элементов может быть разным. К счастью, у массива есть специальное свойство length - длина массива. Первый пример можно переписать следующим образом.
int[] mice = < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 >; for (int i = 0; i < mice.length; i++) mInfoTextView.append(" " + mice[i]);
Мы создали массив из чисел от 0 до 9. Затем проходим в цикле, но на этот раз во втором операторе не используем число 9, а вычисляем длину массива. Такой гибкий подход позволят проделывать с массивами разные трюки - упорядочивать, сортировать, переворачивать и т.д.
Например, если мы хотим вывести числа в обратном порядке, меняем логику следующим образом. Теперь нам нужно начинать вывод не с 0, а с 9, т.е. int i = 9 или int i = mice.length - 1 (для универсальности). Шаг будет не увеличиваться, а уменьшаться, значит - i--. А условием станет достижение 0, т.е. i >= 0. Проверяем.
int[] mice = < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 >; for (int i = mice.length - 1; i >= 0; i--)
Аналог foreach
Во многих языках существует более компактная форма for для перебора элементов массивов - foreach. Конструкция foreach не требует ручного изменения переменной-шага для перебора - цикл автоматически выполняет эту работу.
В Java решили не добавлять новое ключевое слово, а просто сделали усовершенствованный вид цикла for, который имеет вид:
for(тип итер_пер : коллекция) блок_операторов
Для сравнения напишем цикл для вычисления суммы значений элементов массива традиционным способом:
int[] nums = < 1, 2, 3, 4, 5 >; int sum = 0; for(int i = 0; i < 5; i++) sum += nums[i];
Этот код можно переписать следующим образом:
int[] nums = < 1, 2, 3, 4, 5 >; int sum = 0; for(int i : nums) sum += i;
При прохождении цикла переменной i автоматически присваивается значение, равное значению следующего элемента массива nums. Таким образом, при первом прохождении переменная i содержит значение 1, при втором - 2 и т.д. Кроме того при таком способе исключается возможность ошибок выхода за пределы массива.
Для этого способа можно использовать массив или любой класс с интерфейсом Iterable.
Можно прервать выполнение цикла с помощью оператора break:
int[] nums = < 1, 2, 3, 4, 5 >; int sum = 0; for(int i : nums) < sum += i; if(i == 3) break; // останавливаем цикл, если значение равно 3 >
Учтите, что в цикле в стиле foreach итерационная переменная доступна только для чтения, так как она связана только с исходным массивом. Даже если вы измените её значение, то это не повлияет на работу с массивом.
Также можно использовать данный способ для многомерных массивов.
Поскольку каждый оператор for в стиле foreach перебирает элементы массива последовательно, начиная с первого и заканчивая последним, то данный способ удобен для многих операций. Например, для поиска значения в неупорядоченном массиве. Поиск прекращается после обнаружения нужного значения.
int[] nums = < 3, 1, 6, 4, 9, 5, 8, 2 >; int val = 5; boolean found = false; // ищем значение 5 в массиве for (int x : nums) < if (x == val) < found = true; break; >> if (found)
Так как у нас неупорядоченный список, то нам нужно последовательно пройтись по всем элементам. Если нам повезёт и нужное значение встретится при переборе, то выходим из цикла и идём спать .
Вложенные циклы
Также допустимо использование вложенных циклов, когда один цикл выполняется внутри другого:
int i, j; for (i = 0; i < 10; i++) < for (j = i; j < 10; j++) < mInfoTextView.append("*"); >mInfoTextView.append("\n"); >
В результате получим:
При вложенных циклах количество повторений перемножается. В предыдущем примере было 100 повторений. Например, можно написать таблицу умножения.
int i, j, a = 0; for (i = 1; i < 10; i++) < for (j = 1; j < 10; j++) < a = i * j; System.out.print(a + " | "); >System.out.println(); >
Результат смотрите в вкладке LogCat.
Цикл for является более удобным вариантом цикла while.
for(int i = 10; i > 0; i--)
Этот же вариант с while:
int i = 10; while(i > 0)
С помощью цикла можно рисовать красивые узоры, меняя координаты одной фигуры.
Треугольник Флойда
Составьте "Треугольник Флойда", который выглядит как набор чисел, которые увеличиваются на единицу. Например, треугольник с высотой шесть строк выглядит следующим образом.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
Java/Операторы цикла for, while, do . while
Где выражение в скобках определяет условие: пока ( while ) оно выполняется, будет выполняться выражение в фигурных скобках.
class WhileLoop public static void main (String[] args ) int a = 0; while(a 10) System.out.print(a); a++; > > >
Данный цикл выведет:
0123456789
Стоит обратить внимание, что число 10 выведено не будет, так как while это оператор предусловия.
Также обратите внимание на метод print использованный в этом коде, в отличие от println метод print не переводит курсор на новую строку.
Оператор do. while [ править ]
Конструкция оператора do while :
do Тело цикла; > while (условие выполения);
Отличие данного оператора от while только в том, что он является оператором постусловия (сначала выполнит, потом проверит).
То есть, даже если условие не выполняется никогда, всё равно действие будет выполнено один раз.
public class DoWhileLoop public static void main (String[] args) int i = 0; do System.out.print(i); i++; > while (i 10); System.out.println(); //Это можно использовать для простого перевода строки do System.out.print("Do. while is cool;"); > while (2 == 3); //Можно было написать и просто false > >
Данный цикл выведет:
0123456789
Do. while is cool;
Как видно из кода, несмотря на то, что 2 != 3 , строчка всё равно была выведена на экран.
Оператор for [ править ]
Конструкция оператора for :
for (Начальное значение переменной; Логическое выражение с переменной (условие выполнения цикла); Действие над переменной, после выполнения тела цикла) Операторы, которые будут выполнять цикл при условии, что логическое выражение - true; >
Цикл for использует переменную i и проверяя её значение выполняет операторы, после чего совершает над ней действие. Например:
class ForLoop public static void main (String[] args ) for (int i = 0; i 10; i++) System.out.print("Ku-Ku "); > > >
Данный цикл выведет:
Ku-Ku Ku-Ku Ku-Ku Ku-Ku Ku-Ku Ku-Ku Ku-Ku Ku-Ku Ku-Ku Ku-Ku