Презентацию к лекции Вы можете скачать здесь.
! данные 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(!) операции присваивания.
Лучше объединить типы под одним "общим типом".
Объявляет новый тип данных, группируя под одним именем существующие типы.
type имя
типы данных
contains
процедуры привязанные к типу
end type имя
Операция " . " или " % ".
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
Задание начальных значений для каждого поля лучше с использованием конструктора.
Конструктор – функция с именем производного типа.
Параметры функции - поля производного типа.
Тип CHILD наследует поля типа PARENT
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')
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 имеет больше возможностей.
Полиморфная переменная объявленная родительским типом может "принимать" все дочерние типы.
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
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
Как определить какой тип имеет полиморфная переменная ?
Select type позволяет выполнить блок операторов в зависимости от динамического типа полиморфной переменной.
select type (переменная)
type is (имя типа)
class is (имя типа)
class default
end select
Схема выполнения
type istype is, то находится и выполняется class is.class is, то выбирается ближайший родитель.class default.
...
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
Неограниченно полиморфная переменная принимает любые типы
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 ! затем комплексный тип
procedure(proc), pointer :: p1 => null()
Procedure описывает процедурный указатель, позволяет добавлять в созданный тип процедуры.
type NewType
integer a
real b
contains
procedure proc1
procedure :: proc2 => other_pr
end type NewType
...
call A.proc1(a,b)
Используются для процедур привязанных к производному типу по имени.
pass позволяет получить доступ к переменной, посредством которой вызывалась процедура (по умолчанию).
Вызывающая переменная записывается в процедуре, первым параметром и должна быть объявлена оператором class.
При вызове процедуры данный параметр опускается.
nopass отменяет доступ к вызывающей переменной.
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), intent(out) :: vc
length = sqrt((vc.x1-vc.x2)**2 + (vc.y1-vc.y2)**2)
end function length
end module algebra
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
Оператор final объявляет процедуры (деструкторы), которые выполняются при удалении ранее размещенных в памяти элементов
type NewType
...
contains
final :: finish
end type NewType
Используется для задания отдельных полей производных типов в модулях. Доступ к приватной части происходит при помощи public-процедур.
module MyModule
...
type NewType
integer A
real, private :: B
integer C
real, private :: D
end type NewType
...
end module MyModule
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
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
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
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
interface assignment (=)
module procedure asgn ! имя процедуры
end interface
interface operator (+)
module procedure plus ! имя процедуры
end interface
Замена имени процедуры на знак операции.
Унарная операция - функция с одним входным параметром имеющего вид связи IN.
Двуместная операция - функция с двумя параметрами имеющими вид связи IN.
Нельзя изменять тип встроенной операции. (например '*' оформить как унарную).
Процедура, задающая '=' должна быть подпрограммой с двумя параметрами.
OUT или INOUT (левая часть),IN (правая часть).Вводятся аналогично унарным и двуместным операциям.
Имя операции задаётся по общим правилам.
В выражениях операция ограничивается точками.
interface operator (.PLUS.)
module procedure plus
end interface
...
SUMMA = A.PLUS.B
Создать модуль для работы с длинными числами. Реализовать операции присваивания, сложения и вывода длинных целых чисел.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.