Поскольку язык
Функции n! происходит рекурсивный спуск от значения аргумента n к значению n-1 с запоминанием значения n к тому моменту, когда будет вычислено значение (n-1)! и надо будет умножить это значение на запомненное n. Такой рекурсивный спуск требует, чтобы
имеет другой синтаксис, чем вызов обычной
<apply /Рефал-функция/ аргументРефал-функции>
Здесь полужирные уголковые скобки являются обязательными синтаксическими единицами в отличие от обычных уголковых скобок, служащих для описания синтаксиса. При вызове порождается новое
k/Рефал-функция/ аргументРефал-функции.
Происходит попытка вычисления этого .
Поле того как результат замены сформирован, дополнительное , уничтожается. При рекурсивном обращении к образуется
В качестве примера мы рассмотрим n!.
FACT START
ENTRY Factorial
EXTRN prout, card, numb, symb, mul, first, apply
Factorial = k/fact/ k/numb/ k/prout/'n: '. k/card/...
fact /0/ = k/pr/ '!=1'
E1 = k/pr/ k/symb/E1.'!=' k/symb/ k/f0/ E1...
f0 E1 = <apply /f/ E1>
f /1/ = /1/
E1 = k/mul/ (E1) k/f0/ k/m1/ E1...
pr =
E1 = k/pr1/ k/first/ /80/ E1..
pr1 (E1)E2 = k/prout/ E1. k/pr/ E2.
'*'E1 = k/prout/ E1.
END
В этой программе функция вводит цепочку цифр данного, преобразует к , которая вычисляет значение факториала от аргумента и готовит полученное значение к выводу на экран.
Функция для вычислений вызывает функцию f0, которая при помощи функции f. Эта функция накапливает произведение аргумента на значение факториала от аргумента, уменьшенного на 1, для чего снова вызывает функцию f0 с этим уменьшенным значением f0 снова f с новым значением аргумента и так делается до тех пор, пока значение аргумента не станет равно 1.
В этом случае будет происходить завершение вычисления функции f в обратном порядке вызванных процессов. Память завершающихся процессов будет удаляться, а значение, вычисленное в каждом процессе, будет передаваться в вызвавший процесс до тех пор, пока не закончится вычисление функции f0 в первом вызванном процессе.
Функция вызовет после вычислений преобразование результата к pr для вывода на экран результата.
Здесь следует обратить внимание на то, что полученная цепочка символов может не уместиться в одной строке экрана. Поэтому функция pr отщепляет от цепочки 80 символов при помощи функции first и передает на печать функцию pr1, которая печатает отщепленную часть и возвращает остаток функции pr для следующего отщепления. Так происходит до тех пор, пока вся цепочка символов не будет выведена.
Содержимое
('<ИмяСтека1>=<Выраж1>'). . . ('<ИмяСтекаN>=<ВыражN>'),
где <ИмяСтека1> ... <ИмяСтекаN> - произвольные имена <Выраж1>...<ВыражN> - произвольные
Первичная функция '<ИмяСтека>=<Выраж>' добавляет в
k/br/ 'X=A'. k/br/ 'X=B'.
в ('X=B')('X=A'), т. е. образуется X (если его ранее не было в
Первичная функция '<ИмяСтека>' ищет в ('<ИмяСтека>=<Выраж>') с именем <ИмяСтека>, удаляет его из <Выраж> ; в
('X=A')('Y=B')('Y=C').
Тогда после выполнения
k/dg/ 'Y'.
копилка примет вид:
('X=A')('Y=C'),
а функция возвратит значение 'B'.
Первичная функция <ИмяСтека> возвращает то же, что и функция dg. но не удаляет ничего из
k/dg/ 'Y'.
для результатов предыдущего примера
Первичная функция '<ИмяСтека>=<Выраж>', так же как и функция br, добавляет в
('X=A')('Y=B')('Y=C').
Тогда после выполнения
k/rp/ 'Y=C'.
копилка примет вид: ('X=A')('Y=C')('Y=C').
Первичная функция
('X=A')('Y=B')('Y=C').
Тогда после выполнения
k/dgall/ .
в ('X=A')('Y=B')('Y=C') и
В качестве примера мы рассмотрим Y, в котором формируется отсортированная в возрастающем порядке последовательность, и X, который является вспомогательным: в нем содержится начало уже отсортированной последовательности в обратном порядке.
Каждое вводимое число z сравнивается с числом, находящимся в Y, и если оно меньше, то идет поиск его места в стеке X, а если оно не меньше, то числа из Y переписываются в X до тех пор, пока z не станет меньше, чем в вершине Y (или Y не станет пустым), после чего оно записывается в Y.
При поиске места z в X оно сравнивается с числом, находящимся в вершине X, и если оно меньше, то числа из X переписываются в Y до тех пор, пока z не станет не меньше, чем в вершине X - тогда оно записывается в X.
При вводе нуля (признак окончания ввода) остаток в X переписывается в Y, а затем извлекается из Y для вывода через пробел на экран.
SORT START
ENTRY Sort
EXTRN prout, card, numb, symb, sub, first, br, dg, cp
* ввод 1-го числа в стек Y
Sort = k/n1/ k/br/'Y=' k/numb/
k/prout/'Последовательность чисел: '. k/card/....
* ввод очередного числа z
n1 E1 = k/n2/ k/br/'Z=' k/numb/ k/card/... k/cp/'Z'..
* z=0? X–>Y : z–y
n2 /0/ = k/t1/ k/cp/'X'..
S(N)1 = k/n3/ k/sub/ (S1) k/cp/'Y'...
* z<y?
n3 '–'E1 = k/nx/ k/cp/'X'..
E1 = k/ny/ k/cp/'Y'..
* X=0? z->X : z–x
nx = k/n1/ k/br/'X=' k/dg/'Z'...
S(N)1 = k/n4/ k/sub/ (k/cp/'Z'.) S1..
* z<x? X->Y : Z->X
n4 '–'E1 = k/br/'Y=' k/dg/'X'.. k/nx/ k/cp/'X'..
E1 = k/n1/ k/br/'X' k/dg'Z'...
* Y=0? Z->Y : z–y
ny = k/n1/ k/br/'Y=' k/dg/'Z'...
S(N)1 = k/n5/ k/sub/ (k/cp/'Z'.) S1..
* z<y? Z->Y : Y->X
n5 '–'E1 = k/br/'Y=' k/dg/'Z'.. k/n1/ k/cp/'X'..
E1 = k/br/'X' k/dg'Y'.. k/ny/ k/cp/'Y'..
* X=0? –>вывод Y : X–>Y
t1 = k/m2/ () k/cp/'Y'..
E1 = k/t1/ k/br/'Y' k/dg/'X'..k/cp/'X'..
* Y=0? –>печать (E) : –>вывод Y
m2 (E1) = k/pr/ E1.
(E1)S(N)2 = k/m2/ (E1' 'k/symb/S2.) k/dg/'Y'..
* выделение 80 символов для печати
pr =
E1 = k/pr1/ k/first/ /80/ E1..
* печать выделенного или остатка
pr1 (E1)E2 = k/prout/ E1. k/pr/ E2.
'*' E1 = k/prout/ E1.
END
Работа
<имя обменной функции>/ <рефал-выражение>.
В результате вызова такой функции содержимое
Все :
<пробел> SWAP <пробел> <имя ящика 1>, ... ,<имя ящика N>
и не могут уничтожаться во время работы. Например, в следующем фрагменте программы
SWAP X,Y swxy = k/X/'A'. k/Y/ 'B'. k/sw/ /X/ /Y/. sw Sx Sy = k Sx k Sy k Sx...
при вызове функции
k/swxy/.
в X и Y сначала будут занесены символы 'A' и 'B' соответственно, а затем в результате выполнения
k/sw/ /X/ /Y/.
содержимое ящиков поменяется местами.
new. В результате выполнения
k/new/ <рефал-выражение>.
создается новый
EXTRN new swrr = k/sw/ k/new/'A'/. k/new/ 'B'.. sw Sx Sy = k Sx k Sy k Sx...
Теперь при вызове функции swrr будут выполнены 2 вызова функции new, в результате которых образуются 2 ящика, например, с именами /%0321514/ и /%0674236/. В эти ящики будут записаны символы 'A' и 'B' соответственно, а затем при вызове функции sw их содержимое поменяется местами.
Обращаться напрямую к динамическому ящику мы не можем, но можем запомнить символ-ссылку и вызывать
Имеются 5 первичных функций, которые удобнее по сравнению с прямым использованием
Функция gtr (взять по ссылке)
k/gtr/ <ссылка>. ,
где
Функция rdr (прочитать по ссылке)
k/rdr/ <ссылка>.
копирует в
Функция (положить по ссылке)
k/ptr/ <ссылка> <рефал-выражение>.
добавляет в ящик справа
Функция wtr (записать по ссылке)
k/wtr/ <ссылка> <рефал-выражение>.
заменяет в ящике содержимое на
Функция swr (Обменять по ссылке)
k/swr/ <ссылка> <рефал-выражение>.
делает обмен между содержимым
Рассмотрим пример работы с
<ссылка следующего ящика> (<ключ>) <данные>
Последний элемент в цепочке динамических ящиков имеет пустую ссылку следующего ящика, а на первый элемент ссылается статический ящик, который определяет , производят
pred ссылку на предыдущий ящик в цепочке списка);Следующая программа выводит меню действий:
0. Завершить программу. 1. Инициализировать список. 2. Добавить элемент списка. 3. Найти данные по ключу. 4. Удалить элемент по ключу. Введите пункт меню.
и осуществляет эти действия.
LIST START
ENTRY Init, In, Find, Out, List
EXTRN prout, card, numb, symb,
* ключ, данные, указатели головы списка и
* элементов текущего, предыдущего и след.
SWAP key, data, pl, cur, pred, next
* начальный вывод меню и выбор действия
List = k/menu/. k/act/ k/pnkt/..
* вывод меню
menu = k/prout/ '0. Завершить программу.'.
k/prout/ '1. Инициализировать список.'.
k/prout/ '2. Добавить элемент списка.'.
k/prout/ '3. Найти данные по ключу.'.
k/prout/ '4. Удалить элемент по ключу.'.
k/prout/ ' Выберите пункт меню.'.
* выбор пункта меню
pnkt = k/numb/ k/card/..
* выбор действия
act =
/0/ =
/1/ = k/Init/. k/menu/. k/act/ k/pnkt/..
/2/ = k/In/. k/menu/. k/act/ k/pnkt/..
/3/ = k/inkey/. k/Find/. k/prd/. k/menu/. k/act/ k/pnkt/..
/4/ = k/inkey/. k/Out/. k/prd/. k/menu/. k/act/ k/pnkt/..
E1 =
* ввод ключа
inkey E1 = k/key/ k/numb/ k/prout/'Ключ: '. k/card/...
* ввод данных
indat E1 = k/data/ k/prout/'данные: '. k/card/..
* инициализация списка
Init E1 = k/pl/.
* добавление элемента
In E1 = k/pl/ k/new/ k/gtr/ /pl/. (k/rdr/ /key/ k/inkey/..)
k/rdr/ /data/ k/indat/....
* поиск по ключу: опред. тек.эл. cur
Find = k/wtr/ /pred/. k/wtr/ /cur/ k/rdr/ /pl/..
k/f1/ k/rdr/ /cur/..
* нет текущего? не найден : анализ текущего
f1 = k/data/ 'Не найден'.
S(R)c = k/f2/ k/rdr/ k/rdr/ /cur/...
* анализ текущего
f2 S(R)n(S(N)k)Ed = k/wrt/ /next/ Sn. k/data/ Ed. k/f3/ Sk.
* сравнение ключей k–key
f3 S(N)k = k/f4/ k/sub/ (Sk) k/rdr/ /key/...
* k=key? найден : следующий
f4 /0/ =
E1 = k/pred/ k/cur/ k/next/... k/f1/ k/rdr/ /cur/..
* вывод результата из данных
prd E1 = k/prout/ k/rdr/ /data/..
* удаление: есть ли ключ?
Out E1 = k/Find/. k/o1/ k/rdr/ /cur/..
* удаление: есть ли предыдущий?
o1 = k/data/ 'Не найден'.
Vc = k/o2/ k/rdr/ /pred/..
* удаление: есть ли предыдущий?
o2 = k/pl/ k/rdr/ /next/.. k/data/ 'Удален'.
Vp = k/o3/ k/rdr/ k/rdr/ /pred/...
* удаление: изменение предыдущего
o3 S(R)cEd = k/wtr/ /pred/ k/rdr/ /next/. Ed. k/data/ 'Удален'.
END
Отметим, что в случае, когда в статическом ящике A находится ссылка на другой %B, к которой мы непосредственно не можем обратиться, то для получения данных последнего ящика нужно дважды вызвать данные:
k/rdr/ k/rdr/ /A/..
В результате первого вызова функции rdr в A ), а в результате второго вызова этой функции в
Добавление элемента определяется функцией In. Ее выполнение начинается с получения ссылки в ящике (для первого вводимого элемента списка эта ссылка пустая и означает конец списка, а для последующих данных, определяемых
Поиск элемента по ключу определяется функцией и вспомогательными функциями f1, f2, f3, f4. Действия функции начинаются с записи в ящик pred предыдущего элемента пустой ссылки и с записи в ящик cur текущего элемента ссылки на первый элемент списка, находящейся в ящике f1, которая в случае неуспешности поиска (ссылка на текущий элемент пустая) записывает в ящик data отыскиваемых данных фразу 'Не найден'. В случае же непустой ссылки на текущий элемент f1 вызывает функцию f2, передавая ей на анализ этот элемент. Функция f2 анализирует данные текущего элемента, разбивая его на ссылку на следующий элемент (записывается в ящик next ), ключ и данные (записываются в ящик data данных). Затем она отправляет этот ключ функции f3 (для сравнения с поисковым ключом в ящике key ), которая готовит разность ключей и отправляет ее для решения функции f4. Эта функция при равенстве ключей (разность ключей равна 0) заканчивает вычисления поиска (в ящике data уже находятся искомые данные), а в ином случае сначала изменяет ссылку текущего элемента на следующий элемент, а ссылку предыдущего элемента - на прежний текущий элемент, и затем вызывает функцию f1 для нового текущего элемента.
Out и вспомогательными функциями o1, o2, o3. Действия начинаются с поиска элемента по ключу и передачи текущего определенного элемента функции o1 для анализа. Функция o1 при пустой ссылке текущего элемента записывает в ящик data неуспешность поиска, а в ином случае передает эту ссылку функции o2 для подготовки удаления элемента из списка. Функция o2 в случае пустой ссылки предыдущего элемента изменяет ссылку в головном указателе на ссылку на следующий элемент (и этим ликвидирует текущий элемент списка), а в случае непустой ссылки предыдущего элемента передает функции f3 эту ссылку для удаления текущего элемента списка. Функция f3 записывает в ящик pred предыдущего элемента ссылку на следующий элемент, сохраняя остальные данные предыдущего элемента. Этим также заканчивается удаление текущего элемента.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.