30
Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ

Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ

  • Upload
    tobias

  • View
    61

  • Download
    2

Embed Size (px)

DESCRIPTION

Лекция 9 ПРОИЗВОДНЫЕ ТИПЫ. Производные типы, зачем ?. При сортировке используются перестановки элементов. Перестановка требует 3 операции присваивания . tmp = x(12) x(12) = x(15) x(15) = tmp Для перестановки двух частиц потребуется записать 21 (!) операции присваивания. - PowerPoint PPT Presentation

Citation preview

Page 1: Лекция  9 ПРОИЗВОДНЫЕ  ТИПЫ

Лекция 9

ПРОИЗВОДНЫЕ

ТИПЫ

Page 2: Лекция  9 ПРОИЗВОДНЫЕ  ТИПЫ

Производные типы, зачем ?

! данные 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 ПРОИЗВОДНЫЕ  ТИПЫ

Производные типы, зачем ?Лучше объединить типы под одним "общим типом“.

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 ПРОИЗВОДНЫЕ  ТИПЫ

Оператор type

Объявляет новый тип данных,группируя под одним именем существующие типы.

type имя

типы данных

contains

процедуры привязанные к типу

end type имя

Page 5: Лекция  9 ПРОИЗВОДНЫЕ  ТИПЫ

Операция " . " или " % ".

Доступ к полям

Задание начальных значений для каждого поля лучше с использованием конструктора.

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 ПРОИЗВОДНЫЕ  ТИПЫ

Конструктор производного типа

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 ПРОИЗВОДНЫЕ  ТИПЫ

Иерархия типов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 ПРОИЗВОДНЫЕ  ТИПЫ

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 ПРОИЗВОДНЫЕ  ТИПЫ

Оператор 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 ПРОИЗВОДНЫЕ  ТИПЫ

Полиморфная переменная объявленная родительским типом может "принимать" все дочерние типы.

Оператор 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 ПРОИЗВОДНЫЕ  ТИПЫ

Оператор 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 ПРОИЗВОДНЫЕ  ТИПЫ

Конструкция select typeКак определить какой тип имеет

полиморфная переменная ?

Select type позволяет выполнить блок операторов в зависимости от динамического типа полиморфной

переменной.

select type (переменная)

type is (имя типа)

class is (имя типа)

class default

end select

Page 13: Лекция  9 ПРОИЗВОДНЫЕ  ТИПЫ

Оператор select type

Схема выполнения

Находится и выполняется блок type is

Если не найден type is, то находится и выполняется class is.

Если найдено соответствие нескольким блокам class is, то выбирается ближайший родитель.

Если не найден ни один блок выбирается class default.

Page 14: Лекция  9 ПРОИЗВОДНЫЕ  ТИПЫ

Оператор 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 ПРОИЗВОДНЫЕ  ТИПЫ

Оператор 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 ПРОИЗВОДНЫЕ  ТИПЫ

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 ПРОИЗВОДНЫЕ  ТИПЫ

Атрибуты pass и nopass

Используются для процедур привязанных к производному типу по имени.

pass позволяет получить доступ к переменной, посредством которой вызывалась процедура

(по умолчанию).

Вызывающая переменная записывается в процедуре, первым параметром и должна быть объявлена

оператором class.При вызове процедуры данный параметр опускается.

nopass отменяет доступ к вызывающей переменной.

Page 18: Лекция  9 ПРОИЗВОДНЫЕ  ТИПЫ

Процедуры привязанные к типу

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 ПРОИЗВОДНЫЕ  ТИПЫ

Процедуры привязанные к типу

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 ПРОИЗВОДНЫЕ  ТИПЫ

type NewType...contains final :: finishend type NewType

Завершающие процедуры

Оператор final объявляет процедуры (деструкторы), которые выполняются при удалении

ранее размещенных в памяти элементов

Page 21: Лекция  9 ПРОИЗВОДНЫЕ  ТИПЫ

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 ПРОИЗВОДНЫЕ  ТИПЫ

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 ПРОИЗВОДНЫЕ  ТИПЫ

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 ПРОИЗВОДНЫЕ  ТИПЫ

Перегрузка операцийНабросок модуля арифметики длинных чисел.

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 ПРОИЗВОДНЫЕ  ТИПЫ

Набросок вызывающей программы

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 ПРОИЗВОДНЫЕ  ТИПЫ

Перегрузка операций

Перегрузка операции присваивания

interface assignment (=) module procedure asgn ! имя процедуры end interface

Перегрузка операции сложения, умножения и др.

interface operator (+) module procedure plus ! имя процедуры end interface

Замена имени процедуры на знак операции.

Page 27: Лекция  9 ПРОИЗВОДНЫЕ  ТИПЫ

Перегрузка операций

Унарная операция - функция с одним входным параметром имеющего вид связи IN.

Двуместная операция - функция с двумя параметрами имеющими вид связи IN.

Нельзя изменять тип встроенной операции. (например '*' оформить как унарную).

Процедура, задающая '=' должна быть подпрограммой с двумя параметрами.

1-й вид связи OUT или INOUT (левая часть),2-й параметр IN (правая часть).

Page 28: Лекция  9 ПРОИЗВОДНЫЕ  ТИПЫ

Задаваемые операции

Вводятся аналогично унарным и двуместным операциям.

Имя операции задаётся по общим правилам.

В выражениях операция ограничивается точками.

interface operator (.PLUS.) module procedure plus end interface

...

SUMMA = A.PLUS.B

Page 29: Лекция  9 ПРОИЗВОДНЫЕ  ТИПЫ

Приоритет операций

унарная перегруженная или задаваемая операция

арифметические операции

символьная операция конкатенация

операции отношения

логические операции

задаваемая или перегруженная бинарная операция

Page 30: Лекция  9 ПРОИЗВОДНЫЕ  ТИПЫ

Создать модуль для работы с длинными числами. Реализовать операции присваивания, сложения и

вывода длинных целых чисел.

* З а д а н и е *