Maple 9.5/10 в математике, физике и образовании - Владимир Дьяконов
Шрифт:
Интервал:
Закладка:
Простейшая форма задания процедуры следующая:
name := proc(Параметры)
Тело процедуры
end;
Параметры процедуры задаются перечислением имен переменных, например proc(х) или proc(x,y,z). С помощью знака :: после имени переменной можно определить ее тип, например в объявлении prog(n::integer) объявляется, что переменная n является целочисленной.
При вызове процедуры выражением вида
name(Фактические_параметры)
фактические параметры подставляются на место формальных. Несоответствие фактических параметров типу заданных переменных ведет к сообщению об ошибке и к отказу от выполнения процедуры.
В качестве примера ниже приведена процедура вычисления модуля комплексного числа z — в данном случае это единственный параметр процедуры (файл р4):
> mode:=рroc(z)
> evalf(sqrt(Re(z)^2+Im(z)^2))
> end;
modc := proc(z) evalf (sqrt(ℜ(z)^2 + ℑ(z)^2)) end procПосле ввода заголовка процедуры под строкой ввода появляется сообщение: «Warning, premature end of input». Оно указывает на то, что ввод листинга процедуры не закончен и должен быть продолжен до тех пор, пока не будет введено завершающее слово end листинга процедуры. Если после этого слова поставить символ точки с запятой, то листинг процедуры будет выведен на экран дисплея.
Теперь для вычисления модуля достаточно задать обращение к процедуре modc(z), указав вместо z конкретное комплексное число:
> mode(3.+I*4.);
5.0000000000Нетрудно заметить, что при знаке ; после завершающего слова end текст процедуры повторяется в строке вывода (в общем случае в несколько ином виде).
Если это повторение не нужно, после слова end надо поставить знак двоеточия. Обратите также внимание на то, что для обозначения действительной и мнимой частей процедуры в ее тексте появились готические буквы.
10.3.2. Графические процедуры
В процедурах могут использоваться все вычислительные, графические и иные функции системы Maple. Так что материал предшествующих глав фактически уже был описанием возможностей языка программирования Maple. Как пример применения в процедуре графических средств, приведем процедуру построения кольца Мебиуса заданной ширины width (файл gproc):
> mob := proc(width)
> plot3d([(5+cos(1/2*t)*u)*cos(t),
(5+cos(1/2*t)*u)*sin(t),sin(1/2*t)*u], t=0..2*Pi,
> u=-width/5..width/5, gnd= [60,10] ,
> scaling=UNCONSTRAINED, orientation= [0,140]);
> end:
Запуск этой процедуры командой
> mob(5);
строит фигуру, показанную на рис. 10.4.
Рис. 10.4. Кольцо Мебиуса, построенное графической процедурой
10.3.3. Просмотр кодов процедур
Коды процедур на языке Maple можно просмотреть с помощью функции eval(name) или pint(name), где name — имя процедуры. При этом уровень просмотра можно менять с помощью функции interface(verboseproc=N), где N — уровень вывода. Следующий пример иллюстрирует это для только что созданной процедуры mode (файл р4):
> eval(modc);
proc(z) evalf (sqrt(ℜ(z)^2 + ℑ(z)^2)) end proc> interface(verboseproc=0);
1> eval(modc);
proc(z) evalf (sqrt(ℜ(z)^2 + ℑ(z)^2)) end proc> interface(verboseproc=1);
0> eval(modc);
proc(z) evalf (sqrt(ℜ(z)^2 + ℑ(z)^2)) end procАналогичным образом можно просмотреть коды процедуры, уже созданной в Maple. Например, не очень большой процедуры смены системы координат changecoords из пакета расширении plots:
> interface(verboseproc=0);
1> eval(plots[changecoords]);
proc(p,coord) … end proc> interface(verboseproc=2);
0> eval(plots[changecoords]);
proc(p, coord)
local c_name, a, b, c;
option
`Copyright (c) 1994 by the University of Waterloo. All rights reserved;`
a :=1;
b := 1/2;
с := 1/3;
if type(coord, function) then
c_name :=op(0, coord);
if nops(coord) = 1 then a :=op(1, coord)
elif nops(coord) = 2 then a :=op(1, coord); b :=op(2, coord)
elif nops(coord) = 3 then
a :=op(1, coord); b :=op(2, coord); с :=op(3, coord)
else error "Inappropriate number of parameters."
end if
else c_name := coord
end if;
if member(c_name, `plot3d/coordset2` ( )) then
(p, c_name, a)
elif member(c_name , `plot3d/coordset` ( )) then
`plots/changecoords/threetrans` (p, c_name, a,b,c)
else error "Cannot convert to coordinate system %1", coord
end if
end proc
10.3.4. Оператор возврата значения RETURN
Как отмечалось, процедуры, которые возвращают значение результата в ответ на обращение к ним, во многом тождественны функциям. Будем называть их процедурами-функциями. Обычно процедура возвращает значение последнего выражения в ее теле или выражения, намеченного к возврату специальным оператором возврата RETURN (файл р4):
> modc:=proc(z)
> evalf(sqrt(Re(z)^2+Im(z^2)):
> RETURN(%)
> end;
modc := proc(z) evalf (sqrt(ℜ(z)^2 + ℑ(z)^2)); RETURN(%) end proc> modc(3.+I*4.);
5.000000000Параметром оператора RETURN может быть любое выражение. В Maple не принято выделять процедуры-функции в какой-то отдельный класс. Действует правило — если не использован оператор RETURN, процедура возвращает значение последнего выражения в ее теле. Для устранения выдачи значений выражений внутри процедуры-функции после них просто надо установить знак двоеточия.
10.3.5. Статус переменных в процедурах и циклах
Переменные, которые указываются в списке параметров (например, z в нашем примере) внутри процедуры являются локальными. Это означает, что изменение их значений происходит лишь в теле процедуры, то есть локально. За пределами тела процедуры эти переменные имеют то значение, которое у них было до использования процедуры. Это хорошо поясняет следующий пример (файл р5):
> restart:z:=1;
z := 1> modc:=proc(z)
> evalf(sqrt(Re(z)^2+Im(z)^2));
> end;
modc := proc(z) evalf (sqrt(ℜ(z)^2 + ℑ(z)^2)) end proc> modc(3.+I*4.);
5.000000000> z;
1Нетрудно заметить, что внутри процедуры z=3+I*4, тогда как вне нее значение z=1. Таким образом, имена переменных в списке параметров процедуры могут совпадать с именами глобальных переменных, используемых за пределами процедуры.
Переменные, которым впервые присваивается значение в процедуре, также относятся к локальным. Кроме того, переменные, применяемые для организации циклов, являются локальными. Все остальные переменные — глобальные.
10.3.6. Объявления переменных локальными с помощью оператора local
Если в теле процедуры имеются операции присваивания для ранее определенных (глобальных) переменных, то изменение их значений в ходе выполнения процедуры создает так называемый побочный эффект. Он способен существенно изменить алгоритм решения сложных задач и, как правило, недопустим.
Поэтому Maple-язык программирования имеет встроенные средства для исключения побочных эффектов. Встречая такие операции присваивания, Maple-язык корректирует текст процедуры и вставляет в нее объявление переменных локальными с помощью ключевого слова local и выдает предупреждающую надпись о подобном применении (файл р5):
> restart:m:=0;
m := 0> modc:=proc(z)
> m:=evalf(sqrt(Re(z)^2+Im(z)^2)):RETURN(m)
> end;
Warning, `m` is implicitly declared local to procedure 'modc'
modc:= proc(z) evalf (sqrt(ℜ(z)^2 + ℑ(z)^2)); RETURN(m) end proc> modc(3.+I*4.);
5.000000000> m;
0Обратите внимание на то, что в тело процедуры было автоматически вставлено определение local m, задающее локальный статус переменной m. Оператором print (modc) можно вывести текст процедуры.
10.3.7. Объявления переменных глобальными с помощью слова global
Говорят, что запретный плод сладок! Что бы ни говорили о нежелательности работы с глобальными переменными, бывает, что их применение желательно или даже необходимо. Чтобы сделать переменные внутри процедуры глобальными, достаточно объявить их с помощью ключевого слова global, после которого перечисляются идентификаторы переменных.
Следующий пример поясняет применение оператора global в процедуре (файл р5):