Přeskočit na obsah

Dynamická alokace

alokace pomoci allocate

Při deklaraci polí jsme určovali velikost pole předem. Někdy ovšem velikost pole na začátku programu nevíme a dozvíme se jí až v průběhu. Dynamická alokace slouží k tomu, abychom mohli za běhu programu nadefinovat velikost polí.

Při deklaraci pole přidáme specifikace ,allocatable :: a místo abychom zadali mezi závorky velikost pole napíšeme (:).

Nyní máme pole označené jako alokovatelné, ale neexistující protože jsme mu neudali velikost. Alokovat, tj. přiřadit mu paměť, můžeme pomocí příkazu allocate(_jmenoPole_(_požadovanáVelikost_)).

S alokací jsme se již setkali při deklaraci pole ve funkci, kde jsme nezadali přesnou velikost pole. Ta se přiřadila automaticky podle velikosti pole na vstupu.

Další možností alokace je použít přepínač mold - allocate(pole, mold=pole2), který alokuje pole1 na stejný tvar, jako má pole2. Další zajímávý přepínač je source - allocate(pole, source=pole2), který alokuje pole na stejný tvar jako pole2 a navíc jej nastaví na stejné hodnoty, tj, zkopíruje pole2 do pole.

Pole můžeme pak dealokovat pomocí příkazu deallocate(_jmenoPole_).

Můžeme také testovat zda pole již bylo alokováno pomocí allocated(_jmenoPole_).

    program priklad_36
    implicit none
    
      integer :: i,j
      integer :: n, m
      integer, allocatable :: a(:,:), b(:)
      
      write(*,*) "Zadejte velikost matice m (sloupcu), n (radku): "
      read(*,*) m,n
      
      allocate(a(m,n), b(m))
      
      do i=1,n
        write(*,'(a,x,i3,a)') "Zadente",i,"-ty radek"
        read(*,*) a(:,i)
      enddo
        
      write(*,*) "Matice je zadána"
      do i=1,n
        write(*,'(8x)',advance='no') 
        do j=1,m
          write(*,'(i5,x)',advance='no') a(j,i)
        enddo
        write(*,*)
      enddo
      
      write(*,*) "------------------------------"
      
      write(*,'(a)',advance='no') "soucet: "
      do i=1,m
        b(i) = sum(a(i,:)) ! scitame sloupecky matice a
        write(*,'(i5,x)',advance='no') b(i)
      enddo
    
    end program
    				

Alokace pomocí konstruktoru pole

S fortranem 2008 přišlo drobné vylepšení. Pole můžeme alokovat jen tím, že použijeme konstruktor pole tj. [] nebo (//).

    program priklad_37
    implicit none
      
      integer :: i
      integer,allocatable :: a(:)
      integer :: b
     
      read(*,*) b
      a = [b] ! vlozime nactenou hodnotu b do a pomoci konstruktoru.
              ! tím pole a alokujeme na velikost 1
     
      do i=2,10
        read(*,*) b 
    
        a = [a, b] ! do pole a vložime pole a + skalarni promennou b tj. dostaneme pole o jeden
                   ! prvek vetsi
    
        write(*,*) size(a)
        write(*,*) a
        write(*,*) "----------------------------"
      enddo
     
    end program