Циклы for while repeat и оператор break в LUA

Циклы for while repeat в lua

Циклы for while repeat в lua

Приступаем к важной теме «циклы». Для начала определимся с тем что такое циклы, для чего они нужны и в каких случаях их применяют.

Циклы это выполнение одних и тех же действий несколько раз. Применение циклов позволяет очень сильно сокращать код. Из этого следует вопрос, можно ли обойтись без циклов? Теоретический да, обойтись без циклов можно, но правильно ли будет так поступать, нет не правильно.

Представьте следующую ситуацию. Вам необходимо найти на графике бар у которого цена закрытия равна 50. Предположим что график состоит из 3000 баров. Каким образом найти бар у которого цена закрытия равна 50? Необходимо сделать следующие. Нужно взять 1 бар, запросите его цену закрытия и сравнить с ценой 50, далее необходимо взять 2 бар, запросить его цену закрытия и сравнить с ценой 50, потом взять 3 бар, запросить его цену закрытия и сравнить с ценой 50 и так далее, пока не просмотрим все 3000 баров. Код программы будет выглядеть примерно так:

Если цена закрытия 1 бара = 50 тогда оповестить пользователя
Если цена закрытия 2 бара = 50 тогда оповестить пользователя
Если цена закрытия 3 бара = 50 тогда оповестить пользователя

Если цена закрытия 3000 бара = 50 тогда оповестить пользователя

Как видите такая простая задача, как поиск бара с определенной ценой закрытия, будет занимать как минимум 3000 строк. Есть ли у вас желание писать такой громадный код? Надеюсь что нет.

Посмотрите внимательно на написанный выше пример. Как видите строки абсолютно одинаковые, единственное что в них меняется это номер бара. Если мы организуем цикл и вместо номера бара будем подставлять число от 1 до 3000, нам потребуется использовать строку лишь только один раз.

Начало цикла. n изменять от 1 до 3000
Если цена закрытия n бара = 50 тогда оповестить пользователя
Конец цикла

Теперь наш код состоит из 3 строк. Строка где будет выполняться сравнение цены закрытия с ценой 50 будет выполнено 3000 раз, но номер бара будет меняться от 1 до 3000. Это теоретическое представление цикла показывает, что обходиться без цикла практически невозможно.

Переходим к практике. Необходимо разобраться какие циклы бывают в lua, как их необходимо описывать, а также как они работают.

Любой цикл состоит из 2 частей. Первая часть это объявление цикла. Вторая часть это тело цикла.

Первый вариант цикла for.

Простой вариант цикла for позволяет выполнить перечисление переменной в указанном диапазоне, как раз то что мы делали немного выше в теоретическом коде.

В этом примере объявление цикла описано во 2 строке, а тело цикла это строки под номерами 3, 4 и 5.

Для того чтобы не запрашивать цену закрытия бара в примере выше я просто сравниваю номер бара с 50. Переменная n меняется от 1 до 3000, включая и значение 3000 тоже. Как только n становится равным 50 выполняется условие и появляется сообщение, далее цикл продолжается.

Чуть более расширенную версию цикла for можно написать следующим образом

Как видите практически ничего не изменилось, единственное в объявлении цикла появилось еще одно число 1 после 3000. Этим параметром мы можем задавать шаг цикла. Так как в примере выше шаг установлен 1, то переменная n меняется как 1 2 3 4 5 и так далее. Если мы напишем шаг 2, то переменная n будет меняться как 1 3 5 7 9 и так далее, в этом случае переменная n не попадает в 50, а значит и сообщение не появится.

Точно также можно запускать и обратный цикл используя отрицательный шаг.

В этом примере переменная n меняется от 3000 до 1 в обратном порядке. Как только переменная n будет равняться 50, условие выполняется, и появится сообщение.

Второй вариант цикла for.

Второй вариант цикла for можно применять для перебора значений в массиве (таблице).

В примере выше у нас имеется таблица t, в которую мы записали несколько значений. В поля таблицы под номерами 1 2 3 4 5 записаны значения соответственно 10 20 30 40 50. Далее в поле под номером 10 записано значение 100, а в поле под номером 120 записано значение 1200.

После заполнения таблицы мы объявляем цикл, где переменная n будет перебирать индексы нашей таблицы, переменная val будет принимать значение поля указанного индекса, после in мы пишем в какой таблице перебирать индексы.

Если вы запустите этот код на выполнение, то возможно немного удивитесь, так как увидите всего 5 сообщений. Вы увидите номера индексов от 1 до 5 и их значения. Индексы под номерами 10 и 120 обработаны не будут. Дело в том что этот вариант цикла for перебирает лишь только идущие подряд индексы без пропусков, как только встречаются отсутствующий индекс, а в нашем примере это индекс номер 6, цикл прекращается.

Также этот вариант цикла не подходит для таблиц в которых индексы не являются числами например такой вариант:

Запустив такой код вы не увидите ни одного сообщения.

Третий вариант цикла for.

Рассмотрим еще один вариант как можно описать цикл for. Этот вариант как и предыдущий предназначен для перебора индексов в массивах (таблицах).

Посмотрите внимательно на этот и предыдущий коды, как говорится найдите отличие. На первый взгляд они абсолютно одинаковые но отличие всё-таки есть, ipairs(t) заменили на pairs(t). Будьте внимательны при написании, изменение всего в одной букве влияет на работу кода. Также для удобства имя переменной n заменили на key, это не является различием так как имена переменных могут быть абсолютно любыми.

Этот пример перебирает всю таблицу, запустив его на выполнение вы увидите 7 сообщений. Но если вы посмотрите на порядок отображения сообщений, то увидите, что они идут не в том порядке в котором мы их объявляли. Текущий вариант цикла for позволяет перебрать все поля таблицы, но порядок просмотра полей может быть абсолютно любым, об этом нужно помнить.

Цикл while в lua.

Ещё один вариант с помощью которого можно объявить цикл в языке lua является цикл while. Этот цикл не перебирает какие-то значения переменных как это делал цикл for, а выполняется до тех пор пока выполняется условие.

В третьей строке написано пока условие указанное в скобках выполняется, выполнять тело цикла.

Сначала переменная i у нас равна 1, так как 1 меньше 5 значит условие выполняется, следовательно перейти к выполнению тела цикла. В теле цикла описано показать сообщение «значение переменной i «, а так же к переменной i прибавить 1. Тело цикла заканчивается и переходим снова к проверке условия. Теперь переменные i равна 2, что так же меньше 5, значит условие выполняется, повторяем тело цикла. Когда переменная i будет равна 5, то условие уже не выполнится, а значит цикл прекратится. Следовательно последнее сообщение которое вы увидите запустив данный код будет «Значение i = 4». Условие может быть абсолютно любым, а не только сравнение чисел, главное если условие выполняется, то выполняется тело цикла, иначе цикл прекращается.

Цикл repeat — until в lua.

Последний вариант цикла в lua, который мы рассмотрим, очень сильно похож на предыдущий вариант while, но работает немного по-другому. Этот вариант также предусматривает проверку условия, но наоборот, как только условие выполнится цикл прервется.

В отличии от предыдущего варианта этот вариант цикла покажет пять сообщений, после чего прервется цикл. Так как тело цикла находится выше условия, то как минимум 1 раз тело цикла обязано выполниться.

Первое сообщение которое мы получим «Значение i = 1», потом к i прибавим 1, далее будет выполнена проверка 2 больше 5 ? — нет, значит цикл продолжается. Когда мы получим сообщение «Значение i = 4», после к i прибавим 1 и переменная i будет равна 5, производится проверка 5 больше 5 ? — нет, значит цикл продолжает работать. Появляется сообщение «Значение i = 5», прибавляем 1 и переменная i уже равна 6, при проверке условия 6 больше 5 ? — да, цикл прекращается.

Вот такие варианты циклов можно использовать при программирование на языке lua.

Оператор break

Для того чтобы выйти из любого описанного выше цикла раньше времени, существует специальный оператор break, который может прервать цикл в любой момент.

В этом примере в цикле используется условие которое всегда выполняется, а значит цикл сам по себе является бесконечным, он никогда не сможет закончиться, так как в условии указано Истина. Такой цикл можно прервать только принудительно, используя оператор break.

В этом примере использована дополнительно проверка на условие переменной i, когда переменная i будет равна 5 условие выполняется, будет вызван оператор break, который прервет цикл. Таким образом данный цикл покажет 5 сообщений и цикл прервется.

На этом мы заканчиваем тему с циклами, надеюсь всё понятно, по традиции все вопросы жду в комментариях.

Постоянная ссылка на это сообщение: https://k-pavel.ru/cikly-for-while-repeat-i-operator-break-v-lua/

avatar
3 Цепочка комментария
7 Ответы по цепочке
0 Последователи
 
Популярнейший комментарий
Цепочка актуального комментария
3 Авторы комментариев
Павел КашинскийИринаДмитрий Авторы недавних комментариев

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.

  Subscribe  
Новые Старые Популярные
Подписаться на
Ирина
Гость
Ирина

И ещё пара вопросов, если найдете время.
Какой цикл предпочтителен и почему (больше всего интересуют затраты памяти и время выполнения, конечно): while или repeat? Почему в функции main обычно используется while?
На просторах интернета вычитала о существовании функции foreach(), которая быстрее while. В руководстве Lua такого слова нет. Не знаете, что это?
Заранее спасибо за ответы и ещё раз за статьи!

Ирина
Гость
Ирина

Спасибо большое за ответ — очень полезен!

Ирина
Гость
Ирина

Павел, если знаете, подскажите, пожалуйста.
Для цикла вида

for n = a, b do тело цикла end

где a, b — заданные заранее переменные и a может оказаться больше b,

надо ли вводить дополнительную проверку на соответствие a<=b или цикл сам отвергнется?
Ну и "for n = b, a, -1 do тело цикла end" аналогичен?

Ирина
Гость
Ирина

Спасибо, Павел! Предельно понятно, как всегда. 🙂
Здорово это! При таком раскладе у меня циклов в 2 раза меньше получается. Нравится простота Lua!

P.S. (Вы не заметили, что во втором цикле, с шагом -1, я a и b местами поменяла — не учтено в объяснении — это я для читателей, чтоб не запутались).

Дмитрий
Гость
Дмитрий

Здравствуйте. Скажите можно в квик поставить реакцию на клавиатуру или мышь. Что бы если я по ошибки напишу бесконечный цикл (и понял это только во время работы) нажал на клавишу и цикл прервался.

Дмитрий
Гость
Дмитрий

Спасибо за ответ. Очень благодарен. Приму к сведению