Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
современный фортран , Бортеньев.pdf
Скачиваний:
242
Добавлен:
26.03.2015
Размер:
2.34 Mб
Скачать

О. В. Бартеньев. Современный ФОРТРАН

exit end if

current => tree%next tree => current

end do

end subroutine insel

 

subroutine chava(ind)

! Изменим теперь значение поля элементов

integer ind

! списка с index = ind и index = ind - 1

do while(associated(tree))

 

if(tree%index == ind) then

! Поле val элемента списка с index = ind

tree%val = 500

tree%next%val = 400

! Поле val элемента списка с index = ind - 1

exit

 

end if

 

current => tree%next

 

tree => current

 

end do

 

end subroutine chava

 

end program one_d_li

 

Замечания:

1.В общем случае элементы списка располагаются в свободной памяти ЭВМ произвольным образом. Поэтому подобные списки иногда называют разреженными векторами.

2.Используя ссылки в качестве компонентов производного типа, можно сформировать циклические, двунаправленные списки и более сложные структуры данных.

3.11.6. Ссылки как параметры процедур

Ссылка может быть формальным параметром процедуры. В этом случае фактический параметр также должен быть ссылкой. Ранги фактического и формального параметров-ссылок должны совпадать. При вызове процедуры состояние привязки фактического параметра передается формальному, и, наоборот, при завершении работы процедуры состояние привязки формального параметра передается фактическому. Однако при выходе адресат может стать неопределенным, если, например, в процессе работы процедуры ссылка была прикреплена к локальной переменной, не имеющей атрибут SAVE.

В случае модульной или внутренней процедуры компилятор знает, является ли формальный параметр ссылкой или нет. В случае внешней процедуры компилятору необходимо явно указать, что формальный параметр является ссылкой. Это достигается за счет задания явного интерфейса. Для формального параметра-ссылки недопустимо задание атрибута INTENT, устанавливающего вид связи параметра.

104

риложение3. Организация данных

Пример:

real, pointer, dimension(:) :: a, a2

 

 

interface

 

 

 

subroutine pab(b, b2)

 

 

 

real, pointer :: b(:), b2(:)

 

 

 

end

 

 

 

end interface

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

call pab(a, a2)

! формального параметра передается фактическому

print '(10f5.1)', a

! 1.0

2.03.0 4.05.0

print '(10f5.1)', a2

! .0

.0.0

.0.0

print *, associated(a), associated(a2) ! T T

 

 

end

 

 

 

subroutine pab(b, b2)

 

 

 

real, pointer, dimension(:) :: b, b2

 

 

integer k

 

 

 

real, target, save :: c(5)

 

 

 

real, target, automatic :: c2(5)

 

 

 

c = (/ (1.0*k, k = 1, 5) /)

 

 

 

c2 = (/ (1.0*k, k = 1, 5) /)

! После выхода из-за отсутствия у c2 атрибута

b => c

b2 => c2

! SAVE адресат ссылки a2 будет неопределен

end subroutine pab

 

 

 

Если фактическому параметру-ссылке соответствует формальный параметр, не являющийся ссылкой, то ссылка-параметр должна быть прикреплена к адресату, который и будет ассоциирован с формальным параметром.

Пример:

integer, pointer :: a(:)

 

 

 

 

 

 

integer, target :: c(5) = 2

! Адресат c фактического параметра-ссылки a

a => c

call pab(a, size(a))

! ассоциируется с не являющимся ссылкой

 

! формальным параметром b подпрограммы pab

print *, a

!

7

7

7

7

7

print *, c

!

7

7

7

7

7

end

 

 

 

 

 

 

subroutine pab(b, n) integer n, b(n)

b = b + 5

end subroutine pab

3.11.7. Параметры с атрибутом TARGET

Фактический

параметр процедуры может иметь атрибут TARGET.

В этом случае

ссылки, прикрепленные к такому параметру, не

прикрепляются к соответствующему формальному параметру, а остаются

105

О. В. Бартеньев. Современный ФОРТРАН

связанными с фактическим параметром. Если же формальный параметр имеет атрибут TARGET, то любая прикрепленная к нему ссылка (если только она явно не откреплена от адресата) остается неопределенной при выходе из процедуры. К процедуре, формальный параметр которой имеет атрибут TARGET, должен быть организован явный интерфейс. Таким интерфейсом обладают внутренние и модульные процедуры, обретают его и внешние процедуры после их описания в интерфейсном блоке, расположенном в вызывающей программной единице (разд. 8.11.3).

3.11.8. Ссылки как результат функции

Функция может иметь атрибут POINTER. В этом случае результатом функции является ссылка и к ней можно прикрепить другую ссылку. Такое использование функции целесообразно, если, например, размер результата зависит от вычислений в самой функции.

При входе в функцию вначале ссылка-результат не определена. Внутри функции она должна быть прикреплена к адресату или определена посредством оператора NULLIFY как открепленная.

Обращение к функции-ссылке можно выполнить из выражения. В этом случае адресат ссылки-результата должен быть определен и его значение будет использовано при вычислении выражения. Также функция-ссылка может быть ссылочным компонентом конструктора структуры.

Тема "ссылки" тесно связана с темой "массивы", поэтому дальнейшее рассмотрение ссылок мы отложим до следующей главы.

Пример. Получить массив a из неотрицательных чисел массива c.

integer, pointer :: a(:)

 

 

 

 

 

 

integer :: c(10) = (/ 1, -2, 2, -2, 3, -2, 4, -2, 5, -2 /)

 

 

 

a => emi(c)

! Прикрепляем ссылку к результату функции

print *, a

!

1

2

3

4

5

! Использование функции-ссылки в выражении

 

 

 

print *, 2 * emi(c)

!

2

4

6

8

10

contains

! Внутренняя процедура обладает

function emi(c)

! явно заданным интерфейсом

integer, pointer :: emi(:)

! Результатом функции является ссылка

integer c(:), i, k

! c - перенимающий форму массив

k = count(c >= 0)

! k - число неотрицательных элементов

allocate(emi(k))

! Прикрепляем ссылку к адресату

emi = pack(c, mask = c >= 0) ! Заносим в ссылку неотрицательные

end function emi

! элементы массива c

 

 

end

 

 

 

 

 

 

Замечания:

1. Если функцию emi оформить как внешнюю, то в вызывающей программе потребуется блок с интерфейсом к этой функции, поскольку, во-первых, она

106

риложение3. Организация данных

возвращает ссылку, а, во-вторых, ее формальным параметром является перенимающий форму массив.

2. Встроенные функции COUNT и PACK приведены в разд. 4.12.1

и 4.12.4.2.

107