![]()
Главная Обратная связь Дисциплины:
Архитектура (936) ![]()
|
Вычисления в интерактивном режиме. 5 часть
Затем нужно добавить ещё проверку третьего параметра на скалярность, что можно выполнить следующим фрагментом кода: [ m ,n ] = size( x ); if ( m ~=1 | n ~= 1 ) error( 'Bad 3d parameter' ) end Наконец, неплохо проверить общее число параметров, с которыми функция была вызвана. Для этой цели в системе MATLAB специально предусмотрена переменная с именем nargin. Её значением является количество аргументов, фактически переданное функции при вызове. Тогда проверка на число параметров выполняется следующим образом: if nargin ~= 3 error( 'Bad number of parameters' ) end Более того, в системе MATLAB предусмотрена переменная nargout, содержащая число возвращаемых значений, предполагающихся в реальной форме вызова этой функции. Например, вызов [ s1, s2, s3 ] = MatrProc1( x1, x2, x) предполагает получить аж три возвращаемых значения, в то время как из определения функции следует, что возвращаемых значений у этой функции два. Чтобы предупредить пользователя функции о несовпадении числа ожидаемых возвращаемых значений их номинальному числу, нужно в теле функции осуществить проверку переменной nargout: if nargout ~= 2 Осуществлённые нами проверки приводят к тому, что функцию можно вызвать только с правильным числом входных параметров и возвращаемых значений. Однако ранее мы встречались со встроенными функциями системы MATLAB, которые могли быть вызваны с разным числом входных параметров (и это очень типично). В результате фактически разные работы бликого типа выполняются под одним и тем же именем функции, что весьма наглядно и удобно. Таковой, например, является функция plot, имя которой говорит о построении графиков функций. Если бы разные варианты вызовов этой функции пришлось бы осуществлять под разными именами, то от наглядности не осталось бы и следа. Подведём итог этим рассуждениям: когда функция допускает многовариантность работы при разном числе входных аргументов, это нужно предусмотреть при проверках их числа, и вместо прекращения работы функции осуществить разные ветви выполнения. То же касается и числа возвращаемых значений. В определении функции при этом нужно использовать максимально возможное число как первых, так и вторых. Так, функция function [ res1, res2] = TestFunc2( var1, var2 ) switch nargin case 1 if nargout == 1, res1 = var1 * 2; elseif nargout == 2, res1 = var1 * 2; res2 = var1 + 3; else error( 'Must be 1 or 2 return values' ); end case 2 if nargout == 1, res1 = var1 .* var2; elseif nargout == 2, res1 = var1 .* var2; res2 = var1 + 3; else error( 'Must be 1 or 2 return values' ); end otherwise error( 'Must be 1 or 2 parameters' ); end допускает много вариантов корректных вызовов. Для краткости мы здесь опустили проверку размеров входных параметров, подробно рассмотренную выше. Кроме того, мы здесь намеренно для большей наглядности выполняем некоторую лишнюю работу: на практике MATLAB самостоятельно отслеживает ситуацию превышения числа параметров и возвращаемых значений над номинальным их числом. В заключение отметим, что степень подробности проверок зависит от предназначения функции. Если M-функция пишется для собственного потребления, проверки могут быть менее строгими. Но если предполагается передача функции для внешнего потребления, то проверки нужно сделать более жёсткими, так как внешнему пользователю трудно разобраться во всех деталях работы вашей функции. 5. Видимость имён переменных и имён функций. Локальные и глобальные переменные.Функция располагает собственным, изолированным от рабочего пространства системы MATLAB, пространством переменных. Поэтому, если перед вызовом M-функции в командном окне MATLABа была определена переменная с именем, например, varName1, то нельзя рассчитывать на то, что переменная в теле функции с этим же именем уже имеет некоторое значение. Это совсем другая переменная (хотя у неё и то же самое имя varName1) и располагается она в памяти машины в другой области памяти. Переменные, которые используются в теле M-функции и не совпадают с именами формальных параметров этой функции, называются локальными. По-другому говорят, что они видимы лишь в пределах M-функции. Извне они не видны (не достижимы). Внутри функции не видны переменные, определённые в командном окне MATLABа - они являются внешними по отношению к функции и не видны в ней. Аналогично, локальные внутри некоторой функции переменные не видны внутри другой M-функции. Одним из каналов передачи информации из командного окна системы MATLAB в M-функцию и из одной функции в другую является механизм параметров функции. Другим таким механизмом являются глобальные переменные. Чтобы рабочая область системы MATLAB и несколько M-функций могли совместно использовать переменную с некоторым именем, её всюду нужно объявить как глобальную с помощью ключевого слова global. К примеру, переменная glVarS, участвующая в вычислениях в рабочем пространстве и в функции FuncWithGlobVar является одной и той же переменной (единственный участок памяти) повсюду - поэтому её можно использовать в функции без дополнительного присваивания её какого-либо значения:
Так как у глобальных переменных "глобальная" область действия, то чтобы случайно (по ошибке) не переопределить её где-либо, желательно давать таким переменным более мнемонические (более длинные и осмысленные) имена. Теперь рассмотрим вопрос о видимости имён функций. Если мы сохранили функцию с некоторым именем в файле с этим же именем и расширением m, и кроме того если системе MATLAB известен путь к этому файлу на диске, то эту функцию можно вызывать как из командного окна, так и из других функций. Однако в тексте M-функции можно поместить опеределения нескольких функций, причём только одна из них может совпадать по имени с именем файла. Именно эта функция и будет видна из командного окна и других функций. Все остальные функции будут внутренними - их могут вызывать только функции из того же файла. Например, если в файле ManyFunc.m будет содержаться следующий текст function ret1 = ManyFunc( x1, x2 ) ret1 = x1 .* x2 + AnotherFunc( x1 ) function ret2 = AnotherFunc( y ) ret2 = y .* y + 2 * y + 3; состоящий из определений двух функций с именами ManyFunc и AnotherFunc, то извне можно вызывать только функцию ManyFunc. По-другому можно сказать, что извне видны только функции с именами, совпадающими с именами M-файлов. Остальные функции должны вызываться этой функцией и другими внутренними функциями. 6. Разработка и отладка M-функций. Разрабатывая функцию, вы в первую очередь разрабатываете алгоритм решения некторой задачи, после чего переводите его на формальный язык кодирования, которым и является M-язык. Несмотря на довольно высокую наглядность M-языка (отсутствуют низкоуровневые конструкции, близкие к машинным командам), всё равно это формальный язык. По прошествии времени детали разработок забудутся и для модификации функции придётся всё вспоминать снова. Чтобы упростить процесс дальнейшей модификации функции, а также её отладки на стадии, когда ещё не удалось добиться правильной работы, в текст функции вставляют комментарии. Комментарии могут занимать отдельные строки, начинающиеся с символа %, после которого следует текст комментария. Также комментарии можно располагать в конце любой строки кода, поскольку интерпретатор M-языка, встретив знак %, считает все символы после него просто комментарием (а не командами, подлежащими переводу в машинную форму и исполнению). Особую роль в системе MATLAB имеют комментарии, располагающиеся в смежном наборе строк сразу за заголовком определения функции. Весь этот набор строк выводится в командное окно системы MATLAB при исполнении команды help имя_M-функции Поскольку такую команду в первую очередь будут применять пользователи функции (а не разработчики), то желательно расположить в этих комментариях описательную информацию и сведения о правильном вызове этой функции. Теперь подробно остановимся на вопросе об отладке M-функций, то есть на приёмах, с помощью которых можно выявить месторасположение ошибок и их причину. Система MATLAB осуществляет серьёзную помощь в этом процессе. В частности, при возникновении ошибки в процессе выполнения M-функции, в командное окно выводится приблизительное диагностическое сообщение (не следует переоценивать качество такой диагностики) и номер строки, в котором по мнению MATLABа произошла ошибка. Другим, более развитым способом отладки функции является применение точек останова и пошаговое выполнения тела функции. Для этого применяют встроенные возможности редактора-отладчика системы MATLAB. То, что уже многократно применяемый нами редактор (в нём набираем текст функций и с помощью меню сохраняем в файле) заодно является и отладчиком, говорит даже заголовок его окна: Matlab Editor / Debugger так как debugger в переводе с английского означает "отладчик". Чтобы поставить "точку останова" на какой-либо строке кода функции, туда нужно поместить курсор и нажать клавишу F12 (повторное нажатие этой клавиши убирает точку останова). Вместо нажатия этой клавиши можно выполнить команду меню Debug | Set/Clear Breakpoint но всё же быстрее это можно выполнить нажатием клавиши. После этого в строке слева появляется красный кружок, указывающий на то, что в данной строке проставлена точка останова. После этого, не закрывая окна Редактора/Отладчика (Editor/Debugger), переключаем фокус ввода с клавиатуры в командное окно MATLABа и запускаем обычным образом функцию на выполнение. После этого и произойдёт останов выполнения функции прямо на строке, в которой поставлена точка останова (Breakpoint).
Теперь мы можем просматривать фактические значения входных параметров функции, текущие значения глобальных и локальных переменных, а также значения выражений. Чтобы просмотреть значение переменной, достаточно подвести курсор к её имени в тексте функции, после чего на экране появится всплывающий жёлтый прямоугольник со значением переменной внутри него: Далее, нажимая клавишу F10 мы можем выполнять функцию построчно, каждый раз проверяя результаты такой пошаговой работы функции. В результате всегда можно "окружить ошибку" и выявить её причину. Изменив текст функции и устранив выявленную ошибку,запускаем функцию на выполнение, в результате чего либо удостовериваемся в её правильной работе, либо находим новую ошибку. Желательно продумать методику отладки, запуская функцию на выполнение с разными значениями аргументов и разными значениями глобальных функций. В результате такого итерационнного отладочного процесса приходят к правильно работающим функциям. 7. Массивы символов. До сих пор мы мели дело с единственным типом данных - массивами вещественных чисел. Это действительно основной тип данных системы MATLAB, предназначенный для вычислений. В то же время, при рассмотрении графики MATLABа мы столкнулись с типом данных "короткое целое", обозначаемое с помощью ключевого слова uint8. Этот тип данных специально предназначен для компактного хранения больших массивов целых чисел, что очень характерно для графических задач. Однако производить вычисления с типом данных uint8 нельзя (по крайней мере в версии системы MATLAB 5.2). Если всё же нужно произвести вычисления, то сначала тип данных uint8 приводят явно к типу double, производят вычисления и возвращаются к типу uint8 для дальнейшего хранения. Во всех языках программирования, и MATLAB здесь не исключение, большую роль играет обработка текстовых данных. Для этой цели в системе MATLAB предусмотрен тип данных char (то есть "символ"). Текстовые данные, в том числе и одиночный символ, должны заключаться с обеих сторон апострофами: c1 = 'a'; c2 = 'abcd'; c3 = 'Hello, World!';
В результате таких присваиваний создаются переменные (естественно, это массивы - в системе MATLAB всё является массивами) типа char: Из рисунка видно, что текстовые данные в системе MATLAB являются вектор-строками типа char (одна строка и несколько столбцов по числу содержащихся символов). Например, переменная c3 является символьным массивом (часто говорят - строкой символов) из 13 символов, занимающим 26 байт. Таким образом, под каждый символ отводится 2 байта. Каждый символ кодируется целым числом в соответствии со стандартной системой кодировки ASCII. Легко практически выяснить, какой код соответствует тому или иному символу. Следующий фрагмент code = double( c1( 1 ) ) code = показывает, что символу 'a' соответствует десятичное число 97. Если после того, как переменная c3 получила текстовое значение 'Hello, World!', написать c3 = 3.14; то переменная c3 станет уже переменной типа double. Так как в сложных и громоздких M-функциях могут возникнуть ситуации, когда заранее неизвестен тип переменной в какой-либо момент времени исполнения функции, то с целью определения типа переменной следует применить функцию isa. Например, следующий вызов этой функции isa( s3, 'char' ) вернёт истину (единицу), если переменная s3 является в этот момент строковой (символьной), и вернёт ложь (нуль) в противоположном случае. По отношению к массивам символов справедливы также все операции, которые мы ранее рассмотрели для случая массивов типа double. Например, вместо группового присваивания c2 = 'abcd' можно организовать поэлементное присваивание с помощью операции индексации: c2( 1 )='a'; c2( 2 )='b'; c2( 3 )='c'; c2( 4 )='d'; или осуществить операцию конкатенации c2 = [ 'abc' , 'd' ]; c2 = [ c2 , ' QWERTY' ]; В тесной связи с рассмотренной операцией конкатенации текстовых строк находится стандартная функция int2str, которая преобразует целые числовые значения в символы, отображающие эти целые числа. Например, вызов функции res = int2str( 2 ) приведёт к появлению текстовой переменной res со значением '2'. В итоге, мы имеем возможность сформировать в цикле набор нескольких имён функций, отличающихся только последним символов - их номером: name = 'function'; arg = 10.7; for k = 1 : 10 Name = [ name , int2str( k ) ]; res( k ) = feval( Name, arg ); end и даже вычислить значения всех таких функций при значении аргумента arg. Это осуществляется с помощью стандартной функции системы MATLAB feval, которая принимает в качестве своего первого аргумента текстовую строку с именем M-функции, подлежащей вычислению. Второй и последующие аргументы этой функции служат для передачи в качестве аргументов вычисляемым функциям. В вышеприведённом фрагменте результаты вычислений десяти функций запоминаются в массиве res. Если требуется в одной переменной запомнить несколько имён функций (это возможно в случае их одинаковой длины) для последующего их исполнения с помощью feval, то можно сформировать текстовый массив размерности 2: Names( 1, : ) = 'function1'; Names( 2, : ) = 'function2'; Первая строка этого массива содержит имя первой функции, вторая строка - второй функции. Размер этого массива типа char есть 2 x 9. Часто текстовые строки используются для вывода в командное окно системы MATLAB для информирования пользователя о ходе выполнения M-функции. Это осуществляется с помощью функции disp, принимающей в качестве аргумента текстовую строку: x = 7; message = [ ' Variable x = ', int2str( x ) ]; disp( message ); Кроме того, в командное окно надо выводить сообщения, предупреждающие пользователя о необходимости ввода с клавиатуры значения переменной: VarX = input( ' VarX = ? ' ); Функция input выводит в командное окно текст, являющийся её аргументом, после чего ожидает ввода значения с клавиатуры и нажатия клавиши Enter. Таким образом можно ввести с клавиатуры числовое значение и запомнить её значение в переменной VarX. Внутри строки-аргумента функции input может присутствовать специальный набор из двух символов /n, приводящий к показу сообщения на двух строках (часть сообщения после /n показывается на новой строке ). Для ввода текстового значения, а не числового, требуется вызывать функцию input с двумя аргументами: VarStr = input( ' StringVar = ', 's' ); В результате выполнения этой функции на экране появляется надпись StringVar = после чего можно набирать необходимый текст с клавиатуры, заканчивая ввод нажатием клавиши Enter. Если нажать Enter, не введя с клавиатуры никакого текста, то переменная VarStr примет значение пустого массива. Желательно перед использованием этой переменной проверять её на этот случай функцией isempty(VarStr), возвращающей единицу, когда аргумент является пустым массивом. Система MATLAB располагает также полным набором функций для "классической" обработки текстов. К таким функциям относятся функции findstr, blanks, deblank, num2str, str2num, strcat, strcmp, strcmpi, strrep, strtok. Функции num2str, str2num производят преобразования из строк в действительные числа и обратно, функции blanks, deblank, strrep работают с пробелами и повторением символов, функция strcat осуществляет конкатенацию, функции strcmp и strcmpi сравнивают значения двух строк, функции findstr и strtok находят или выделяют в строках подстроки. Например, в следующем фрагменте находится массив позиций вхождения слова Hello в текст, содержащийся в переменной vStr: innerStr = 'Hello'; vStr='Hello is the word. Hello is opposite to bye.'; positions = findstr( vStr, innerStr ); В результате переменная (масси ) positions принимает следующее значение: positions = 1 20 В итоге функция findstr обнаружила два вхождения переменной innerStr в текст Vstr. Первое вхождение имеет место начиная с самого первого символа, второе вхождение имеет место на 20-ом символе (включая пробелы, разумеется). Если функция findstr не находит вхождений вообще, то она возвращает пустой массив, который надо проверять функцией isempty. 8. Массивы структур. Бывает желательно под одним именем объединить числовые и текстовые данные (например, результаты физических экспериментов, данные о переписи населения и так далее). Для этой цели в системе MATLAB предусмотрен специальный тип данных - struct ( структура ). Переменные типа struct имеют в своём составе несколько именованных полей. Создадим переменную MyStruct1, состоящую из двух полей: одного числового поля с именем data и одного текстового поля с именем name: MyStruct1.name = '1st result'; MyStruct1.data = [ 1, 2.5; -7.8, 2.3 ]; Имя поля отделяется от имени переменной точкой. В данном фрагменте кода создаётся массив MyStruct1 типа struct размером 1 x 1. Добавим в только что созданный массив MyStruct1 второй элемент: MyStruct1( 2 ).name = '2nd res-t'; MyStruct1( 2 ).data = [ -5.7, -2.5; 7.1, 8.4 ]; Получился массив размера 1x2. В этом легко убедиться, если набрать в командном окне MATLABа имя переменной MyStruct1 и нажать клавишу Enter. В результате система покажет не содержимое этого массива, а его структуру:
Можно и далее добавлять элементы к этому одномерному массиву. Достаточно очевидно, что все элементы массива типа struct имеют одинаковое количество полей с фиксированными именами. Если явно не задать значение какого-либо поля, то ему автоматически будет присвоен пустой массив []. Набор полей массива структур можно изменять динамически. Например, уже после того, как мы определили массив MyStruct1 типа struct размера 1x2 с двумя указанными выше полями (name и data), можно выполнить присваивание MyStruct1( 1 ).field = 'Third field'; после которого массив структур уже будет обладать тремя полями - name, data и field. Так как у второго элемента массива MyStruct1 поле field явно не задано, то оно равно пустому массиву: MyStruct1( 2 ).field ans = [] Если два массива структур имеют одинаковый набор полей, то допускается групповое присваивание вида MyStruct1( 3 ) = AnotherStruct( 2 ); когда значения всех полей второго элемента массива AnotherStruct копируются в поля третьего элемента массива MyStruct1. Если работа ведётся в интерактивном режиме, когда все данные вводятся с клавиатуры, рассмотренный процесс последовательного задания полей и элементов массива структур вполне оправдан. Однако в программном режиме он не достаточно хорош с точки зрения производительности. Вместо него лучше использовать функцию с именем struct: MyStruct2 = struct( 'field1',[ 1 2 3],'field2','Hello'); MyStruct2(2)= struct( 'field1',[ 7 8 9],'field2','World'); Покажем теперь (хотя это и очевидно), как подобраться к единственному числовому значению в поле data первого элемента массивы MyStruct1. Для этого надо применить две операции индексации и одну операцию доступа к полю структуры. Например, выражение MyStruct1( 1 ).data( 1 , 2 ) имеет значение 2.5, так как в поле data расположены числовые матрицы 2x2. Если же требуется групповая операция копирования содержимого одноимённого поля всех элементов массива структур, то здесь решение менее очевидно: v = [ MyStruct1.data ]; Применение прямоугольных скобок обязательно, так как над значениями полей отдельных элементов производится операция конкатенации, которая в системе MATLAB и обозначается прямоугольными скобками. В результате такой операции переменная v становится матрицей 2x4 ( если учесть ранее введённые значения ). Для удаления некоторого поля из всех элементов созданного массива структур применяют функцию rmfield: MyStruct2=rmfield(MyStruct2,'field2'); После этого в массиве структур MyStruct2 остаётся только поле field1. В качестве содержимого некоторого поля структуры может выступать другая структура, то есть структуры могут быть вложенными. В качестве имени вложенной структуры выступает имя поля объемлющей структуры: Outer.number = 1; Outer.inner.name='name1'; Outer.inner.data=[ 5 3; 7 8]; Здесь Outer - имя внешней (объемлющей) структуры, а inner - имя внутренней структуры, являющейся полем структуры Outer. Для чтения числового данного, стоящего во второй строке первого столбца (поле data), применяем выражение Outer.inner.data( 2, 1 )
MATLAB сообщает, как устроены структуры Outer и inner следующим образом: В тех случаях, когда массивы структур передаются M-функциям в качестве параметров, следует аккуратно проверять их на наличие требуемых для работы полей. Для этого можно воспользоваться следующими функциями: isstruct( s ) - возвращает истину, если аргумент структура isfield( s, 'name') - возвращает истину, если имеется такое поле fieldnames( s ) - возвращает массив строк с именами всех полей Структуры MATLABа можно назвать агрегированным типом данных. Другим агрегированным типом данных в системе MATLAB являются так называемые ячейки (cells). 9. Массивы ячеек. Массив ячеек может содержать в качестве элементов массивы разных типов! Таким образом, он является универсальным контейнером - его ячейки могут содержать любые типы и структуры данных, с которыми работает MATLAB - массивы чисел любой размерности, строки, массивы структур и другие (вложенные) массивы ячеек. Массив ячеек может быть полем структуры. Методы создания массивов ячеек похожи на методы создания структур. Как и в случае структур, массивы ячеек могут быть созданы либо путём последовательного присваивания значений отдельным элементам массива, либо созданы целиком при помощи специальной функции cell(). Однако в любом случае важно различать ячейку (элемент массива ячеек) и её содержимое. Ячейка - это содержимое плюс некоторая оболочка (служебная структура данных) вокруг этого содержимого, позволяющая хранить в ячейке произвольные типы данных любого размера. Выражение любого типа данных системы MATLAB можно превратить в ячейку, заключив его в фигурные скобки. Тогда с помощью следующих присваиваний и обычных операций индексации MyStruct = struct( 'field1',[ 1 2 3],'field2','Hello'); MyCellArray( 1, 1 ) = { 'Bonjour!' }; MyCellArray( 1, 2 ) = { [ 1 2 3; 4 5 6; 7 8 9 ] }; MyCellArray( 2, 1 ) = { MyStruct }; MyCellArray( 2, 2 ) = { [ 9 7 5 ] };
строится массив ячеек 2x2, элементами которого являются ячейки, содержащие соответственно текстовую строку, числовой массив 3x3, структуру MyStruct и вектор-строку 1x3. Итак, построенный массив ячеек содержит разнородные данные, о чём нам и сообщает система MATLAB при вводе имени такого массива и нажатии клавиши Enter: При этом показывается содержимое не всех ячеек этого массива. Более подробную информацию можно получить, вызвав функцию celldisp(MyCellArray): MyCellArray{1,1} = Bonjour! MyCellArray{2,1} = field1 : [ 1 2 3 ] field2 : 'Hello' MyCellArray{1,2} = 1 2 3 4 5 6 7 8 9 MyCellArray{2,2} = 9 7 5 Отсюда видно, что для того, чтобы подобраться к содержимому ячеек, нужно индексировать массив ячеек при помощи фигурных скобок. При обычной индексации круглыми скобками мы из массива ячеек извлекаем отдельную ячейку. Напоминаем ещё раз о том, что следует чётко различать саму ячейку и её содержимое (см. выше). Массивы ячеек полностью решают типовую задачу хранения нескольких строковых данных под одним именем. Раньше мы уже формировали матрицы типа char, каждая строка которых имела одну и ту же длину. Это очевидным образом ограничивает применение такого решения. В случае массива ячеек такого ограничения нет: cellNames{ 1 } = 'function1'; cellNames{ 2 } = 'func2'; Здесь мы продемонстрировали применение фигурных скобок в роли индексирующих элементов, так что использовать фигурные скобки в правых частях операции присваивания теперь не нужно (там присутствуют значения, а не ячейки). В итоге под именем массива cellNames хранятся две текстовые строки (можно и больше), доступ к каждой из которых осуществляется по индексу в соответствии с синтаксисом массива ячеек. Вот код, который выводит на экран обе текстовые строки: disp( cellNames{ 1 } ); disp( cellNames{ 2 } ); Как и в случае структур, показанное выше поэлементное создание массива ячеек неэффективно с точки зрения производительности. Это не создаёт проблем в медленном интерактивном режиме работы, но в программном режиме этот процесс лучше предварить вызовом функции cell(): MyCellArray = cell( 2, 2 ); которая сразу создаст массив ячеек требуемой размерности и размера, причём каждая ячейка будет пустой. Пустые ячейки обозначаются как {[]}. Затем можно осуществлять ранее рассмотренные поэлементные присваивания, так как теперь они не требуют перестройки структуры массива с каждым новым присваиванием. Содержимым пустой ячейки является пустой числовой массив, который, как мы знаем, обозначается []. Чтобы удалить некоторый диапазон ячеек из массива ячеек, нужно этому диапазону присвоить значение пустого массива []: MyCellArray( 2, : ) = []; Теперь массив ячеек MyCellArray имеет размер 1x2, так как мы только что удалили всю вторую строку массива. У массивов ячеек имеется множество полезных применений. Например, с помощью массива ячеек решается задача организации M-функции, которой можно передать произвольно большое число аргументов. Допустим, требуется вычислить суммарную длину заранее неизвестного числа вектор-строк. Эта задача решается с помощью ключевых слов varargin и varargout (второе ключевое слово используется, когда M-функция возвращает заранее неизвестное число выходных значений). В определении M-функции параметр, через который передаётся заранее неизвестное число входных аргументов, нужно обозначить ключевым словом varargin. Им обозначается массив ячеек, в который упакованы эти параметры. Функция всегда может узнать истинное число аргументов в этом параметре, вычислив функцию length. Ниже представлен код функции, вычисляющей сумму квадратов длин вектор-строк: function sumlen = NumLength( varargin ) n= length( varargin ); sumlen = 0; for k = 1 : n sumlen = sumlen + varargin{ k }(1)^2 +varargin{ k }(2)^2; end
![]() |