Перейти к основному содержимому

Назад: Программный код

Циклы

Основная информация

Циклы — это особые конструкции в программе, которые многократно выполняют определённый кусочек кода.

Например, чтобы вывести на экран числа с 1 по 15, не обязательно пятнадцать раз писать команду *P, можно использовать цикл:

loop i=1 while i<=15 step i+=1:
*p "<<i>>, "
end

Для организации циклов в QSP используется оператор loop, состоящий из трёх ключевых слов. Общая запись выглядит так:

LOOP {команды до начала цикла} WHILE [#условие] STEP {команды в конце итеррации}:
{операторы тела цикла}
END

Здесь:

  • {команды до начала цикла} — это команды, выполняемые до того, как цикл будет запущен. Данные команды относятся к блоку цикла, но не попадают в итерации (проходы), т.е. выполняются только один раз (не являются телом цикла). Здесь можно, например, объявить счётчик цикла. И здесь можно писать множество команд, перечисляя их через разделитель & (амперсанд).
  • [#условие] — это выражение, по значению которого проверяется условие, при котором цикл будет выполняться. Здесь могут использоваться операции сравнения и логические операции в любых связках. В случае, если значение выражения [#условие] равно нулю, цикл прерывается.
  • {команды в конце итеррации} — это команды, выполняемые в конце каждого прохода цикла. Сюда можно помещать команды, которые не относятся напрямую к телу цикла, но тем не менее должны быть выполнены на каждой итерации. Здесь можно, например, изменять значение счётчика цикла. На самом деле здесь можно писать множество команд, перечисляя их через разделитель & (амперсанд).
  • {операторы тела цикла} — это команды, которые необходимо выполнять на каждом проходе. Они являются основными для цикла. То есть мы создаём цикл именно ради этих команд.

Цикл в QSP — это отдельный блок кода (так же как и действие ACT), и это значит, что внутри цикла мы можем объявить локальные переменные. Это очень удобно, потому что мы можем объявить локальную переменную для счётчика, что не повлияет на остальные переменные на локации:

i=99
*pl "i до цикла <<i>>"
loop local i=0 & *p "i в цикле: " while i<6 step i+=1:
*p "<<i>>, "
end
*nl "i после цикла <<i>>"

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

summ=0 & ! сюда будем записывать сумму чисел
! наши числа лежат в массиве mass
loop local i,size = 0,arrsize('mass') while i<size step i+=1:
summ += mass[i]
end
*pl 'Сумма всех элементов массива mass: <<summ>>'

У циклов нет собственных массивов args и result, они используют args и result локации (или другого блока кода), на которой расположены.

Виды циклов

В программировании существуют три основных вида циклов:

  • Цикл с предусловием
  • Цикл с постусловием
  • Цикл со счётчиком

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

$text='Выводим текст в столбик'
! сначала проверяется условие
loop while len($text)>0:
! и лишь затем выполняется тело цикла
*pl $mid($text,1,1)
if len($text)=1:
$text=''
else:
$text=$mid($text,2)
end
end

Цикл с постусловием — это такой цикл, в котором сначала производится итерация (то есть выполняется тело цикла), и лишь затем проверяется условие. Такие циклы более редки, но всё же необходимы. В QSP не предусмотрена отдельная конструкция для таких циклов, поэтому приходится несколько изменять само тело цикла, чтобы цикл работал правильно.

loop local run=1 while run:
! сначала выполняется тело цикла
$name=$input('Введите ваше имя:')
! и лишь затем проверяется условие
if $name<>'': run=0
end

Данный цикл можно изменить вот так, чтобы убрать условие из тела цикла:

loop local run=1 while run step run=iif($name<>'',0,1):
! сначала выполняется тело цикла
$name=$input('Введите ваше имя:')
! и лишь затем проверяется условие (в Step)
end

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

! выводим каждое десятое число от 230 и заканчивая 402
loop local i=230 while i<=402 step i+=10:
*p "<<i>>, "
end

! выводим в обратном порядке каждый третий элемент массива mass
loop local i=arrsize('mass') while i>0 step i-=3:
mass[i-1]
end

Выход из середины. Прерывание цикла

Чтобы в любой момент прервать выполнение цикла, нужно использовать оператор JUMP и "прыжок" на метку вне цикла:

$text='Выводим текст в столбик'
! сначала проверяется условие
loop local $s while len($text)>0:
$s=$mid($text,1,1)
if $s='к': jump 'end_of_cycle'
*pl $s
if len($text)=1:
$text=''
else
$text=$mid($text,2)
end
end
:end_of_cycle
loop while 1:
$name=$input('Введите ваше имя:')
if $name<>'': jump 'out'
end
:out

Вперёд: Массивы