Справочник по Ada 2012
5.5 Операторы цикла
Оператор loop_statement включает последовательность_операторов, которые должны выполняться многократно, ноль или более раз.
Синтаксис
loop_statement ::=
[loop_идентификатор_оператора:]
[схема_итерации] loop
последовательность_операторов
end loop [loop_идентификатор];
[loop_идентификатор_оператора:]
[схема_итерации] loop
последовательность_операторов
end loop [loop_идентификатор];
спецификация_параметра_цикла ::=
определяющий_идентификатор in [reverse] определение_подтипа_дискретного_типа
определяющий_идентификатор in [reverse] определение_подтипа_дискретного_типа
Если у оператора loop_statement есть loop_идентификатор_оператора, то идентификатор должен быть повторён после end loop; в противном случае, идентификатор после end loop отсутствует.
Статическая семантика
спецификация_параметра_цикла объявляет параметр_цикла, который является объектом, подтип которого определяется определением_подтипа_дискретного_типа.
Динамическая семантика
При выполнении оператора loop_statement, последовательность_операторов выполняется многократно, ноль или более раз, до тех пор, пока оператор цикла не завершится. Оператор цикла завершается, когда происходит передача управления, которая выводит управление из цикла, или, в случае схемы итерации, как указано ниже.
При выполнении оператора loop_statement со схемой итерации while схема_итерации, условие вычисляется перед каждым выполнением последовательности_операторов; если значение условия равно True, последовательность_операторов выполняется; если False, выполнение loop_statement завершается.
При выполнении оператора loop_statement со схемой итерации for спецификация_параметра_цикла, спецификация_параметра_цикла сначала обрабатывается. Эта обработка создаёт параметр цикла и обрабатывает определение_подтипа_дискретного_типа. Если определение_подтипа_дискретного_типа определяет подтип с пустым диапазоном, выполнение loop_statement завершается. В противном случае, последовательность_операторов выполняется один раз для каждого значения дискретного подтипа, определённого определением_подтипа_дискретного_типа, которое удовлетворяет предикатам подтипа (или пока цикл не покидается в результате передачи управления). Перед каждой такой итерацией соответствующее значение дискретного подтипа присваивается параметру цикла. Эти значения присваиваются в возрастающем порядке, если зарезервированное слово reverse не присутствует, в противном случае значения присваиваются в убывающем порядке.
Подробности о выполнении оператора loop_statement со схемой итерации for спецификация_итератора см. в 5.5.2.
ПРИМЕЧАНИЯ
5 Параметр цикла является константой; его нельзя обновлять внутри последовательности_операторов цикла (см. 3.3).
6 Объявление объекта для параметра цикла не должно быть предоставлено, поскольку параметр цикла автоматически объявляется спецификацией_параметра_цикла. Область видимости параметра цикла распространяется от спецификации_параметра_цикла до конца loop_statement, а правила видимости таковы, что параметр цикла виден только внутри последовательности_операторов цикла.
7 определение_подтипа_дискретного_типа цикла for обрабатывается только один раз. Использование зарезервированного слова reverse не изменяет определённый дискретный подтип, поэтому следующие схемы итерации не эквивалентны; первая имеет пустой диапазон.
for J in reverse 1 .. 0
for J in 0 .. 1
for J in 0 .. 1
Примеры
Пример оператора цикла без схемы итерации:
loop
Get(Current_Character);
exit when Current_Character = '*';
end loop;
Get(Current_Character);
exit when Current_Character = '*';
end loop;
Пример оператора цикла со схемой итерации while:
while Bid(N).Price < Cut_Off.Price loop
Record_Bid(Bid(N).Price);
N := N + 1;
end loop;
Record_Bid(Bid(N).Price);
N := N + 1;
end loop;
Пример оператора цикла со схемой итерации for:
for J in Buffer'Range loop -- работает даже с пустым диапазоном
if Buffer(J) /= Space then
Put(Buffer(J));
end if;
end loop;
if Buffer(J) /= Space then
Put(Buffer(J));
end if;
end loop;
Пример оператора цикла с именем:
Summation:
while Next /= Head loop -- см. 3.10.1
Sum := Sum + Next.Value;
Next := Next.Succ;
end loop Summation;
while Next /= Head loop -- см. 3.10.1
Sum := Sum + Next.Value;
Next := Next.Succ;
end loop Summation;