Главная » Просмотр файлов » Основы программирования

Основы программирования (947332), страница 29

Файл №947332 Основы программирования (Иванова Г.С. Основы программирования) 29 страницаОсновы программирования (947332) страница 292013-09-15СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 29)

Если имена этих подпрограмм необходимо передавать че­рез параметры, то надо описать собственную подпрограмму с указанием режима дальнего вы­зова, в теле которой будет находиться вызов стандартной подпрограммы, и использовать еевместо стандартной подпрограммы.Пример 5.10. Разработать подпрограмму, которая возвращает массивзначений произвольной функции при заданных интервале изменения аргу­мента [а,Ь] и количестве точек п.Имя функции будем передавать в подпрограмму через параметр проце­дурного типа.

Массив значений будем описывать как открытый:UnitSFun;InterfaceType func-functwn(x:real):real;Procedure TabFun(f:func;a,b:real;n:integer;Var Masf:array of real);ImplementationProcedure TabFun;Var h.real; i:integer;Beginh;=(b-a)/(n'l);for i:=0 to n-l do Masf[i]—f(a+h*i);End;EndОсновная программа должна описать конкретную функцию как функ­цию дальнего вызова.

Для функции sin создается специальная функция даль­него вызова.Program ex;Uses SFun;Var masFl: array[L, 10] of real; masF2: array[L. 20] of real;i: integer;function Fl(x:real):real; far;Begin Fl:-sin(x); end;function F2(x:real):real; far;Begin F2:-exp(x)+cos(x); end;BeginWriteLnC Таблица значений функции sin x:);TabFun(FIA2J0,masFI);167Часть 1. Основы алгоритмизации и процедурное программированиеfor i:=l to JO do Write(masFl[i]:7:l);Writeln;WriteLnC Таблица значений функции exp x+cos x:);TabFun(F2A2,20,masF2);for i:=l to 20 do Write(masF2[i]:7:l);Writeln;EndЗадания для самопроверкиЗадание 1. Разработайте процедуру вычисления производных функции у(х) поформулам Лагранжа в трех соседних точках, отстоящих на величину шага h:Уо' = (-ЗУо + 4У1 -У2У2Ь; УГ = (-Уо + У2У2Ь; Уг'= (Уо^У1+Зу2)/2Ь.Поместите процедуру в модуль.

Разработайте тестирующую программу.Задание 2. Разработайте процедуру определения корня функции на заданномотрезке. Поместите процедуру в модуль. Разработайте тестирующую программу.5.7. РекурсияВ математике строгое определение некоторых понятий может опиратьсяна то же понятие. Такие определения называют рекурсивными или индук­тивными. Например, рекурсивно определяется факториал:N1=I 1,еслиЫ=0;I Nx(N-l)!,еслиК>0.Данное определение состоит из двух утверждений.

Первое утверждениеносит название базисного. Базисное утверждение нерекурсивно. Второе ут­верждение носит название рекурсивного или индуктивного. Оно строитсятак, чтобы полученная в результате повторных применений цепочка опреде­лений сходилась к базисному утверждению.В программировании/76?/cy/?cwe;/(9w называется подпрограмма, которая впроцессе выполнения вызывает сама себя.Различают два вида рекурсии подпрограмм:• прямая или явная рекурсия - характеризуется существованием в телеподпрограммы оператора обращения к самой себе;• косвенная или неявная рекурсия - образуется при наличии цепочкивызовов других подпрограмм, которые в конечном итоге приведут к вызовуисходной.1685.

Модульное программированиеКаждое обращение к рекурсивной подпрограмме вызывает независи­мую активацию 3tofi подпрограммы. Совокупность данных, необходимыхдля одной активации рекурсивной подпрограммы, называется фреймом акmueaifuu.Фрейм активации включает:• копии всех локальных переменных подпрограммы;• копии параметров-значений;• четырехбайтовые адреса параметров-переменных и параметров-кон­стант;• копию строки результата (для функций типа string);• служебную информацию - около 12 байт, точный размер этой облас­ти зависит от способа вызова (ближний или дальний) и внутренней органи­зации подпрограмм.Пример 5.11. Разработать программу определения наибольшего общегоделителя двух чисел, используя алгоритм Евклида.Нерекурсивный вариант этого алгоритма уже был рассмотрен в приме­ре 1.2.

Рекурсивный вариант будем строить исходя из двух утверждений.Базисное утверэюдение: если два числа равны, то их наибольший общийделитель равен этим числам.Рекурсивное утверждение: наибольший общий делитель двух чисел ра­вен наибольшему общему делителю их разности и меньшего из чисел.Рекурсивная подпрограмма может быть реализована и как процедура,и как функция.

При реализации в виде процедуры список параметров кромечисел А и В включает параметр-переменную R. Через этот параметр проце­дура возвращает результат (рис. 5.10, а). Текст программы, реализующий ва­риант с рекурсивной процедурой, представлен ниже.Гыос1(А,В) JПЧос1(А,ВД))данетА=ВдаА>ВданетR=AнетА-ВдаА>ВнетNod = ANod(А.В,ВД)Nod(A,B-A,R)Nod =Nod(A-B,B)I(ReturnjNod =Nod(A,B-A)I(Returnaj6Рис.

5.10. Схема алгоритма Евклида:а - с использованием рекурсивной процедуры; о - с использованием рекурсивной функции169Часть 1. Основы алгоритмизации и процедурное программированиеФреймактивациитретьеговызова1[_< Г1Служебная информацияАдрес возвратаАдресрезультатаЬ=4Фреймактивациивтороговызова1< Г1>Фреймактивациипервоговызова|_< Г1ч1VПараметры-значенияа~4N1Параметр-переменнаяСлужебная информацияАдрес возвратаАдресрезультатаЬ-8а=4Служебная информацияАдрес возвратаАдресрезультатаЬ«8а=12,]Параметр-переменнаяПараметры-значенияПараметр-переменнаяПараметры-значенияJ2 байтаРис. 5.11.

Заполнение стека при выполнении рекурсивнойподпрограммыProgram ex;Var a,b,r:integer;Procedure nod(a,b:inieger; var rnnteger);Begin ifa-b then r:-a{базис}else ifa>b then nod(a'b,b,r)else nod(a,lhayr)End;Begin ReadLn(a,b);nod(a,b,r);WriteLn(r);End,При выполнении программы фреймы активации будут размещаться встеке - специальным образом организованной памяти. Например, для а=12и Ь=8 в момент завершения нерекурсивной третьей активации стек будет вы­глядеть, как показано на рис. 5,11 (запись в стек идет словами, т. е. по 2 бай­та, как и изображено на рисунке).Если реализовать вариант с ре1^рсивной функцией (рис. 5.10, б), тофрейм активации уменьшится, так как сократится список параметров. Соот­ветствующая программа будет выглядеть следующим образом:Program ex;Var а,b,r:integer;Function nod(a,b: integer) .integer;begin ifa=b then nod:'=a {базис}1705.

Модульноепрограммированиеelse{рекурсивный вызов}ifa>b thennod:=nod(a'b,b)elsenod:=nod(a,b'a)end;BeginReadLn(a,b);r:=nod(a,b);WriteLn(r);EndИтак, если подпрограмма обращается к себе несколько раз, образуетсянесколько одновременно существующих активаций и, соответственно, не­сколько фреймов активации. Все фреймы размещаются в стеке^ и при боль­шом количестве вызовов возможно переполнение стека. Поэтому необходи­мо стремиться к уменьшению фрейма активации.Примечание. Размер стека устанавливается в настройках среды, по умолчанию он при­нимает размер 16 кб, и его размер не может превышать 64 кб.Пример 5.12.

Разработать рекурсивную подпрограмму «переворота»строки (первая буква должна стать последней, вторая - предпоследней ит.д.).Можно предложить два способа разворота строки.Первый способ заключается в последовательном отсечении начальногоэлемента и добавлении его в конец результирующей строки.Второй - базируется на последовательной перестановке элементов: пер­вого с последним, второго - с предпоследним и т. д.

Перестановки должныпрекратиться, когда дойдем до середины строки, иначе вновь поставим эле­менты на исходные места.Вариант с о т с е ч е н и е м и д о п и с ы в а н и е м :Function reversel (const st: string): string;Begin iflength(st)=0 then reverserl:= "elsereverserl: = reversel (copy (st, 2, length(st)'l)) +stflj;End;Определим размер фрейма активации:V = 4 (адрес параметра) + 256 (результат-строка) ++ <размер служебной области > «270 (байт).171Часть I. Основы алгоритмизации и процедурное программированиеВариант с и с п о л ь з о в а н и е мперестановок:Procedure reverse2(var ss:string; ri:integer);Var temp:char;Begin ifn<=Iength{ss) div 2 thenbegin temp:'=ss[n];ssfnj: =ssflength(ss)' i+1];ss[length(ss) 'П+IJ: = ^emp;reverse2(ss, n+1);end;End;Размер фрейма активации для этого варианта:У=4(адрес 1-го параметра)-ь2(копия 2-го параметра) ++ 1(локальная переменная)+<размер служебной области>«17 (байт).Следовательно, второй вариант предпочтительнее.Одной из наиболее часто встречающихся ошибок при создании рекур­сивных процедур является «зациклившаяся», или бесконечная, рекурсия, прикоторой базисное утверждение не достигается, и, соответственно, вновь ивновь вызывается рекурсивная подпрограмма.

От бесконечного цикла беско­нечная рекурсия отличается тем, что каждая активация требует дополнитель­ной памяти для размещения фрейма активации, и, следовательно, программа,содержащая бесконечную рекурсию, обычно завершается аварийно при пе­реполнении стека.Причиной бесконечной рекурсии может быть не только ошибка в про­грамме, но и обработка некорректных данных.Пример 5.13. Разработать программу определения корней уравненияу=х2-2 на заданном отрезке методом половинного деления.Метод половинного деления для непрерывных функций, так же как иметод хорд, рассмотренный в примере 3.7, позволяет находить корень функ­ции только в случае, если функция имеет на концах заданного отрезка раз­ные знаки, т.е. пересекает ось абсцисс.

Этот метод базируется на следующихутверждениях.Базисное утверждение: если абсолютная величина функции в серединеотрезка не превышает заданного значения погрешности, то координата сере­дины отрезка и есть корень.Рекурсивное утверждение: корень расположен меисду серединой от­резка и тем концом, значение функции в котором по знаку не совпадает созначением функции в середине отрезка (рис. 5.12).Program ex;Var a,b,eps,x:real;1725. Модульное программированиеСRoot Л(а.Ь г,е) JРис. 5.12. Рекурсивный алгоритм определениякорней уравненияProcedure root(a,b,eps:real;var r:real);Varf,x:real;Begin x:=(a+b)/2;f:=x*X'l;ifabs(f)<=eps then r:=xelseif (a *a'l) y> 0 then root(x, b, eps, r)else root(a,x,eps,r)End;Begin ReadLnfa, b, eps);root(a,b,eps,x);WriteLn('Корень x^ \x:9:7);EndЕсли для данной программы задать отрезок, не содержащий корня, топроизойдет «зацикливание», что вызовет аварийное завершение программыпо переполнению стека.

Характеристики

Тип файла
PDF-файл
Размер
13,06 Mb
Тип материала
Учебное заведение
Неизвестно

Список файлов книги

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6310
Авторов
на СтудИзбе
312
Средний доход
с одного платного файла
Обучение Подробнее