Матросов А.В. Maple 6. Решение задач высшей математики и механики (1185909), страница 57
Текст из файла (страница 57)
е. процедур, определенных внутри другой процедуры. Для подобных процедур область действия переменных, не объявленных явно локальными или глобальными, определяется в соответствии с приведенным выше правилом для процедуры, относяшейся ко всему сеансу Мар(е. Если переменная появляется в левой части оператора присваивания или используется в качестве переменной цикла гог, то она считается локальной для этой процедуры и на нее распространяется правило вычисления на один уровень.
Все другие переменные являются глобальными, но глобальность понимается в смысле переменных внешней процедуры, в которой объявлена локальная процедура, т. е. если во внешней процедуре есть локальная переменная с таким же именем, что и глобальная переменная во внутренней процедуре, то во внутренней процедуре используется именно она, иначе глобальная переменная внутренней процедуры является глобальной и для внешней. Пример 5.)3 демонстрирует применение этого правила. В процедурах пезг() и пезг1() объявлены локальные процедуры з (), для которых переменная г является глобальной. Так как в процедуре пезг() есть локальная переменная, то именно она используется во вложенной процедуре. В процедуре пезг1() переменная г вообше отсутствует, поэтому в ее локальной процедуре з () используется глобальная переменная М~ш(МЙ, . $)В(а(>в))з(йгнй)т~' ~ Зяти хе' * ""~еа "~З« ';:-Ф"..: ''":"* !=";:, )-й ' " .
> пезг: =ргос (и) 1оса1 х, з, г; х:=и) х:=пезг; з:=ргоо(х) х*г епс( ргоо; з (х) ) епс( ргос: > пезГ1: ргос(п) 1оса1 х,з; х:=и; з:=ргос(х) х*г егх) ргос; з(х)) епо ргос: Часть 1 Основы Мор!е > э:=пезт1; т:= пезг! > паз т 15) г пеа т1 ( 5)," 5 пезг 5 пезгl Замечание Объявление вложенных процедур, имеющих доступ к локальным переменным внешней процедуры, в сочетании с воэможностью возвращения в качестве значения внешней процедуры одной из вложенных в нее процедур можно использовать как механизм реализации инкапсуляции объектно-ориентированной технологии программирования.
Если процедура возвращает вложенную в нее процедуру, которая определяет или устанавливает значение локальной переменной внешней процедуры, то такую вложенную процедуру можно рассматривать как метод некоторого объекта, свойства которого реализованы в локальных переменных внешней процедуры. Для реализации нескольких методов, однако, в этом случае приходится использовать индекс. Эта технология была единственной в версии Мар1е))гте) 5, реализующей работу с объектами. В версии Мар)е 6 для целей создания и работы с объектами следует использовать новую конструкцию пюс)эта)), о кОторой нЕМНОгс будет рассказано в завершающем разделе данной главы. 5.2.4.
Опции и строка описания При объявлении процедуры в операторе ортьсп (или срт1опз), входящего в ее заголовок, можно определить некоторое специальное поведение процедуры, указав список допустимых опций. Для процедур используются аттон, )ш11т1п, са11 ехтетпа1, 1п11пе,оретатот, тегсога)>ет, эуатега и стасе. Опция )>а11ттп применяется для идентификации встроенных процедур Чар!е, находящихся в его ядре и реализующих разнообразные команды и функции. При полном вычислении подобных функций командой ета1)) опция Ьа11ттп ИНфарМИруЕт ПОЛЬЗОВатЕЛя О тОМ, ЧтО КОМаНда яВЛяЕтСя ВСтрОЕННОй, а отображаемый уникальный номер служит для ее быстрой идентификации и выполнения: > ета1(гоар); ргосО орт!оп би)Ип; 189 епд ргос Создать собственную встроенную процедуру нельзя.
Обычно при обьявлении процедуры Мар!е автоматически производит неко- торые упрощения в ее теле: Глава д Основы программирования в )И Iв > ргос(х) д:=х*г; 1г Ггпе гьеп -х*х е1ае х епс) 1Г; епс) ргос; иагпхпд, д' ха ипр1хсхе1у с)ес1агес) 1оса1 Го ргосег)иге ргос(г) 1о со( рл я:= х"2; -х 2 епп' рго с Сравните тело процедуры при ее объявлении с тем, как оно выглядит в области вывода, и станет ясно, какие упрощения выполняет Мар!е при объявлении процедуры. Опция орегагог предписывает дальнейшие упрощения в теле процедуры, рассматривая ее как математический оператор. Два примера демонстрируют применяемые в этом случае упрощения; > Г1г=-ргос(х) Ь(х) с епС ргоо) Г):= ргос(х) Ь(х) епй ргос > г2;=ргос(х) орг1оп орегагою 'п(х); епс) ргос) 12:= й Используемая совместно с опцией орегагог опция а о предписывает отображать процедуру как функциональный оператор с использованием "стрелочной" нотации и эквивалентна заданию процедуры в области ввода с помощью стрелки.
Следующие два объявления процедуры эквивалентны: > ргос(х, у) оргзоп орегагог, аггее; адгс (х"2су"2); епс) ргос; (х,у) -+ /хе+у' > (х, у) ->адгг (х" 2+у 2) ' (х,у)-ах)х +у- Может оказаться так, что при реализации какого-то алгоритма необходилю много раз вызывать процедуру с одним и тем же набором фактических параметров. Для ускорения процесса ее вычисления она может быть сконструирована так, что результаты ее вычисления с заданными параметрами автоматически записываются в специальную таблицу значений функции. При последующем обращении к процедуре с этим набором фактических параметров ее значение не вычисляется вновь, а просто берется из таблицы значений.
Подобная возможность существенно увеличивает скоростные характеристики процедуры, алгоритм выполнения которой достаточно сложен и может занять большой промежуток времени. Для конструирования процедуры, записывающей результаты своего вычисления с заданными значениями фактических параметров в таблицу, достаточно задать в ее теле опцию гесаеасоег. Использование этой опции особенно эффективно в рекурсивных процедуРах Создать РекуРсивную процедуру в Мар1е очень просто.
Если в теле процедуры есть обращение к ней же самой, то такая процедура реализуется как рекурсивная процедура. Классическим примером рекурсии является вычисление чисел Фибоначчи по формуле: г(и) = г(и — 1)+ г(и- 2) Часть!. Основы Мар1е 310 при заданных начальных условиях Е!0)=0 и Р(!)=1.
Процедура, реализуюшая вычисление чисел Фибоначчи в соответствии с приведенной рекуррентной формулой, представлена в примере 5.!4. > р:=ртос(о::ьоеедес) тд о<2 Е)тес е)ве Г(о)т=к(п-т)ег(п-2) есо 36 еос) рсос: > Г(300); 22223224462942044552973989346)909967206666939096499764990979600 Эта процедура не эффективна с точки зрения ее временных характеристик. Попробуйте вычислить 2000-е число Фибоначчи и вы увидите, сколько времени потребуется ей для получения результата. Дело в том. что она каждый раз вычисляет все предыдущие числа Фибоначчи. Более эффективная реализация этого алгоритма получается с использованием опции т,епьет, при задании которой в таблицу значений автоматически заносятся результаты вычислений с заданными фактическими параметрами. Теперь, если мь( вычислим сразу же большое число Фибоначчи, то при вычислении меньших чисел будут использованы уже вычисленные значения из таблицы значений функции, да и вычисления с большими числами будут использовать все ранее вычисленные значения из таблицы значений.
Даже первое вычисление будет более эффективно, так как некоторые значения будут браться из таблицы. Это можно увидеть, воспользовавшись командой е';;, которая печатает затраченное процессорное время на вычисление выражения, определяемого ее параметром: > твпе(г(20))) .096 > е>дпе (Р (20) ) ) .004 Первый результат получен при выполнении процедуры примера 5.!4, а второй — при добавленной в объявление процедуры опции сепепьеп Занести результаты вычислений процедуры с конкретными фактическими параметрами в таблицу ее значений можно и явным образом.
Для этого достаточно вызову процедуры с заданными значениями фактических параметров присвоить необходимое'значение. Можно, например, реализовать алгоритм вычисления чисел Фибоначчи и способом, показанном в примере 5. ! 5. Тлела 5. Основы программирования в Мвр!и з!т гтя > Г:=ргос(п::1псесег) орг1оп гегаагаЬегг р(п)г48(п-1)+Г(п-2) епг( ргсс: > Г(О):=Ог Г(1):=1г г(0):= 0 г(1):=! > в(в) ) 21 Для правильной работы процедуры примера 5.15 после ее определения обязательно явное занесение в таблицу значений процедуры результатов ее вычисления при п=с и п=1. Забегая вперед, скажем, что таблица значений процедуры представлена четвертым операндом типа ргосег)с а, т. е.
ее можно отобразить, выполнив команду сры,а а1(т) ), где г — имя процедуры. Например, после вычисления восьмого числа Фибоначчи процедурой примера 5.!5 таблица ее значений выглядит следующим образом: > Т".=ор(4,еча1 (Г) ) ) Т:= (аЫе((0 = О,! = 1, 2 = 1, 3 = 2, 4 = 3, 5 = 5, 6 = 8, 7 = 13, 8 = 2! )) Замечание При использовании таблицы значений процедуры, особенно рекурсивной, следует помнить, что подобное действие может потребовать большого объема оперативной памяти. Для удаления записи из таблицы значений достаточно соответствующему элементу присвоить его же собственное имя с помощью команды яча1п(). Например, для удаления записи о пятом числе Фибоначчи из предыдущей таблицы следует воспользоваться командой: > Т [51: =еча1п (Т [5 ) ) ) Т .-7 > ор (4, еча1 (р) ) г (аЫе( !О = О, 1 = 1, 2 = 1, 3 = 2, 4 = 3, 6 = 8, 7 = 13, 8 = 21 )) Удалить полностью всю таблицу значений процедуры можно, подставив значение нц) ь в четвертый операнд ее типа ргосег)игв.
> ясЬяор(4-ИЛ.1„еча1 (Е) ): > ор(4,еча1(Г)); Часть!. Основы Мар1е 312 После выполнения последнего оператора никакая таблица не будет отображена, а это означает, что после применения первого оператора подстановки ее уже не существует. Опция аувер используется совместно с опцией гомопьох и идентифицирует процедуру как "системную функцию", для которой таблица значений удаляется во время процедуры сборки мусора, которая автоматически запускается системой Мар)е. Если для какой-либо пользовательской процедуры эта опция не указана, то при сборке мусора ее таблица значений не удщ(яется из памяти, Замечание Инициировать процедуру сборки мусора можно в любое время с помощью команды чс () (оагЬаое со((ес(юп) без параметров.