Главная страница

Программирование в Scilab Микаэль Боден Micha


Скачать 1.35 Mb.
НазваниеПрограммирование в Scilab Микаэль Боден Micha
Дата18.09.2022
Размер1.35 Mb.
Формат файлаpdf
Имя файлаprogscilab-v.0.10_ru.pdf
ТипРеферат
#683094
страница6 из 13
1   2   3   4   5   6   7   8   9   ...   13
f u n c t i o n t h i s = c o m p a n y _ n e w ()
t h i s = t l i s t ([ " T C O M P A N Y " , " n am e " , " a d d r e s s " , " p u r p o s e " , " e m p l o y e e s " ])
41
t h i s . n a m e = " "
t h i s . a d d r e s s = " "
t h i s . p u r p o s e = " "
t h i s . e m p l o y e e s = l i s t ()
e n d f u n c t i o n
Следующая функция company_addperson позволяет добавлять нового человека в список работников.
f u n c t i o n t h i s = c o m p a n y _ a d d p e r s o n ( th i s , p e r s o n )
t h i s . e m p l o y e e s ( $ +1) = p e r s o n e n d f u n c t i o n
На самом деле, методы, которые широко используются в ООП, могут применяться используя эту схему имитации. Это позволяет создавать отдельные компоненты, предостав- ляющие прозрачный публичный интерфейс и избегающие необходимости в сложных функ- циях, использующих большое количество позиционных аргументов.
3.8
Перегрузка типизированных списков
В этом разделе мы увидим как перегрузить функцию string так, что бы мы могли преобразовать типизированный список в строку. Мы также рассмотрим как перегрузить функцию disp, т. е. систему печати, которая позволяет настраивать печать типизированных списков.
Следующая функция %TPERSON_string возвращает матрицу строковых значений, со- держащую описание текущего объекта «person». Она сначала создаёт пустую матрицу. За- тем она добавляет строки одну за другой с помощью выходного значения функции sprintf,
которая позволяет форматировать строки.
f u n c t i o n str = % T P E R S O N _ s t r i n g ( t h i s )
str = []
k = 1
str ( k ) = s p r i n t f ( " P e r s o n : " )
k = k + 1
str ( k ) = s p r i n t f ( " = = = = = = = = = = = = = = = = = = = = = = " )
k = k + 1
str ( k ) = s p r i n t f ( " N a m e : %s " , t hi s . n a m e )
k = k + 1
str ( k ) = s p r i n t f ( " F i r s t n a m e : %s " , t h i s . f i r s t n a m e )
k = k + 1
str ( k ) = s p r i n t f ( " P h o n e : %s " , th i s . p h o n e )
k = k + 1
str ( k ) = s p r i n t f ( " E - m a i l : %s " , t h i s . e m a i l )
e n d f u n c t i o n
Функция %TPERSON_string позволяет перегрузить функцию string для любого объекта с типом TPERSON.
Следующая функция %TPERSON_p распечатывает текущий объект «person». Она сна- чала вызывает функцию string для того, чтобы вычислить матрицу строк, описывающих объект «person». Затем она делает циклы по рядам матрицы и распечатывает их один за другим в консоли.
f u n c t i o n % T P E R S O N _ p ( t h i s )
str = s t r i n g ( th i s )
n b r o w s = s i z e ( str , " r " )
42
for i = 1 : n b r o w s m p r i n t f ( " %s \ n " , str ( i ))
end e n d f u n c t i o n
Функция %TPERSON_p позволяет перегрузить распечатку объектов с типом TPERSON (буква
«p» обозначает распечатку («print»)).
В следующем примере мы вызываем функцию string с объектом «person» p1.
- - > p1 = p e r s o n _ n e w ();
- - > p1 = p e r s o n _ c o n f i g u r e ( p1 , " - n a m e " , " B a c k u s " );
- - > p1 = p e r s o n _ c o n f i g u r e ( p1 , " - f i r s t n a m e " , " J o h n " );
- - > p1 = p e r s o n _ c o n f i g u r e ( p1 , " - p h o n e " , " 0 1 . 2 3 . 4 5 . 6 7 . 8 9 " );
- - > p1 = p e r s o n _ c o n f i g u r e ( p1 , " - e m a i l " , " j o h n . b a c k u s @ c o m p a n y . com " );
- - > s t r i n g ( p1 )
ans
=
! P e r s o n :
!
!
!
! = = = = = = = = = = = = = = = = = = = = = =
!
!
!
! N a m e : B a c k u s
!
!
!
! F i r s t n a m e : J o h n
!
!
!
! P h o n e : 0 1 . 2 3 . 4 5 . 6 7 . 8 9
!
!
!
! E - m a i l : j o h n . b a c k u s @ c o m p a n y . com
!
В
предыдущем примере функция string автоматически вызвала функцию
%TPERSON_string, которую мы определили ранее.
В следующем примере мы просто напечатаем имя переменной p1 (и немедленно на- жмём клавишу enter в консоли), как и с любой другой переменной. Это распечатает содер- жимое нашей переменной p1.
- - > p1
p1
=
P e r s o n :
= = = = = = = = = = = = = = = = = = = = = =
N a m e : B a c k u s
F i r s t n a m e : J o h n
P h o n e : 0 1 . 2 3 . 4 5 . 6 7 . 8 9
E - m a i l : j oh n . b a c k u s @ c o m p a n y . com
В предыдущем примере система печати автоматически вызвала функцию %TPERSON_p, ко- торую мы уже определили ранее. Заметим, что будет сделан тот же вывод как если бы мы использовали команду disp(p1).
Наконец, мы уничтожим текущий объект «person».
p1 = p e r s o n _ f r e e ( p1 );
Есть много других функций, которые могли бы быть определены для типизированных списков. Например, мы можем перегрузить оператор + так, что мы можем суммировать два объекта «person». Это описано более подробно на страницах справки, посвящённых пере- грузке:
h e l p o v e r l o a d i n g
43

3.9
Тип данных mlist
В этом разделе мы представляем тип данных mlist, который является матрично- ориентированным списком. В первой части этого раздела мы представляем главную мо- тивацию для типа данных mlist сравнивая с tlist. Затем мы представляем пример mlist,
где мы определяем функцию выделения.
Главная разница между tlist и mlist состоит в отношении к выделению и встав- ке функций. В самом деле, для tlist M выделение, основанное на индексах, т. е. команда x=M(2), например, определена по умолчанию. Она может быть перегружена пользователем,
но это не обязательно, как мы увидим далее.
В следующем примере мы определяем tlist с типом «V». Этот типизированный список имеет два поля, «name» (имя) и «age» (возраст).
M = t l i s t ([ " V " , " n a m e " , " age " ] ,[ " a " , " b " ; " c " " d " ] ,[1 2; 3 4 ] ) ;
Как ожидалось от tlist, команда M(2) позволяет выделить второе поле, т. е. «name» (имя)
переменной.
- - > M (2)
ans
=
! a b
!
!
!
! c d
!
То же самое для вставки (т. е. M(2)=x) в list (или tlist).
С другой стороны, для mlist выделение и вставка функций должна быть определена.
Если нет, то формируется ошибка.
В следующем примере мы определяем mlist с типом «V». Как и прежде, этот список матриц имеет два поля, «name» и «age».
M = m l i s t ([ " V " , " n a m e " , " age " ] ,[ " a " , " b " ; " c " " d " ] ,[1 2; 3 4 ] ) ;
В следующем примере мы видим, что не можем напрямую выделять второе поле этого списка
- - > M (2)
! - - e r r o r 144
Операция для заданных операндов не определена.
отметьте или определите функцию % l _ e как перегружаемую.
Сообщение об ошибке говорит нам, что мы не можем выделить второй элемент переменной M
и что должна быть определена некая функция, которую мы увидим позднее в этом разделе.
Давайте рассмотрим предыдущий пример и предположим, что M — это tlist. Особая проблема с M заключается в том, что второй элемент M(2) может не соответствовать тому,
что нам надо. В самом деле, переменная M(2) является матрицей строковых переменных
["a","b";"c" "d"]. Но возможны такие ситуации, где нам бы хотелось выразить, что «вто- рой элемент» представляет особый элемент, который не соответствует особому значению,
которое связано с tlist.
К примеру, мы можем захотеть конкатенировать имя со значением для формирова- ния строки «Name: b, age: 2», которая бы была вторым элементом нашей матрицы M. Сле- довательно, кажется, что нам нужно переопределить выделение (или вставку) значений для tlist. Но это невозможно, поскольку система перегрузки позволяет только определять функции, которые не существуют: в этом случае функция выделения уже существует, так что мы не можем определять её. Это случай, когда полезен mlist: мы можем определить
44
функции выделения и вставки для mlist и настроить их поведение. Фактически, мы даже принуждаем делать так: поскольку, как мы видели до этого, это обязательно.
Для того, чтобы определить функцию выделения для mlist с «V», мы должны опреде- лить функцию %V_e, где буква «e» обозначает «extraction» (выделение). Это сделано в следу- ющем примере.
Заголовок функции выделения должен быть
[x1,...,xm]=%_e_(i1,...,in,a), где x1,...,xm — выделенные значения,
i1,...,in — индексы значений, которые нужно выделить, и a — текущая переменная.
Следовательно, команда M=varargin($) позволяет установить в M текущую переменную из которой выделяются значения. Затем индексы могут быть получены с помощью команды varargin(1:$-1), которая создаёт список переменных, содержащий действующие индек- сы. Наконец, мы создаём матрицу строковых переменных конкатенацией имени со строкой,
представляющей возраст.
f u n c t i o n r = % V _ e ( v a r a r g i n )
M = v a r a r g i n ( $ )
r = " N a m e : " + M . n a m e ( v a r a r g i n (1: $ - 1) ) + ..
" , Age : " + s t r i n g ( M . age ( v a r a r g i n (1: $ - 1 ) ) )
e n d f u n c t i o n
В следующем примере мы выделяем второй элемент M.
- - > M (2)
ans
=
N a m e : c , Age : 3
Мы можем также использовать синтаксис, который очень похож на матрицы, как в следу- ющем примере.
- - > M ( 2 : 3 )
ans
=
! N a m e : c , Age : 3
!
!
!
! N a m e : b , Age : 2
!
- - > M (2 ,:)
ans
=
! N a m e : c , Age : 3
N a m e : d , Age : 4
!
- - > M (: ,1)
ans
=
! N a m e : a , Age : 1
!
!
!
! N a m e : c , Age : 3
!
3.10
Тип данных struct
В этом разделе мы кратко представляем struct, которая является структурой данных,
с беспорядочными составляющими разнородных типов. Мы сравним её характеристики с list.
Внутри struct все составляющие могут быть выделены по их именам. В следующем примере мы определяем переменную d как struct с тремя полями «day» (день), «month»
(месяц) и «year» (год ).
- - > d = s t r u c t ( " day " ,25 , " m o n t h " , " DEC " , " y e a r " ,2006)
d
=
day : 25
m o n t h : " DEC "
y e a r : 2 0 06 45

Заметьте, что поля структуры struct не обязаны быть одного типа: первое поле — это строка, а второе поле число типа double. Для того, чтобы выделить переменную из struct,
мы просто используем имя переменной после точки «.» и имя поля.
- - > d . m o n t h ans
=
DEC
Для того, чтобы вставить значение в struct, мы просто используем оператор присво- ения «=».
- - > d . m o n t h =AUG
d
=
day : 25
m o n t h : " AUG "
y e a r : 2 0 06
Структура struct может содержать другую структуру struct, что может привести к структурам вложенных данных. Например, в следующем примере мы создаём уик-энд из двух последовательных дней.
- - > d1 = s t r u c t ( " day " ,01 , " m o n t h " , " JAN " , " y e a r " ,2011);
- - > d2 = s t r u c t ( " day " ,02 , " m o n t h " , " JAN " , " y e a r " ,2011);
- - > w e e k e n d = s t r u c t ( " Sat " , d1 , " Sun " , d2 )
w e e k e n d
=
Sat : [1 x1 s t r u c t ]
Sun : [1 x1 s t r u c t ]
- - > w e e k e n d . Sat ans
=
day : 01
m o n t h : " JAN "
y e a r : 2 0 11
С точки зрения гибкости tlist более мощный нежели struct. Это из-за того, что мы можем перегружать функции так, что их поведение может быть настроено для tlist. Дей- ствительно, настройка поведения структуры struct невозможна. Вот почему большинство пользователей предпочитают тип данных tlist.
Фактически, главное преимущество struct — это совместимость с Matlab и Octave.
3.11
Массив структур struct
Массив структур struct — это массив, где каждый индекс связан со структурой struct.
Есть несколько способов создать массив структур. В первой части этого раздела мы конка- тенируем несколько структур для создания массива. Во второй части мы инициализируем целый массив структур за один вызов, а затем заполняем поля одно за другим.
Если несколько структур имеют одинаковые поля, и если все эти поля имеют одина- ковый размер, то они могут быть конкатенированы в один массив структур. В следующем примере мы создаём четыре отдельных структуры.
s1 = s t r u c t ( " f i r s t n a m e " , " J o h n " , " b i r t h y e a r " ,1940);
s2 = s t r u c t ( " f i r s t n a m e " , " P a u l " , " b i r t h y e a r " ,1942);
s3 = s t r u c t ( " f i r s t n a m e " , " G e o r g e " , " b i r t h y e a r " ,1943);
s4 = s t r u c t ( " f i r s t n a m e " , " R i n g o " , " b i r t h y e a r " ,1940);
Заметим, что поля не обязаны быть одного типа: первое поле — строка, а второе поле — число типа double. Затем мы конкатенируем их в один массив структур, используя синтаксис [],
который схож с матрицами.
46

- - > s =[ s1 , s2 , s3 , s4 ]
s
=
1 x4 s t r u c t a r r a y w i t h f i e l d s :
f i r s t n a m e n a m e
Мы можем выделить третью структуру из массива используя синтаксис s(3), который схож с матрицами.
- - > s (3)
ans
=
f i r s t n a m e : " G e o r g e "
n a m e : " H a r r i s s o n "
Мы можем получить доступ к полю «firstname» всех структур, как показано в следующем примере. Это даёт список строк.
- - > s . f i r s t n a m e ans
=
ans (1)
J o h n ans (2)
P a u l ans (3)
G e o r g e ans (4)
R i n g o
- - > t y p e o f ( s . f i r s t n a m e )
ans
=
l i s t
По причине производительности мы не советуем позволять структура расти динамиче- ски. Это из-за того, что это заставляет интерпретатор динамически распределять больше и больше памяти и может привести к медленным файлам-сценариям. Вместо этого, где только возможно, нам следует предопределять массивы структур, а затем заполнять существующие ячейки.
В следующем примере мы определяем массив размером 4 × 1 структур struct, где каждая структура содержит пустое firstname и пустое name.
t ( 1 : 4 ) = s t r u c t ( " f i r s t n a m e " ,[] , " b i r t h y e a r " ,[])
Затем мы заполняем каждую структуру как в следующем примере.
t ( 1 ) . f i r s t n a m e = " J o h n " ;
t ( 1 ) . b i r t h y e a r = 1 9 4 0 ;
t ( 2 ) . f i r s t n a m e = " P a u l " ;
t ( 2 ) . b i r t h y e a r = 1 9 4 2 ;
t ( 3 ) . f i r s t n a m e = " G e o r g e " ;
t ( 3 ) . b i r t h y e a r = 1 9 4 3 ;
t ( 4 ) . f i r s t n a m e = " R i n g o " ;
t ( 4 ) . b i r t h y e a r = 1 9 4 0 ;
Мы можем проверить, что это даёт в точности тот же массив структур, что и прежде.
- - > t t
=
4 x1 s t r u c t a r r a y w i t h f i e l d s :
f i r s t n a m e b i r t h y e a r
- - > t (1)
47
ans
=
f i r s t n a m e : " J o h n "
b i r t h y e a r : 1 9 4 0
В предыдущим примерах мы видели только массивы с одним индексом. Должно быть ясно, что массив структур является в действительности 2
х
-индексным массивом, т. е. мат- рицей. Кстати, мы собираемся рассмотреть другой метод инициализации массива структур.
В следующем примере мы инициализируем массив структур размером 2 × 2.
- - > u (2 ,2). f i r s t n a m e =[]
u
=
2 x2 s t r u c t a r r a y w i t h f i e l d s :
f i r s t n a m e
- - > u (2 ,2). b i r t h y e a r =[]
u
=
2 x2 s t r u c t a r r a y w i t h f i e l d s :
f i r s t n a m e b i r t h y e a r
Затем мы можем заполнить ячейки с помощью синтаксиса, который похож на матрицы.
u (1 ,1). f i r s t n a m e = " J o h n " ;
u (1 ,1). b i r t h y e a r = 1 9 4 0 ;
u (2 ,1). f i r s t n a m e = " P a u l " ;
u (2 ,1). b i r t h y e a r = 1 9 4 2 ;
u (1 ,2). f i r s t n a m e = " G e o r g e " ;
u (1 ,2). b i r t h y e a r = 1 9 4 3 ;
u (2 ,2). f i r s t n a m e = " R i n g o " ;
u (2 ,2). b i r t h y e a r = 1 9 4 0 ;
Сделав однажды, мы можем выделять структуры, связанные с индексами (2,1), например.
- - > u (2 ,1)
ans
=
f i r s t n a m e : " P a u l "
b i r t h y e a r : 1 9 4 2 3.12
Тип данных cell
В этом разделе мы кратко представляем cell, который является разнородным масси- вом переменных. Затем мы сравниваем его характеристики с характеристиками гипермат- рицы hypermatrix и списка list. Рисунок
17
представляет несколько функций, связанных с массивами cell.
cell
Создать сell-массив с пустыми ячейками.
cell2mat
Преобразовать cell-массив в матрицу.
iscell
Проверить, является ли переменная cell-массивом.
makecell
Создать cell-массив и инициализировать его ячейки.
Рис. 17: Функции, связанные с массивами cell.
Функция cell позволяет создавать массив. Этот cell-массив может содержать другие типы переменных, включая double, integer, string и т. д. В следующем примере мы создаём cell-массив размером 2 × 3.
48

- - > c = ce l l (2 ,3)
c
=
!{}
{}
{}
!
!
!
!{}
{}
{}
!
Размер cell-массива может быть вычислен с помощью функции size.
- - > s i z e ( c )
ans
=
2.
3.
Для того, чтобы ввести значение в cell-массив, мы не можем использовать тот же синтаксис, что и для матриц.
- - > c ( 2 , 1 ) = 1 2
! - - e r r o r 1 0 0 0 0
I n v a l i d a s s i g n e m e n t : for i n s e r t i o n in cell , use e . g . x ( i , j ). e n t r i e s = y at l i n e
3 of f u n c t i o n g e n e r i c _ i _ c e c a l l e d by :
at l i n e
3 of f u n c t i o n % s _ i _ c e c a l l e d by :
c ( 2 , 1 ) = 1 2
Вместо этого мы можем использовать поле entries элемента (2,1), как в следующем при- мере.
- - > c (2 ,1). e n t r i e s =12
c
=
!{}
{}
{}
!
!
!
!12
{}
{}
!
В следующем примере мы вводим строку в элемент (1,3).
- - > c (1 ,3). e n t r i e s = " 5 "
c
=
!{}
{}
" 5 "
!
!
!
!12
{}
{}
!
Для того, чтобы удалить элемент (1,3), мы можем использовать матрицу [].
- - > c (1 ,3). e n t r i e s =[]
c
=
!{}
{}
{}
!
!
!
!12
{}
{}
!
Мы можем выделять часть cell-массива, используя синтаксис, схожий с матрицами. Заметим,
что результатом является cell-массив.
- - > x = c (1:2 ,1)
x
=
!{}
!
!
!
!12
!
- - > t y p e o f ( x )
ans
=
ce
С другой стороны, когда мы выделяем одну конкретную ячейку с помощью поля entries, мы получаем тот же тип данных, что и в данная конкретная ячейка. В следующем примере мы выделяем ячейку (2,1) в переменную x и проверяем, что эта переменная имеет тип double.
49

- - > x = c (2 ,1). e n t r i e s x
=
12.
- - > t y p e o f ( x )
ans
=
c o n s t a n t
1   2   3   4   5   6   7   8   9   ...   13


написать администратору сайта