Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ
DESCRIPTION
Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ. Производные типы, зачем ?. При сортировке используются перестановки элементов. Перестановка требует 3 операции присваивания . tmp = x(12) x(12) = x(15) x(15) = tmp Для перестановки двух частиц потребуется записать 21 (!) операции присваивания. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/1.jpg)
Лекция 9
ПРОИЗВОДНЫЕ
ТИПЫ
![Page 2: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/2.jpg)
Производные типы, зачем ?
! данные N частицreal x(N)real y(N)real z(N)logical status(N)real temperature(N)real pressure(N)integer color(N)
При сортировкеиспользуются
перестановки элементов.
Перестановка требует 3 операции присваивания.
tmp = x(12) x(12) = x(15) x(15) = tmp
Для перестановки двух частиц потребуется
записать 21(!) операции присваивания.
![Page 3: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/3.jpg)
Производные типы, зачем ?Лучше объединить типы под одним "общим типом“.
type particle real x ! координаты real y real z logical status real temperature ! физические real pressure ! параметрыinteger color ! цветend type particle
type (particle) M(N), tmp... tmp = M(12) ! 3 присваивания M(12) = M(15) M(15) = tmp
поля
![Page 4: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/4.jpg)
Оператор type
Объявляет новый тип данных,группируя под одним именем существующие типы.
type имя
типы данных
contains
процедуры привязанные к типу
end type имя
![Page 5: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/5.jpg)
Операция " . " или " % ".
Доступ к полям
Задание начальных значений для каждого поля лучше с использованием конструктора.
program prog type NewType integer A real B character C logical D end type NewType
type (NewType) PS
PS.A = 35; PS.B = 3.14; PS.C = 'E'; PS.D = .FALSE. PS%A = 25; PS%B = 5.67; PS%C = 'Q'; PS%D = .TRUE.
end
![Page 6: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/6.jpg)
Конструктор производного типа
program prog type NewType integer A real B character C logical D end type NewType
type (NewType) :: PS0 = NewType(1, 0.32, 'Z', .FALSE.) type (NewType) PS1 type (NewType), allocatable :: PS2
PS1 = NewType(5, 3.5, 'Q', .TRUE.)
allocate(PS2); PS2 = NewType(8, 1.2, 'F', .TRUE.) ! ИЛИ allocate(PS2, source = NewType(8, 1.2, 'F', .TRUE.)) write(*,*) PS2 ! вывод значений всех полейend
конструктор
Конструктор – функция с именем производного типа. Параметры функции - поля производного типа.
![Page 7: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/7.jpg)
Иерархия типовtype person character(128) fio integer ageend type person
type firm type (person) people(1000) character(128) name integer moneyend type firm
type (firm) FM
FM.money = 100000 ! доступ к полямFM.name = 'Siberia'FM.people(1).fio = 'Ivanov S.K.'FM.people(1).age = 35
![Page 8: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/8.jpg)
type PARENT ! родитель integer A real Bend type PARENT
type, extends (PARENT) :: CHILD ! потомок character Cend type CHILD
type (CHILD) pas1, pas2
pas1 = CHILD(PARENT(1,2.0),'A')pas2 = CHILD(1,2.0,'A')
Расширение типа, extends
Тип CHILD наследует поля типа PARENT
![Page 9: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/9.jpg)
Оператор classClass объявляет полиморфную переменную.
Если полиморфная переменная не является формальным параметром процедуры, то
используются атрибуты allocatable или pointer.
class (имя производного типа), allocatable :: имя
type PARENT integer A real B end type PARENT type, extends (PARENT) :: CHILD ! наследуем тип PARENT character C end type CHILD type (CHILD), allocatable :: CL1 class (CHILD), allocatable :: CL2 allocate(CL1, source = CHILD(1,3.0,'Q')) allocate(CL2, source = CHILD(1,3.0,'Q'))
Переменная CL2 имеет больше возможностей.
![Page 10: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/10.jpg)
Полиморфная переменная объявленная родительским типом может "принимать" все дочерние типы.
Оператор class
program prog type PARENT integer A real B end type PARENT
type, extends (PARENT) :: CHILD_A character C end type CHILD_A
type, extends (PARENT) :: CHILD_B logical D end type CHILD_B
type, extends (CHILD_A) :: CHILD_CHILD_A complex E end type CHILD_CHILD_A
![Page 11: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/11.jpg)
Оператор classclass (PARENT), pointer :: PAR
type (PARENT), target :: P type (CHILD_A), target :: CA type (CHILD_B), target :: CB type (CHILD_CHILD_A), target :: CCA
PAR => P ! стал родителем PAR => CA ! теперь потомок А PAR => CB ! изменился на потомка B PAR => CCA ! теперь потомок потомка А
end
PARENT
CHILD_A
CHILD_B
CHILD_CHILD_A
![Page 12: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/12.jpg)
Конструкция select typeКак определить какой тип имеет
полиморфная переменная ?
Select type позволяет выполнить блок операторов в зависимости от динамического типа полиморфной
переменной.
select type (переменная)
type is (имя типа)
class is (имя типа)
class default
end select
![Page 13: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/13.jpg)
Оператор select type
Схема выполнения
Находится и выполняется блок type is
Если не найден type is, то находится и выполняется class is.
Если найдено соответствие нескольким блокам class is, то выбирается ближайший родитель.
Если не найден ни один блок выбирается class default.
![Page 14: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/14.jpg)
Оператор select type... type (PARENT), target :: P type (CHILD_CHILD_A), target :: CCA PAR => CCA ! потомок потомка А
select type (PAR) class is (PARENT) write (*,*) "PARENT"
class is (CHILD_A) write(*,*) "CHILD" ! выбирается ближайший родитель
class default write(*,*) "default...." end select end
PARENTCHILD_A
CHILD_B
CHILD_CHILD_A
![Page 15: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/15.jpg)
Оператор class(*)Неограниченно полиморфная переменная
принимает любые типы
type T1 integer index real val end type T1
type T2 logical status character symbol character(10) name end type T2
complex(16), target :: CMP type (T1), target :: PT1 type (T2), target :: PT2
class (*), pointer :: PAR ! неограниченно полиморфная
PAR => PT1 ! сейчас типа T1 PAR => PT2 ! теперь типа T2 PAR => CMP ! затем комплексный тип
![Page 16: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/16.jpg)
procedure(proc), pointer :: p1 => null()
Процедурные указатели
type NewType integer a real b contains procedure proc1 procedure :: proc2 => other_prend type NewType ...
call A.proc1(a,b)
Procedure описывает процедурный указатель, позволяет добавлять процедуры в созданный тип.
![Page 17: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/17.jpg)
Атрибуты pass и nopass
Используются для процедур привязанных к производному типу по имени.
pass позволяет получить доступ к переменной, посредством которой вызывалась процедура
(по умолчанию).
Вызывающая переменная записывается в процедуре, первым параметром и должна быть объявлена
оператором class.При вызове процедуры данный параметр опускается.
nopass отменяет доступ к вызывающей переменной.
![Page 18: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/18.jpg)
Процедуры привязанные к типу
module algebra type, public :: vector real x1, y1, x2, y2
contains procedure, public, pass :: length procedure, nopass :: info end type vector CONTAINS
subroutine info() write(*,*) "I'am VECTOR" end subroutine info
integer function length(vc) ! атрибут pass class(vector) vc length = sqrt((vc.x1-vc.x2)**2 + (vc.y1-vc.y2)**2) end function lengthend module algebra
![Page 19: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/19.jpg)
Процедуры привязанные к типу
program prog
use algebra
class (vector), allocatable :: VEC
allocate(VEC, source = vector(0.0,0.0,3.0,4.0))
call VEC.info()
write(*,*) VEC.length() ! формальный параметр отсутствует ! однако при описании объявлен
deallocate(VEC)
end
![Page 20: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/20.jpg)
type NewType...contains final :: finishend type NewType
Завершающие процедуры
Оператор final объявляет процедуры (деструкторы), которые выполняются при удалении
ранее размещенных в памяти элементов
![Page 21: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/21.jpg)
module MyModule... type NewType integer A real, private :: B integer C real, private :: D end type NewType...end module MyModule
Атрибут privateИспользуется для задания отдельных полей
производных типов в модулях. Доступ к приватной части происходит при помощи public-процедур.
![Page 22: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/22.jpg)
module MyModule
type NewType integer A real, private :: B contains procedure :: SetParamB end type NewType
contains subroutine SetParamB(T,newvalue) class(NewType) T real newvalue if (newvalue < 0) then write(*,*) "Error in parameter B, must be >=0" T.B = 0 else T.B = newvalue end if end subroutineend module
Атрибут private (Пример)
![Page 23: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/23.jpg)
program prog use MyModule class(NewType), allocatable :: nw allocate(nw) nw.A = 1000 !nw.B = 4.5 ! ошибка доступа call nw.SetParamB(4.5)
call nw.SetParamB(-9.4) ! некорректные данные
end
Атрибут private (Пример)
![Page 24: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/24.jpg)
Перегрузка операцийНабросок модуля арифметики длинных чисел.
module long
type LongNumbe integer(1) val(length) ! цифры integer total ! количествоend type LongNumber
contains subroutine asgn(n,val) ! присваивание ! операторы end subroutine asgn function plus(n1,n2) ! операция сложение и другие ! операторы end function plus subroutine PrintLong(n) ! вывод числа ! операторы end subroutine PrintLongend module long
![Page 25: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/25.jpg)
Набросок вызывающей программы
program prog use long type (LongNumber) a, b, c, d
call asgn(a,"2823892839283923837483485555555") call asgn(b,"92882746") call asgn(c,"2038493849300000")
!---- хотим найти выражение ! d = a*(b+c)+c*(a+b)+b d = plus(plus(umn(a,plus(b,c)),umn(c,plus(a,b))),b) ! очень громоздкая запись ! осложнение если будет много операций
call PrintLong(d)end
Перегрузка операций
![Page 26: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/26.jpg)
Перегрузка операций
Перегрузка операции присваивания
interface assignment (=) module procedure asgn ! имя процедуры end interface
Перегрузка операции сложения, умножения и др.
interface operator (+) module procedure plus ! имя процедуры end interface
Замена имени процедуры на знак операции.
![Page 27: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/27.jpg)
Перегрузка операций
Унарная операция - функция с одним входным параметром имеющего вид связи IN.
Двуместная операция - функция с двумя параметрами имеющими вид связи IN.
Нельзя изменять тип встроенной операции. (например '*' оформить как унарную).
Процедура, задающая '=' должна быть подпрограммой с двумя параметрами.
1-й вид связи OUT или INOUT (левая часть),2-й параметр IN (правая часть).
![Page 28: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/28.jpg)
Задаваемые операции
Вводятся аналогично унарным и двуместным операциям.
Имя операции задаётся по общим правилам.
В выражениях операция ограничивается точками.
interface operator (.PLUS.) module procedure plus end interface
...
SUMMA = A.PLUS.B
![Page 29: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/29.jpg)
Приоритет операций
унарная перегруженная или задаваемая операция
арифметические операции
символьная операция конкатенация
операции отношения
логические операции
задаваемая или перегруженная бинарная операция
![Page 30: Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ](https://reader035.vdocuments.site/reader035/viewer/2022062723/56813efd550346895da97f3d/html5/thumbnails/30.jpg)
Создать модуль для работы с длинными числами. Реализовать операции присваивания, сложения и
вывода длинных целых чисел.
* З а д а н и е *