background image

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

background image

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

background image

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

background image

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