Итак, мы установили, что работа в командном режиме (сессия) не является программированием. Внешним атрибутом последнего в MATLAB служит задание последовательности действий по программе, записанной в виде m-файла. В уроке 5 было показано, что для создания m-файлов может использоваться как встроенный редактор, так и любой текстовый редактор, поддерживающий формат ASCII. Подготовленный и записанный на диск m-файл становится частью системы, и его можно вызывать как из командной строки, так и из другого m-файла. Есть два типа m-файлов: файлы-сценарии и файлы-функции. Важно, что в процессе своего создания они проходят синтаксический контроль с помощью встроенного в систему MATLAB редактора/отладчика m-файлов.
Файл-сценарий, именуемый также Script-файлом, является просто записью серии команд без входных и выходных параметров. Он имеет следующую структуру:
«Основной комментарий %Дополнительный комментарий Тело файла с любыми выражениями Важны следующие свойства файлов-сценариев:
· они не имеют входных и выходных аргументов;
· работают с данными из рабочей области;
· в процессе выполнения не компилируются;
· представляют собой зафиксированную в виде файла последовательность операций, полностью аналогичную той, что используется в сессии.
Основным комментарием является первая строка текстовых комментариев, а дополнительным — последующие строки. Основной комментарий выводится при выполнении команд lookfor и help имя_каталога. Полный комментарий выводится при выполнении команды help Имя_файла. Рассмотрим следующий файл-сценарий:
%Plot with color red
%Строит график синусоиды линией красного цвета
%с выведенной масштабной сеткой в интервале [xmin.xmax]
x=xmin:0.1:xmax;
plot(x.sin(x).'r')
grid on
Первые три строки здесь — это комментарий, остальные — тело файла. Обратите внимание на возможность задания комментария на русском языке. Знак % в комментариях должен начинаться с первой позиции строки. В противном случае команда help name не будет воспринимать комментарий (иногда это может понадобиться) и возвратит сообщение вида No help comments found in-name.m.
Обратите внимание на то, что такой файл нельзя запустить без предварительной подготовки, сводящейся к заданию значений переменным xmin и хтах, использованным в теле файла. Это следствие первого свойства файлов-сценариев — они работают с данными из рабочей области. Переменные, используемые в файлах-сценариях, являются глобальными, т. е. они действуют одинаково в командах сессии и внутри программного блока, которым является файл-сценарий. Поэтому заданные в сессии значения переменных используются и в теле файла. Имена файлов-сценариев нельзя использовать в качестве параметров функций, поскольку файлы-сценарии не возвращают значений. Можно сказать, что файл-сценарий — это простейшая программа на языке программирования MATLAB [ Файлы-сценарии нельзя компилировать. Перед компилированием их нужно преобразовать в файлы-функции — Примеч. ред. ].
Рис.20.2.Пример работы с файлом pcr
Статус переменных в функциях
Переменные, указанные в списке параметров функции, являются локальными и служат для переноса значений, которые подставляются на их место при вызовах функций.
Эта особенность переменных-параметров хорошо видна при разборе примера, показанного на рис. 20.3. Здесь (признаемся, что неточно) задана некоторая функция двух переменных fun(x, у).
В этом примере в окне редактора создана функция fun двух переменных х и у, вычисляющая z = х 2 +у 2 . Поскольку переменные х и у указаны как параметры функции fun(x, у), то они являются локальными. В примере вне тела функции им заданы нулевые значения. Очевидно, что при вычислении значения fun(2, 3) в теле функции задается х=2 и у=3. Поэтому результат — z=13. Однако после выхода из тела функции переменные х и у принимают свои исходные значения, равные нулю. Так что эти переменные меняют свои значения на значения параметров функции только локально — в пределах тела функции. А каков статус переменной z в нашем примере? Она, как и любая переменная, определенная в теле функции, также будет локальной. Изначально ее значение не определено. В теле функции переменная принимает значение z=13. А после возврата из функции, как нетрудно увидеть из рис. 18.2, переменная z, несмотря на ее применение в теле функции, остается неопределенной. На это указывает сообщение, отображаемое после попытки вывода значения переменной z.
Рис. 20.3.Пример, поясняющий действие локальных и глобальных переменных при задании файла-функции
Возврат из функции производится после обработки всего тела функции, т. е. при достижении конца файла функции. При использовании в теле функции условных операторов, циклов или переключателей иногда возникает необходимость осуществить возврат функции раньше, чем будет достигнут конец файла. Для этого служит команда return. В любом случае, результатом, возвращаемым функцией, являются значения выходных параметров (в нашем случае выходным параметром является переменная z), присвоенные им на момент возврата.
У нашей функции имеется один недостаток — вывод на индикацию значения z=13 из тела функции, хотя после этого г остается равным 0. Чтобы убрать побочный эффект вывода значения z, достаточно установить знак ; после математического выражения, определяющего z. Таким образом, окончательно наша функция должна записываться следующим образом:
function z=fun(x,y)
z=x^2+y^2;
Этот пример наглядно показывает, что пропуск любого слова или даже простого оператора (вроде знака :) может привести к не сразу понятным побочным эффектам и даже неверной работе функции. Программирование требует особой точности и педантичности, именно поэтому далеко не все могут быть хорошими программистами.
Структура М-файла-функции
М-файл-функция является типичным объектом языка программирования системы MATLAB. Одновременно он является полноценным модулем с точки зрения структурного программирования, поскольку содержит входные и выходные параметры и использует аппарат локальных переменных. Структура такого модуля с одним выходным параметром выглядит следующим образом:
function var=f_name(Cnncoк_napaмeтpов)
%Основной комментарий
%Дополнительный комментарий
Тело файла с любыми выражениями
vаr=выражение
М-файл-функция имеет следующие свойства:
· он начинается с объявления function, после которого указывается имя переменной van — выходного параметра, имя самой функции и список ее входных параметров;
· функция возвращает свое значение и может использоваться в виде name (Список_параметров) в математических выражениях;
· все переменные, имеющиеся в теле файла-функции, являются локальными, т. е. действуют только в пределах тела функции;
· файл-функция является самостоятельным программным модулем, который общается с другими модулями через свои входные и выходные параметры;
· правила вывода комментариев те же, что у файлов-сценариев;
· файл-функция служит средством расширения системы MATLAB;
· при обнаружении файла-функции он компилируется и затем исполняется, а созданные машинные коды хранятся в рабочей области системы MATLAB.
Последняя конструкция vаг=выражение вводится, если требуется, чтобы функция возвращала результат вычислений.
Приведенная форма файла-функции характерна для функции с одним выходным параметром. Если выходных параметров больше, то они указываются в квадратных скобках после слова function. При этом структура модуля имеет следующий вид:
function [varl,var2....]=f_name(Список_параметров)
%Основной комментарий
%Дополнительный комментарий
Тело файла с любыми выражениями
vаг1=выражение
vаг2=выражение
Такая функция во многом напоминает процедуру. Ее нельзя слепо использовать непосредственно в математических выражениях, поскольку она возвращает не единственный результат, а множество результатов — по числу выходных параметров. Если функция используется как имеющая единственный выходной параметр, но имеет ряд выходных параметров, то для возврата значения будет использоваться первый из них. Это зачастую ведет к ошибкам в математических вычислениях. Поэтому, как отмечалось, данная функция используется как отдельный элемент программ вида:
[var1,va2,... ]=f_nаmе(Список_параметров)
После его применения переменные выхода varl, var2,... становятся определенными и их можно использовать в последующих математических выражениях и иных сегментах программы. Если функция используется в виде nаmе(Список_параметров), то возвращается значение только первого выходного параметра — переменной varl.
Статус переменных и команда global
Итак, из сказанного ясно, что переменные в файлах-сценариях являются глобальными, а в файлах-функциях — локальными. Нередко применение глобальных переменных в программных модулях может приводить к побочным эффектам. Применение локальных переменных устраняет эту возможность и отвечает требованиям структурного программирования.
Однако передача данных из модуля в модуль в этом случае происходит только через входные и выходные параметры, что требует тщательного планирования такой передачи. В жизни мы далеко не всегда едим черную икру (локальные переменные) и часто хотим отведать черного хлебушка (глобальные переменные). Так и при создании файлов-функций порой желательно применение глобальных переменных. Ответственность за это должен брать на себя программист, создающий программные модули.
Команда global varl var2... позволяет объявить переменные модуля-функции глобальными. Таким образом, внутри функции могут использоваться и такие переменные, если это нужно по условиям решения вашей задачи [ Чтобы несколько программных модулей могли совместно использовать глобальную переменную, i идентификатор должен быть объявлен как global во всех модулях. ].
Использование подфункций
Начиная с версии 5.0 в функции системы MATLAB можно включать подфункции. Они объявляются и записываются в теле основных функций и имеют идентичную им конструкцию. Не следует путать эти функции с внутренними функциями, встроенными в ядро системы MATLAB. Ниже представлен пример функции с подфункцией:
function [mean.stdev] = statv(x)
USTATV Interesting statistics.
%Пример функции с встроенной подфункций
n = length(x);
mean = avg(x.n);
stdev = sqrt(sum((x-avg(x.n)). ^ 2)/n);
%--------------------------------------
function m = avg(x.n) £Mean subfunction m = sum(x)/n;
В этом примере среднее значение элементов вектора х вычисляется с помощью подфункции avg(x.n), тело которой записано в теле основной функции statv. Пример использования функции statv представлен ниже:
» V=[l 2345]
V=
» [a,m]=statv(V)
а =
m =
1.4142 » statv(V)
ans =
» help statv
STATV Interesting statistics.
Пример функции с встроенной подфункций
Подфункции определены и действуют локально, т. е. только в пределах т-файла, определяющего основную функцию. Команда help пате выводит комментарий, относящийся только к основной функции, тогда как команда type name выводит весь листинг m-файла. Так что заданные в некотором m-файле подфункции нельзя использовать ни в командном режиме работы, ни в других т-файлах. При обращении к функции интерпретатор системы MATLAB прежде всего просматривает m-файл на предмет выявления подфункций. Если они обнаружены, то задаются как локальные функции. Благодаря локальному действию подфункций их имена могут совпадать с именами основных функций системы. Если в функции и подфункциях должны использоваться общие переменные, их надо объявить глобальными как в функции, так и в ее подфункциях.
Частные каталоги
Для записи m-файлов используются каталоги, называемые родительскими каталогами. Они содержат группы файлов определенного функционального назначения, например по статистическим расчетам, матричным операциям, вычислению определенных классов функций и т. д.
Однако начиная с версии MATLAB 5.0 появилась возможность в родительских каталогах создавать частные каталоги с именем PRIVATE. Расположенные в них m-файлы доступны только файлам родительского каталога. Файлы частных каталогов просматриваются интерпретатором системы MATLAB в первую очередь. Применение частных каталогов позволяет изменять исходные файлы, сохраняя оригиналы в родительском каталоге в неизменном виде.
Если вы решили отказаться от применения измененного файла, достаточно стереть его в частном каталоге. Такая возможность связана с тем, что интерпретатор при поиске m-файла прежде всего просматривает частный каталог и интерпретирует найденный в нем файл. И только если файл не найден, ищется файл в родительском каталоге.