Цикл ИНДЕКС
Цикл перебора элементов контейнерных переменных (цикл ИНДЕКС) предназначен для последовательного получения значений элементов и соответствующих им значений индексов, содержащихся в контейнерной переменной.
Синтаксис:
ЦИКЛ ИНДЕКС ( <переменная значения> = [КОНСТ] <контейнерная переменная или поле> [<переменная-индекс1> [, …] ] ) <операторы секции цикла> КОНЕЦ_ЦИКЛА
Количество переменных-индексов должно соответствовать размерности контейнерной переменной. Переменная значения и переменные-индексы последовательно принимают значения, соответствующие элементам контейнерной переменной.
Указание ключевого слова КОНСТ после знака равенства и перед контейнерным значением позволяет ускорить выполнение цикла за счет того, что контейнерное значение рассматривается как неизменяемое в теле цикла. По умолчанию считается, что значение может изменяться, что приводит к дополнительному копированию и проверкам. Если ключевое слово КОНСТ указано, но в теле цикла прямо или опосредованно происходит изменение контейнерного значения, то возможно проявление различных артефактов поведения. Следует избегать такой практики и указывать ключевое слово КОНСТ только в тех циклах, где осуществляется доступ к перебираемому контейнерному значению исключительно на чтение.
Пример:
ВЫЧИСЛИТЬ // определим двумерную контейнерную переменную, // которая содержит три элемента ПЕРЕМ СТРОКА: ип[ЧИСЛО,СТРОКА] = ( 1, "И": "Иванов", 2, "П": "Петров", 3, "С": "Сидоров" ) // перебираем элементы в цикле // переменные фамилия, номер и буква принимают значения, // соответствующие элементам контейнерной переменной ип ЦИКЛ ИНДЕКС (фамилия = ип[номер, буква]) СООБЩЕНИЕ(СТР(номер) + ", " + буква + " : " + фамилия) КОНЕЦ_ЦИКЛА КОНЕЦ
Помимо стандартного перебора значений, цикл ИНДЕКС предоставляет следующие возможности:
- отключение обмена данными с переменной-элементом и (или) переменными-индексами с помощью символа *;
- частичный перебор контейнерных значений при фиксации одного или нескольких индексов (для 2-х и более -мерных значений);
- обработка добавления и удаления элементов контейнерного значения в процессе выполнения цикла;
Отключение обмена данными, которые не нужны в данной задаче позволяет ускорить перебор индексного значения. В случаях, когда не требуется знать значения элемента, цикл ИНДЕКС может быть записан в следующем формате:
Синтаксис:
ЦИКЛ ИНДЕКС (* = <контейнерная переменная> [ <индексы> ])
То есть звездочка на месте элемента указывает на то, что при переборе нам не нужны его значения. Аналогично могут быть проигнорированы значения индексов (одного, нескольких или всех).
ПЕРЕМ СТРОКА: а[ЧИСЛО,ЧИСЛО] = ( 1, 1: "А", 2, 2: "Б" ) ЦИКЛ ИНДЕКС (стр = а[*,*]) // значения индексов нам не нужны ОТЛАДКА(стр) КОНЕЦ_ЦИКЛА
Результат: А Б
Частичный перебор индексного значения осуществляется путем задания фиксированных значений для одного или нескольких индексов. Фиксированные значения не могут быть заданы для всех индексов. На порядок следования фиксированных и не фиксированных индексов ограничений не накладывается. Фиксация индекса может быть осуществлена двумя путями:
- указанием явной константы (литерала, например, 5 или "красный")
- использованием ключевого слова КОНСТ перед выражением: КОНСТ <выражение>, где выражение - константное или неконстантное выражение. В последнем случае значение фиксированного индекса будет вычислено в момент выполнения цикла ИНДЕКС.
Тип константы или выражения должен соответствовать типу индекса.
Пример:
ПЕРЕМ СТРОКА: а[ЧИСЛО,ЧИСЛО] = ( 1, 1: "А", 1, 2: "Б", 2, 1: "В", 2, 2: "Г" ) ЦИКЛ ИНДЕКС (стр = a[ 1, и2 ]) // первый индекс зафиксирован равным 1 ОТЛАДКА(стр) КОНЕЦ_ЦИКЛА ОТЛАДКА("---") и2 = 2 ЦИКЛ ИНДЕКС (стр = a[ и1, КОНСТ и2 ]) // второй индекс зафиксирован равным и2 ОТЛАДКА(стр) КОНЕЦ_ЦИКЛА
Результат: А Б --- Б Г
Для управления итерациями цикла используются ключевые слова ПРОДОЛЖИТЬ и ПОВТОР. ПРОДОЛЖИТЬ переходит к следующей итерации цикла без выполнения нижеследующих операторов тела цикла. ПОВТОР повторно выполняет текущую итерацию цикла., т.е. управление передается от ключевого слова ПОВТОР в начало цикла. Цикл ИНДЕКС корректно поддерживает модификацию контейнерного значения в процессе его перебора даже в случае вложенных циклов ИНДЕКС по одному индексному значению. Наиболее важной задачей, где совместно применяются перебор и модификация, является удаление некоторых элементов контейнерного значения. В случае удаления текущего элемента возникает неопределенность с новым текущим элементом. Логика перебора в этом случае зависит от природы последнего индекса: ассоциативный или последовательный. Тем не менее, ключевое слово ПОВТОР позволяет создать инвариатный алгоритм, корректно работающий в обоих случаях:
ЦИКЛ ИНДЕКС (стр = a[ и1, и2 ]) ЕСЛИ НадоУдалять(стр, и1, и2) ТО // функция принимает решение об удалении ЕСЛИ ^а[ и1, и2 ] ТО // если успешно удален ПОВТОР // если здесь не вернемся в начало цикла, // то пропустим следующий за удаленным элемент КОНЕЦ_ЕСЛИ КОНЕЦ_ЕСЛИ КОНЕЦ_ЦИКЛА