КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Побочный эффект рекурсии
Пример. Пример. Итерация и рекурсия Стандартные функции Они вам известны: это арифметические, алгебраические и тригонометрические функции. Кроме того, есть функция конца строки: Eoln - end of line. Итерация (от лат. повторение) - повторение, применение какой – либо математической. Пример: Вычислить сумму ряда: S=a1+a2+….+an S1=a1 S2=a1+a2 S3=a1+a2+a3 S4=a1+a2+a3+a4 ………………… S=a1+a2+…+an Рекурсия (от лат. возвращение) - вычисление последующего значения ряда через предыдущее. Последовательность, в которой соседние значения связаны формулой, называется рекурсивной. Пример: Арифметическая прогрессия: a1, a2=a1+d, a3=a2+d, an=an-1+d Begin If (n=0) or (n=1) then Factorial:=1 Else begin F:=1 For i:=2 to n do F:=f*i; Factorial:=f; End; End; Begin Writeln (‘Введите N’); Readln (N); Writeln (‘факториал=’,Fact); End.
Program Rekursion; Var fact:real; N:integer; Function Factorial (N:integer):real; Begin If (n=0) or (N=1) then factorial:=1 Else factorial:=factorial (N-1)*n; End; Begin writeln (‘Введите N’); Readln (N); Fact:=factorial (N); Writeln (‘факториал=’,fact); End. Здесь первый вызов функции происходит в основной программе, а затем, начинается рекурсивный вызов внутри функции. В языке программирования Паскаль есть возможность обращения процедуры или функции к самой себе. При этом циклическую часть программы можно составить без операторов цикла. Способ обращения процедуры или функции к самой себе называется рекурсией. С помощью рекурсии удобно представлять те задачи, которые сводятся к подзадачам того же типа, но меньшей размерности. Вычисление факториала можно представить опять через факториал. N!=n(n-1)!-рекурсивная формула. Представление факториала в виде последовательности операций умножения – это итерационный процесс. n!= 1*2*3…n-итерационная формула. Итерация программируется с помощью циклов. Пример: Вычисление факториала. Program Iteracion; Var fact: real; N:integer; Function factorial (n: integer):real; Var f:real; I: integer; Пример. В 13 веке итальянский математик Фибоначчи сформулировал задачу: ”Некто поместил пару кроликов в некое место, огороженное со всех сторон стеной, чтобы узнать, сколько пар кроликов родится в течении года, если через месяц пара кроликов производит на свет другую пару, а рожают со второго месяца после своего рождения. Program Krolik; Var kr:integer; (*число кроликов*) N:Integer; (*число месяцев*) Function fib(n:integer):integer; Begin If (n=1) or (n=2) then fib:=1 Else fib:=fib(n-1)+fib(n-2) End; Begin Writeln(‘ввести N’); Readln (N); Kr:=fib (N); (*вызов ф-и*) Writeln (kr:5); End. В теле подпрограммы известны, то есть доступны все объекты, описанные в объемлющем блоке, в том числе и имя самой подпрограммы. Внутри тела подпрограммы возможен вызов самой подпрограммы. Параметры и функции использующие вызовы “самих себя“, называются рекурсивными. Допустима также косвенная рекурсия, при которой параметр А вызывает параметр В, а тот, в свою очередь, вызывает С, который вызывает первоначальный параметр А. Рекурсия достаточно широко применяется в программировании, что основано на рекурсивной природе многих математических алгоритмов. В языке программирования Паскаль нет никаких ограничений на рекурсивные вызовы подпрограмм, необходимо только понимать, что каждый очередной рекурсивный вызов приводит к образованию новой копии локальный объектов подпрограммы и все эти копии, соответствующие цепочке активизированных и не активизированных рекурсивных вызовов, существующих независимо друг от друга. При выполнении функций возникает один неожиданный эффект, причиной которого является изменение значений нелокальных переменных в теле функции. Если в некоторой функции имеются конструкции, например, операторы присваивания, изменяющие значения переменных, описанных в объемлющих блоках, то может возникнуть ситуация, при которой значения выражения, использующего вызов такой функции, зависит от порядка следования операторов, что является потенциальным источником ошибок и поэтому крайне нежелательно. Описанная ситуация называется побочным эффектом рекурсии. Пример: Program Side Effect; Var a,z:integer; Function change (x: integer): integer; Begin Z:=z-x; {изменяем значение нелокальной переменной} Change:= sqr (x) End; Begin Z:=10; a:=change (z); writeln(a,z); Z:=10; a:=change (10)*change (z); Writeln(a,z); Z:=10; a:=change (z) * change(10); Writeln (a,z) End. Выполнение этой программы приводит к следующему результату на дисплее: 100 0 10000 -10 0 0 Т.е. два последних присваивания переменной а дают различный результат, хотя правила вычисления выражений предлагают равноправные сомножители. Следует всячески избегать такой зависимости функции от глобальных по отношению к ней переменных. Заметим, что современные языки, например, Ada содержит прямые запреты на подобные действия. Предварительное описание (ссылки вперед) Объявления констант и переменных в любом блоке располагаются перед скобками begin...end (в этих скобках заключены сами операторы). Поэтому компилятору никогда не приходится иметь дело с оператором, содержащим константы и переменные, которых он не знает, это вызовет во время компиляции сообщение об ошибке. Все это справедливо и в отношении подпрограмм (т.е. функций и процедур). Программист обязан следить за правильным порядком следования определений (описаний). Пример: Program Demo; Var a, b,c: real; Procedure Ring (var s, l: real; d: real); Begin L:=3.14 *d; {длина окружности } S:=cir (d); {компилятор еще не знает о функции cir} End; Function Cir (d: real): real; {площадь круга } Begin cir:= 3.14* sqr(d) / 4; End; ……………………………………………………………………… Очевидный выход – поменять порядок строк так, чтобы функция Cir была определена перед процедурой Ring(…).Однако можно и иначе. Действия: 1. Оставить подпрограмму (функцию cir) на своем месте, вычеркнув из ее заголовка все параметры: Function cir; 2. Вставить полный заголовок там, где ему надлежит бытью, т.е. перед подпрограммой, которая его вызывает. Function cir (d: real): real; 1. После полного заголовка добавить слово Forward.
Дата добавления: 2014-10-23; Просмотров: 450; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |