Красавин Компютерныы практикум в среде МатЛаб 2015
.pdf10
Функции
10.1. Функции, возвращающие несколько переменных
Функции в MatLab могут быть поделены на три категории:
1)функции, вычисляющие и возвращающие одну переменную;
2)функции, вычисляющие и возвращающие несколько переменных;
3)функции, не возвращающие переменных.
Хотя приведенная классификация функций и является условной, различия между этими тремя типами определяют формат заголовка функции, а также способ, которым функции должны быть определены.
Каждая функция в MatLab |
состоит из следующих частей: |
||
1) заголовок |
функции; |
2) |
комментарий, описывающий |
предназначение функции; 3) тело функции, включающее в себя основной код функции.
Заголовок функции включает в себя следующие элементы:
•зарезервированное слово function;
•названия (одно или несколько) возвращаемых функцией переменных с последующим оператором =, если функция возвращает переменные; в случае, если возвращаются несколько переменных, названия переменных должны быть заключены в квадратные скобки;
•название функции (название функции должно совпадать с названием m-файла, содержащего эту функцию);
•названия (одно или несколько) входных переменных, заключенных в круглые скобки.
121
Например, у функции sorting:
function [t, Asort, A] = sorting(R, n)
две входных переменных (R и n) и три выходных переменных (t, Asort, A). Эта функция должна располагаться на жестком диске в файле sorting.m.
Функция, возвращающая несколько переменных, имеет следующий общий вид:
function [возвр. переменные] = название(входные переменные)
% комментарий, описывающий предназначение функции
Тело функции
В примере 10.1 рассмотрена функция, вычисляющая два значения: площадь и периметр круга.
Пример 10.1.
function [area, circum] = areacirc(rad)
%areacirc возвращает площадь и
%периметр окружности
%Формат: areacirc(радиус)
area = pi * rad .* rad; circum = 2 * pi * rad;
Пример использования:
[a, c] = areacirc(4)
a =
50.2655
c =
25.1327
122
Следует обратить внимание на то, что порядок возвращаемых переменных важен. В данном примерефункция сначала возвращает площадь, а затем периметр круга.
Функция help возвращает комментарий, который описывает предназначение функции, расположенной под заголовком функции:
help areacirc
areacirc возвращает площадь и периметр окружности
Формат: areacirc(радиус)
Функция areacirc из примера 10.1 может быть вызвана из командной строки, как было рассмотрено в примере, или из скрипта. В примере 10.2 приведен скрипт areacirc_call, который запрашивает у пользователя радиус окружности, вызывает функцию areacirc для расчета площади и периметра окружности и выводит результат.
Пример 10.2.
radius = input('Введите радиус окружности: ');
[area, circ] = areacirc(radius);
fprintf('Для окружности радиуса %.1f\n', radius)
fprintf('площадь равна %.1f , периметр равен %.1f\n', area, circ)
Пример использования:
reacirc_call
Введите радиус окружности: 5
Для окружности радиуса 5.0
площадь равна 78.5 , периметр равен 31.4
В примере 10.3 рассмотрена функция, возвращающая три переменные: функция принимает на вход количество секунд и возвращает число часов, минут и секунд.
123
Пример 10.3.
function [hours, minutes, secs] = breaktime(totseconds)
%функция breaktime разделяет общее количество секунд на
%часы, минуты и секунды
%Формат: breaktime(общее количество секунд)
hours = floor(totseconds/3600); remsecs = rem(totseconds, 3600); minutes = floor(remsecs/60); secs = rem(remsecs,60);
Пример использования:
[h, m, s] = breaktime(7515)
h=
2
m=
5
s=
15
10.2. Функции, не возвращающие переменные
Многие функции не рассчитывают переменные, а лишь выполняют такие определенные инструкции, как вывод форматированной информации. Общий вид таких функций следующий:
function название(входные переменные)
% комментарий, описывающий предназначение функции
Тело функции
В данном случае в заголовке функции отсутствуют перечисление выходных переменных, а также оператор «=». В примере 10.4 рассмотрена функция, которая выводит числа, поданные в качестве входных аргументов, в форматированном виде.
124
Пример 10.4.
unction printem (a,b)
%printem выводит два числа в виде предложения
%Формат: printem (num1, num2)
fprintf('Первое число %.1f и второе число %.1f\n',a,b)
Пример использования:
printem(3.3, 2)
Первое число 3.3 и второе число 2.0
Во всех примерах, представленных до сих пор, каждая функция обладала, по крайней мере, хотя бы одним входным аргументом, что было отображено в заголовках функций. Данный метод вызова функций называется методом «вызов по значению». В некоторых случаях функциям не требуются входные переменные. Рассмотрим функцию, выводящую на экран случайное вещественное число с двумя знаками после запятой:
function printrand()
%printrand выводит на экран случайное число
%Формат: printrand или printrand() fprintf('Случайное число: %.2f\n',rand)
Пример использования:
printrand()
Случайное число: 0.94
Записи заголовка функции printrand в виде function printrand() и function printrand эквивалентны.
125
10.3. Анонимные функции
Преимущество анонимных функций заключается в том, что их не нужно хранить в отдельном m-файле. Это может очень сильно упрощать программы, так как если повторяющиеся вычисления достаточно просты, можно использовать анонимные функции, тем самым уменьшив общее число m-файлов. Анонимные функции могут быть созданы как в командной строке, так и в скрипте или функции. Синтакс анонимных функций имеет следующий вид:
fnhandlevar = @ (arguments) functionbody;
где fnhandlevar – дескриптор функции, с помощью которого можно вызывать анонимную функцию. Дескриптор возвращается с помощью оператора @ и затем приписывается переменной fnhandlevar. Аргументы arguments, заключенные в круглые скобки, отвечают входным аргументам функции, так же как и в обычных функциях. functionbody – тело функции, которое может содержать любое выражение, соответствующее синтаксису MatLab. Например, анонимная функция, вычисляющая и возвращающая площадь круга, может быть записана в следующем виде:
cirarea = @ (radius) pi * radius .^2;
Имя дескриптора данной функции – cirarea. Здесь присутствует только один входной аргумент (радиус круга). Телом функции является выражение pi*radius.^2. Оператор .^ применяется для возможности использования вектора в качестве входного аргумента. Функция вызывается с помощью дескриптора. Вызов анонимной функции аналогичен вызову обычной функции:
cirarea(4)
ans = 50.2655
areas = cirarea(1:4)
areas =
3.1416 12.5664 28.2743 50.2655
126
В отличие от функций, содержащихся в m-файле, в случае анонимной функции круглые скобки для входных аргументов должны присутствовать, даже если входные аргументы отсутствуют, например:
prtran = @ () fprintf('%.2f\n',rand);
prtran()
0.95
Если в командной строке указать лишь имя дескриптора, то на экран выведется содержимое анонимной функции:
prtran
prtran =
@ () fprintf('%.2f\n',rand)
Анонимные функции могут быть сохранены в mat-файле и загружены впоследствии при необходимости:
cirarea = @ (radius) pi * radius .^2;
save anonfns cirarea
В одном mat-файле может храниться несколько анонимных функций. В этом заключается их преимущество: анонимные функции не обязательно сохранять в отдельные m-файлы, а можно группировать и сохранять в едином mat-файле.
10.4. Использование дескриптора функции
Дескриптор функции может быть создан и для обычной функции, не только для анонимной. Например, при выполнении команды
facth = @factorial;
127
оператор @ вызывает дескриптор функции factorial и сохраняет его в переменную facth. Этот дескриптор может быть использован как функция, к которой он прикреплен:
facth(5)
ans =
120
Одной из причин использования дескрипторов функций является возможность представить функции в качестве входных аргументов для других функций. Например, пусть имеется функция, создающая вектор x. Вектор y при этом создается как некоторая зависимость, вычисляемая в каждой точке вектора x, после чего строится график зависимости :
function fnfnexamp(funh)
%fnfnexamp получает дескриптор функции
%и строит эту функцию на отрезке x
%Формат: fnfnexamp(дескриптор функции)
x = 1:.25:6; y = funh(x); plot(x,y,'ko') xlabel('x')
ylabel('fn(x)')
title(func2str(funh))
Если теперь передать в качестве входного аргумента стандартную функцию, например sin, cos, или tan без использования оператора @, то результатом данных действий будет ошибка:
fnfnexamp(sin)
Error using sin
Not enough input arguments.
128
Правильно использовать дескриптор данных функций:
fnfnexamp(@sin)
Функция func2str в теле функции fnfnexamp переводит имя дескриптора функции в строку для дальнейшего использования в заголовке графика.
В качестве входного аргумента функции fnfnexamp может быть использован любой дескриптор любой функции. Следует обратить внимание на то, что если переменная уже содержит дескриптор функции, ее использование в качестве входного аргумента не требует использования оператора @, например:
fnfnexamp(cirarea)
MatLab содержит некоторое количество встроенных функций, аргументами которых могут быть другие функции. Одной из таких функций является fplot, которая строит график некоторой функции в заданном диапазоне. Формат вызова функции fplot следующий:
fplot(fnhandle, [xmin, xmax])
Например, для построения функции |
|
на отрезке |
sin |
|
с |
помощью fplot требуется передать |
дескриптор функции |
|
: |
|
|
sin |
|
π,π |
|
fplot(@sin, [-pi, pi])
Другим примером такой встроенной функции является feval, которая вызывает функцию по дескриптору с определенным входным аргументом:
feval(@sin, 3.2)
ans =
-0.0584
Функция fzero находит нулевое значение функции вблизи заданного значения:
129
fzero(@cos,4)
ans =
4.7124
10.5. Переменное число аргументов
Часто возникают ситуации, когда удобно создать функцию, допускающую использование переменного числа как входных аргументов, так и возвращаемых переменных. Встроенный массив ячеек varargin может быть использован для хранения переменного числа входных аргументов, а массив varargout – для возвращаемых переменных. Данные переменные varargin и varargout имеют тип массива ячеек, поскольку как входные аргументы, так и возвращаемые переменные могут иметь различные типы. Функция nargin возвращает количество входных аргументов, а nargout определяет количество возвращаемых функцией переменных. В примере 10.5 рассматривается функция, предусматривающая переменное число как входных, так и выходных параметров [1].
Пример 10.5. Задача состоит в том, чтобы написать функцию, входными
параметрами которой были бы координаты точки |
, |
, а также параметры |
||||
окружностей; –1, 1, 1 |
, |
2, |
2, 2 |
, …, где |
– координаты центров |
|
окружностей |
|
|
, |
радиусы окружностей; количество окружностей при этом может быть произвольным. Функция должна определить, лежит ли заданная точка внутри какой-либо окружности, найти число окружностей, внутри которых лежит точка, а также выдать номера этих окружностей в списке входных аргументов.
function [w, varargout] = point2(varargin)
%файл-функция определяет попадание точки с заданными
%координатами (px, py) в круги с центрами
%в (x1,y1), (x2, y2) и т. д. и радиусами r1, r2 и т. д.
%Использование:
%w = point(px,py,[x1,y1,R1],[x2,y2,R2],...)
%w равно 1, если точка попала в какой-либо круг,
%0 – в противном случае
130