Скачать презентацию
Идет загрузка презентации. Пожалуйста, подождите
Презентация была опубликована 11 лет назад пользователемwww.intuit.ru
1 Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ
2 Производные типы, зачем ? ! данные 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(!) операции присваивания.
3 Производные типы, зачем ? Лучше объединить типы под одним "общим типом. 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 поля
4 Оператор type Объявляет новый тип данных, группируя под одним именем существующие типы. type имя типы данных contains процедуры привязанные к типу end type имя
5 Операция ". " или " % ". Доступ к полям Задание начальных значений для каждого поля лучше с использованием конструктора. 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
6 Конструктор производного типа 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 конструктор Конструктор – функция с именем производного типа. Параметры функции - поля производного типа.
7 Иерархия типов type person character(128) fio integer age end type person type firm type (person) people(1000) character(128) name integer money end type firm type (firm) FM FM.money = ! доступ к полям FM.name = 'Siberia' FM.people(1).fio = 'Ivanov S.K.' FM.people(1).age = 35
8 type PARENT ! родитель integer A real B end type PARENT type, extends (PARENT) :: CHILD ! потомок character C end type CHILD type (CHILD) pas1, pas2 pas1 = CHILD(PARENT(1,2.0),'A') pas2 = CHILD(1,2.0,'A') Расширение типа, extends Тип CHILD наследует поля типа PARENT
9 Оператор class Class объявляет полиморфную переменную. Если полиморфная переменная не является формальным параметром процедуры, то используются атрибуты 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 имеет больше возможностей.
10 Полиморфная переменная объявленная родительским типом может "принимать" все дочерние типы. Оператор 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
11 Оператор class class (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
12 Конструкция select type Как определить какой тип имеет полиморфная переменная ? Select type позволяет выполнить блок операторов в зависимости от динамического типа полиморфной переменной. select type (переменная) type is (имя типа) class is (имя типа) class default end select
13 Оператор select type Схема выполнения Находится и выполняется блок type is Если не найден type is, то находится и выполняется class is. Если найдено соответствие нескольким блокам class is, то выбирается ближайший родитель. Если не найден ни один блок выбирается class default.
14 Оператор 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 PARENT CHILD_A CHILD_B CHILD_CHILD_A
15 Оператор 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 ! затем комплексный тип
16 procedure(proc), pointer :: p1 => null() Процедурные указатели type NewType integer a real b contains procedure proc1 procedure :: proc2 => other_pr end type NewType... call A.proc1(a,b) Procedure описывает процедурный указатель, позволяет добавлять процедуры в созданный тип.
17 Атрибуты pass и nopass Используются для процедур привязанных к производному типу по имени. pass позволяет получить доступ к переменной, посредством которой вызывалась процедура (по умолчанию). Вызывающая переменная записывается в процедуре, первым параметром и должна быть объявлена оператором class. При вызове процедуры данный параметр опускается. nopass отменяет доступ к вызывающей переменной.
18 Процедуры привязанные к типу 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 length end module algebra
19 Процедуры привязанные к типу 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
20 type NewType... contains final :: finish end type NewType Завершающие процедуры Оператор final объявляет процедуры (деструкторы), которые выполняются при удалении ранее размещенных в памяти элементов
21 module MyModule... type NewType integer A real, private :: B integer C real, private :: D end type NewType... end module MyModule Атрибут private Используется для задания отдельных полей производных типов в модулях. Доступ к приватной части происходит при помощи public - процедур.
=0" " title="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" " class="link_thumb"> 22 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 subroutine end module Атрибут private (Пример) =0" "> =0" T.B = 0 else T.B = newvalue end if end subroutine end module Атрибут private (Пример)"> =0" " title="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" ">
23 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 (Пример)
24 Перегрузка операций Набросок модуля арифметики длинных чисел. 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 PrintLong end module long
25 Набросок вызывающей программы program prog use long type (LongNumber) a, b, c, d call asgn(a," ") call asgn(b," ") call asgn(c," ") !---- хотим найти выражение ! 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 Перегрузка операций
26 Перегрузка операции присваивания interface assignment (=) module procedure asgn ! имя процедуры end interface Перегрузка операции сложения, умножения и др. interface operator (+) module procedure plus ! имя процедуры end interface Замена имени процедуры на знак операции.
27 Перегрузка операций Унарная операция - функция с одним входным параметром имеющего вид связи IN. Двуместная операция - функция с двумя параметрами имеющими вид связи IN. Нельзя изменять тип встроенной операции. (например ' * ' оформить как унарную). Процедура, задающая ' = ' должна быть подпрограммой с двумя параметрами. 1-й вид связи OUT или INOUT (левая часть), 2-й параметр IN (правая часть).
28 Задаваемые операции Вводятся аналогично унарным и двуместным операциям. Имя операции задаётся по общим правилам. В выражениях операция ограничивается точками. interface operator (.PLUS.) module procedure plus end interface... SUMMA = A.PLUS.B
29 Приоритет операций унарная перегруженная или задаваемая операция арифметические операции символьная операция конкатенация операции отношения логические операции задаваемая или перегруженная бинарная операция
30 Создать модуль для работы с длинными числами. Реализовать операции присваивания, сложения и вывода длинных целых чисел. * З а д а н и е *
Еще похожие презентации в нашем архиве:
© 2024 MyShared Inc.
All rights reserved.