Циклы в языке Перфолента

Материал из ТХАБ.РФ
Перейти к: навигация, поиск

В любом языке программирования имеются средства для многократного повторения определенных частей кода в зависимости от каких-либо условий. Есть такие возможности и в Перфоленте. Многократное повторение участков кода возможно с помощью операторов цикла, которых в языке имеется несколько видов.

Последствия зацикливания программы могут дорого обойтись пользователю, не забывайте об этом. Для начала разберемся с терминологией. Английское слово Cycle в переводе на русский язык имеет смысл близкий к словосочетанию "движение по кругу". А при движении по кругу вы будете проходить одни и те же точки окружности столько раз, сколько оборотов вы сделаете.

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

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

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

Как и в других языках программирования, для выполнения повторяющихся действий в языке Перфолента.Net используются циклы. Имеется несколько разновидностей циклов, отличающихся способом определения количества повторений заданного блока операторов. В этой статье будут рассмотрены все имеющиеся варианты циклов.

Самый простой цикл можно написать так:

Цикл
   //блок операторов       
КонецЦикла

Этот цикл будет бесконечно выполнять указанный блок операторов, если в нём нет ни одного оператора выхода из цикла. Операторы выхода из цикла будут рассмотрены дальше, а пока только заметим, что самый простой цикл применяется не так уж редко.

Умнику на заметку: находящийся внутри цикла блок операторов называется телом цикла, а одно выполнение тела цикла называется итерацией цикла. Бесконечное выполнение цикла, не предусмотренное программистом, называется зацикливанием. Обо всём этом мы и говорили выше, когда обсуждали терминологию.

Оператор Прервать

Для выхода из цикла в блоке операторов может присутствовать оператор Прервать, который передаст управление оператору, следующему за ключевым словом КонецЦикла. Если несколько циклов вложены друг в друга, то оператор Прервать организует выход только из того цикла в блоке операторов которого он находится. Оператор Прервать не может выполнить выход из нескольких циклов сразу.

Цикл
   //блок операторов
   Прервать
КонецЦикла

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

Цикл
   //блок операторов
   Если ЦельДостигнута
       Прервать
   КонецЕсли    
КонецЦикла

В языке Перфолента существует сокращенный условный вариант записи оператора Прервать:

Цикл
    //блок операторов
    Прервать Если ЦельДостигнута
КонецЦикла

Оператор Прервать Если можно писать отдельными словами или слитно ПрерватьЕсли, главное, что после него должно следовать выражение задающее условие выхода из цикла.

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

Цикл
   Прервать Если УсловиеВходаВТелоЦиклаНеВыполнено
   //блок операторов
   Прервать Если ЦельДостигнута
   //блок операторов
   Прервать Если ЦельДостигнута
   //блок операторов
   Прервать Если ЦельДостигнута
КонецЦикла

Этот вариант цикла наиболее универсален и может заменить любые другие варианты циклов, которые будут описаны ниже.

Оператор Продолжить

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

А=0
Цикл
   А=А+1    //в начале каждой итерации увеличиваем значение переменной А на единицу
   Если А=3
       Продолжить     //переходим в начало цикла, если А=3
   КонецЕсли
   Обработать(А)
   Прервать Если А=10
КонецЦикла

В приведенном примере метод Обработать(А) не будет выполнен, если А=3, т.к. в этом случае выполнится условие продолжение цикла и оператор Продолжить немедленно передаст управление в начало цикла.

Как и в случае с оператором Прервать, оператор Продолжить можно записать в укороченной условной форме Продолжить Если (или слитно ПродолжитьЕсли):

А=0
Цикл
   А=А+1    //в начале каждой итерации увеличиваем значение переменной А на единицу
   Продолжить Если А=3    //переходим в начало цикла, если А=3
   Обработать(А)
   Прервать Если А=10
КонецЦикла

Цикл Пока

В языке Перфолента существует цикл с предварительным условием, в котором перед началом каждой операции проверяется условие входа в тело цикла.

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

Пока УсловиеВхода Цикл
    //блок операторов
КонецЦикла

Умнику на заметку: Ключевое слово Цикл не является обязательным и может быть пропущено.

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

Цикл Для

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

Для Номер=1 По 7 Шаг 2 Цикл
    ВыводСтроки "Номер = "+Номер
КонецЦикла

Умнику на заметку: Ключевое слово Цикл не является обязательным и может быть пропущено.

В этом примере на экран консоли будут выведены значения 1, 3, 5, 7. После выполнения тела цикла к значению переменной цикла будет прибавлено значение, заданное после ключевого слова Шаг, и выполнение продолжится, если значение переменной цикла не превысит конечное значение, заданное после ключевого слова По.

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

Для Номер=7 По 1 Шаг -2 
   ВыводСтроки "Номер = "+Номер
КонецЦикла

В этом случае на экран консоли будут выведены значения 7, 5, 3, 1.

Умнику на заметку: Ключевое слово Шаг не является обязательным и может быть пропущено. В этом случае значение шага будет равно единице.

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

Если переменная цикла не была определена ранее, то она может быть определена прямо в цикле, по тем же правилам, по которым определяются обычные переменные, например:

//Цикл с дробным шагом для значений типа Вещ
Для ВещИнд Тип Вещ=1.1 По 2 Шаг 0.1 Цикл
    ВыводСтроки "ВещИнд="+ВещИнд
КонецЦикла

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

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

Для СимИнд тип Символ="А"с По "Д"с Шаг 2    //операция Символ+Число
    ВыводСтроки СимИнд
КонецЦикла

Цикл по датам также может быть полезен во многих случаях.

Для Дт='20200101' По '20200131' Шаг 86400    //операция Дата+Число, где число определяется в секундах
    ВыводСтроки "Дата="+Дт
КонецЦикла

В языке Перфолента все три параметра цикла Для могут быть представлены переменными, значения которых допустимо изменять в теле цикла.

ПерИнд=1
ПерПо=20
ПерШаг=1
Для ПерИнд По ПерПо Шаг ПерШаг
   ПродолжитьЕсли ПерИнд=4
   ВыводСтроки "Инд="+ПерИнд+" По="+ПерПо+" Шаг="+ПерШаг
   ПрерватьЕсли ПерИнд=10
   ПерИнд+=1
   ПерПо-=1
   ПерШаг+=1
КонецЦикла

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

Цикл Для Каждого

Цикл Для Каждого предназначен для обхода и обработки перечисляемых коллекций элементов. На каждой итерации в переменную цикла передается для обработки один из элементов коллекции. В качестве коллекций могут выступать массивы, строки, кортежи и любые объекты, которые поддерживают интерфейс IEnumerable, в том числе все универсальные коллекции значений из стандартной библиотеки, такие как Массив, Соответствие, Структура, Стек, Очередь, СписокЗначений, ТаблицаЗначений, ДеревоЗначений и многие другие объекты.

Если переменная цикла ранее не была определена, то ее можно определить при определении цикла. Тип переменной цикла должен допускать присваивание объектов, имеющих тип, соответствующий типу элементов коллекции.

Для Каждого ЭлементСписка Тип ЭлементСпискаЗначений Из МойСписокЗначений Цикл
    ВыводСтроки ЭлементСписка
КонецЦикла  

Умнику на заметку: Ключевые слова Каждого и Цикл не являются обязательными и могут быть пропущены. Определение типа переменной цикла так же может быть пропущено в большинстве случаев. Однако, некоторые коллекции поддерживают перечисление своего содержимого несколькими способами, и в таких случаях определение типа переменной цикла обязательно, иначе компилятор не сможет выбрать способ обхода коллекции.

//аналогично предыдущему примеру
Для ЭлементСписка Из МойСписокЗначений
    ВыводСтроки ЭлементСписка
КонецЦикла  

Коллекция Матрица из стандартной библиотеки позволяет обойти себя двумя способами, по значениям типа ДВещ и по элементам матрицы типа ЭлементМатрицы, которые кроме значения содержат номер строки и номер колонки матрицы откуда взято значение:

//обойдем матрицу по всем значениям
Для Значение тип ДВещ Из МояМатрица //цикл по IEnumerable<ДВещ>
   ВыводСтроки Значение
КонецЦикла 
//обойдем матрицу по всем элементам
Для Элемент тип ЭлементМатрицы Из МояМатрица  //цикл по IEnumerable<ЭлементМатрицы>
    ВыводСтроки Элемент
КонецЦикла 

Умнику на заметку: Языки C# и Visual Basic.Net не умеют обходить коллекцию по двум разным типам, как это делает Перфолента, учитывайте это при написании классов, которые будут использоваться из других языков.

Если тип элементов коллекции на момент написания программы не известен, то при определении переменной цикла используйте тип Объект.

Для Об тип Объект Из НеизвестнаяКоллекция
    ВыводСтроки Об
КонецЦикла 

Вложенные циклы

Циклы любых видов могут быть многократно вложены друг в друга, однако, операторы Прервать и Продолжить действуют в пределах того цикла, в теле которого они определены.

Для Инд = 1 По 5
       Для Инд2 = 1 По 1    //вложенный цикл
               Выраж1 = 5
               Пока Выраж1 > 3    //вложенный цикл
                       Выраж2 = 0
                       Цикл                            //вложенный цикл
                               ВыводСтроки ""+Инд+", "+Выраж1+", "+Выраж2
                               ПрерватьЕсли Выраж2 = 1
                               Выраж2 += 1
                               Продолжить
                               ВыводСтроки "Не будет напечатано"
                       КонецЦикла
                       Выраж1 -= 1
                       Продолжить
                       ВыводСтроки " Не будет напечатано "
               КонецЦикла
       КонецЦикла
       Прервать Если Инд = 3
       Продолжить Если Инд < 3
       ВыводСтроки " Не будет напечатано "
КонецЦикла

Обход двухмерного массива с помощью двух вложенных циклов:

А=0
Массив МойМассив[1, 1] Тип Целое = А++    //заполним массив индексами
Для Инд1 = 0 По 1
   Для Инд2 = 0 По 1
       ВыводСтроки МойМассив[Инд1, Инд2]
   КонецЦикла
КонецЦикла

В окно консоли будут выведены значения 0, 1, 2, 3.

'Показать Содержание Описание языка Перфолента.NET'

Ссылки