J
ęzyki
P
rogramowania i
S
ystemy
O
peracyjne
2
–– I N Ż Y N I E R I A W I R T U A L N A P R O J E K T O W A N I A ––
Lab. 1: Fortran 95 - dynamiczna alokacja pamięci
1. Wprowadzenie
Obliczenia numeryczne najczęściej prowadzone są na danych dostarczanych przez użytkownika (np.
odczytywanych z pliku). Często nie można określić na etapie programowania, jaki będzie rozmiar tych
danych, a zatem jaki obszar pamięci komputera należy zarezerwować. Programiści piszący w
FORTRANIE 77 zmuszeni byli do (statycznego) rezerwowania pamięci dla maksymalnego przewidzia-
nego rozmiaru deklarowanych danych.
W Fortranie 90 udostępniono możliwość dynamicznej alokacji pamięci dla tablic. Celem laboratorium
jest zapoznanie się ze sposobami tworzenia i wykorzystywania takich zmiennych, a także przekazywania
ich pomiędzy podprogramami (procedurami, modułami).
2. Podstawy teoretyczne
1. Deklaracja tablicy – parametr allocatable, polecenia allocate i deallocate, funkcja allocated
Zmienną alokowaną dynamicznie deklarujemy w sposób przedstawiony poniżej:
integer, allocatable, dimension (:)
:: tablica1
! (:) oznacza tablicę jednowymiarową (wektor)
real*8, allocatable, dimension (:,:)
:: tablica2
! (:,:) oznacza tablicę dwuwymiarową
Tak zadeklarowanej tablicy można przydzielić odpowiednią ilość pamięci, np.:
allocate(tablica1(7))
! Tablica o elementach 1..7
allocate(tablica2(20))
! Tablica o elementach 1..20
allocate(tablica3(5,0:3))
! Elementy 1..5 w 1. kierunku i 0..3 w drugim
Od tego momentu można przydzielać wartości poszczególnym elementom tej tablicy, a także
wykonywać operacje na całej tablicy. Kiedy zmienna nie jest już potrzebna, można zwolnić
przydzieloną jej pamięć:
deallocate(tablica1)
Jeżeli nie wiemy, czy dla danej zmiennej została przydzielona pamięć, można to sprawdzić stosując
funkcję allocated:
if (allocated(tablica1)) deallocate(tablica1)
2. Nadawanie wartości elementom tablicy
•
poszczególne elementy tablicy (dostępne w Fortranie 77), np.:
do i=1,7
tablica1(i)=i**2+2*i
enddo
© Witold Stankiewicz, 2011
1/4
J
ęzyki
P
rogramowania i
S
ystemy
O
peracyjne
2
–– I N Ż Y N I E R I A W I R T U A L N A P R O J E K T O W A N I A ––
•
z użyciem tzw. konstruktora tablicy, np.:
tablica1=(/ 1,2,3,4,1,-1,-7 /)
•
przypisanie wartości wszystkim elementom (całej tablicy), np.
tablica1_kopia=tablica1
tablica1=tablica2(1:7)
•
z zastosowaniem maski (instrukcja where), np.:
where (tablica1.ge.0)
! Skopiowanie wartości nieujemnych
tablica1_kopia=tablica1
else where
! Dla elementów ujemnych wypełnienie 0
tablica1_kopia=0
end where
•
jeżeli kształt dwóch tablic różni się, można zastosować polecenie reshape:
tablica2=
reshape
(tablica3,(/ 20,1 /))
tablica3=
reshape
(tablica2,(/ 5,0:3 /))
3.
Przekazywanie tablic do podprogramów
•
Jeżeli zewnętrzna procedura (nie należąca do bloku głównego) nie zostanie opisana w bloku, z
którego jest wywoływana (z użyciem łącznika interface), jej wywołanie spowoduje błąd na etapie
działania programu (kompilacja nie wyświetli błędów). Przykład użycia interface podano w (3.2)
•
3. Przykłady
1. Dynamiczna alokacja tablic i przypisywanie wartości tablicom
program test_tablic
implicit none
integer, allocatable, dimension (:) :: x
integer, allocatable, dimension(:,:) :: b
integer, dimension(6) :: y = (/ 2,4,6,8,10,12 /)
integer :: i,n
n=8
allocate(b(4,2)
write(*,*) 'Przed alokacja :', x
allocate (x(n))
write(*,*) 'Po alokacji :', x
do i=1,n
x(i)=i
enddo
write(*,*) 'Po wypelnieniu :', x
where (x.le.3)
© Witold Stankiewicz, 2011
2/4
J
ęzyki
P
rogramowania i
S
ystemy
O
peracyjne
2
–– I N Ż Y N I E R I A W I R T U A L N A P R O J E K T O W A N I A ––
x=-10*x
else where (x.ge.7)
x=5*x
end where
write(*,*) 'Po instrukcji where :', x
b=reshape(x,(/4,2 /))
write(*,*) '1. wiersz po reshape:', b(:,1)
write(*,*) '2. wiersz po reshape:', b(:,2)
write(*,*) 'Pisanie co 2.elem. :', x(1:n:2)
if (allocated(x)) deallocate(x)
if (allocated(b)) deallocate(b)
return
end
2. Użycie łącznika interface
subroutine srednia(x,y,z)
implicit none
real*8, allocatable, dimension(:)
:: x,y,z
if (.not.
allocated
(z)) allocate(z(size(x)))
z=(x+y)/2
end subroutine srednia
program test
implicit none
real*8, allocatable, dimension(:)
:: x,y,z
interface
subroutine srednia(x,y,z)
implicit none
real*8, allocatable, dimension(:)
:: x,y,z
end subroutine srednia
end interface
allocate(x(4))
x=(/ 1,2,3,4 /)
allocate(y(4))
y=(/ 2,4,6,8 /)
call srednia(x,y,z)
write(*,*) z
return
end
3.
4. Zadanie
Przetestować podane przykłady. Napisać podany przez prowadzącego program wykorzystujący
dynamiczną alokację pamięci
5. Literatura
1) Clive Page. Fortran90 for Fortran77 Programmers.
http://www.star.le.ac.uk/~cgp/f90course/f90.html
© Witold Stankiewicz, 2011
3/4
J
ęzyki
P
rogramowania i
S
ystemy
O
peracyjne
2
–– I N Ż Y N I E R I A W I R T U A L N A P R O J E K T O W A N I A ––
2) Dariusz Chrobak. Fortran praktyka programowania. MIKOM PWN, 2003. ISBN 83-7279-361-1
3) Janusz R. Piechna. Programowanie w języku Fortran 90 i 95. Oficyna Wydawnicza Politechniki
Warszawskiej, 2000. ISBN 83-7207-225-6
4) Dokumentacja na serwerze dydaktycznym
http://stanton.ice.put.poznan.pl/student/
© Witold Stankiewicz, 2011
4/4