Fortran - tablice

Tablice mogą przechowywać sekwencyjną kolekcję elementów tego samego typu o stałym rozmiarze. Tablica jest używana do przechowywania kolekcji danych, ale często bardziej przydatne jest myślenie o tablicy jako o zbiorze zmiennych tego samego typu.

Wszystkie tablice składają się z ciągłych lokalizacji pamięci. Najniższy adres odpowiada pierwszemu elementowi, a najwyższy adres ostatniemu elementowi.

Liczby (1) Liczby (2) Liczby (3) Liczby (4)

Tablice mogą być jednowymiarowe (jak wektory), dwuwymiarowe (jak macierze), a Fortran umożliwia tworzenie do 7-wymiarowych tablic.

Deklarowanie tablic

Tablice są deklarowane z rozszerzeniem dimension atrybut.

Na przykład, aby zadeklarować jednowymiarową tablicę o nazwie liczba, składającą się z liczb rzeczywistych zawierającej 5 elementów, piszesz:

real, dimension(5) :: numbers

Odwołania do poszczególnych elementów tablic są określane przez określenie ich indeksów. Pierwszy element tablicy ma indeks równy jeden. Tablica liczb zawiera pięć zmiennych rzeczywistych - liczby (1), liczby (2), liczby (3), liczby (4) i liczby (5).

Aby utworzyć dwuwymiarową tablicę liczb całkowitych 5 x 5 o nazwie macierz, piszesz -

integer, dimension (5,5) :: matrix

Możesz również zadeklarować tablicę z wyraźną dolną granicą, na przykład -

real, dimension(2:6) :: numbers
integer, dimension (-3:2,0:4) :: matrix

Przypisywanie wartości

Możesz przypisać wartości poszczególnym członkom, na przykład

numbers(1) = 2.0

lub możesz użyć pętli,

do i  =1,5
   numbers(i) = i * 2.0
end do

Jednowymiarowym elementom tablicy można bezpośrednio przypisywać wartości za pomocą symbolu krótkiej ręki, zwanego konstruktorem tablicy, na przykład

numbers = (/1.5, 3.2,4.5,0.9,7.2 /)

please note that there are no spaces allowed between the brackets ‘( ‘and the back slash ‘/’

Przykład

Poniższy przykład ilustruje koncepcje omówione powyżej.

program arrayProg

   real :: numbers(5) !one dimensional integer array
   integer :: matrix(3,3), i , j !two dimensional real array
   
   !assigning some values to the array numbers
   do i=1,5
      numbers(i) = i * 2.0
   end do
   
   !display the values
   do i = 1, 5
      Print *, numbers(i)
   end do
   
   !assigning some values to the array matrix
   do i=1,3
      do j = 1, 3
         matrix(i, j) = i+j
      end do
   end do
   
   !display the values
   do i=1,3
      do j = 1, 3
         Print *, matrix(i,j)
      end do
   end do
   
   !short hand assignment
   numbers = (/1.5, 3.2,4.5,0.9,7.2 /)
   
   !display the values
   do i = 1, 5
      Print *, numbers(i)
   end do
   
end program arrayProg

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

2.00000000    
 4.00000000    
 6.00000000    
 8.00000000    
 10.0000000    
         2
         3
         4
         3
         4
         5
         4
         5
         6
 1.50000000    
 3.20000005    
 4.50000000    
0.899999976    
 7.19999981

Niektóre terminy związane z tablicą

Poniższa tabela zawiera niektóre terminy związane z tablicami -

Semestr Znaczenie
Ranga Jest to liczba wymiarów tablicy. Na przykład, dla tablicy o nazwie matrix, rank to 2, a dla tablicy o nazwie numbers, rank to 1.
Stopień Jest to liczba elementów w wymiarze. Na przykład numery tablic mają zasięg 5, a tablica o nazwie macierz ma zasięg 3 w obu wymiarach.
Kształt Kształt tablicy to jednowymiarowa tablica liczb całkowitych, zawierająca liczbę elementów (zakres) w każdym wymiarze. Na przykład dla macierzy tablicy kształt to (3, 3), a numery tablicy to (5).
Rozmiar Jest to liczba elementów, które zawiera tablica. Dla macierzy tablic jest to 9, a dla numerów tablic jest to 5.

Przekazywanie tablic do procedur

Możesz przekazać tablicę do procedury jako argument. Poniższy przykład ilustruje koncepcję -

program arrayToProcedure      
implicit none      

   integer, dimension (5) :: myArray  
   integer :: i
   
   call fillArray (myArray)      
   call printArray(myArray)
   
end program arrayToProcedure


subroutine fillArray (a)      
implicit none      

   integer, dimension (5), intent (out) :: a
   
   ! local variables     
   integer :: i     
   do i = 1, 5         
      a(i) = i      
   end do  
   
end subroutine fillArray 


subroutine printArray(a)

   integer, dimension (5) :: a  
   integer::i
   
   do i = 1, 5
      Print *, a(i)
   end do
   
end subroutine printArray

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

1
2
3
4
5

W powyższym przykładzie podprogram fillArray i printArray można wywołać tylko z tablicami o wymiarze 5. Jednakże, aby napisać podprogramy, które mogą być użyte dla tablic o dowolnym rozmiarze, można je przepisać przy użyciu następującej techniki -

program arrayToProcedure      
implicit  none    

   integer, dimension (10) :: myArray  
   integer :: i
   
   interface 
      subroutine fillArray (a)
         integer, dimension(:), intent (out) :: a 
         integer :: i         
      end subroutine fillArray      

      subroutine printArray (a)
         integer, dimension(:) :: a 
         integer :: i         
      end subroutine printArray   
   end interface 
   
   call fillArray (myArray)      
   call printArray(myArray)
   
end program arrayToProcedure


subroutine fillArray (a)      
implicit none      
   integer,dimension (:), intent (out) :: a      
   
   ! local variables     
   integer :: i, arraySize  
   arraySize = size(a)
   
   do i = 1, arraySize         
      a(i) = i      
   end do  
   
end subroutine fillArray 


subroutine printArray(a)
implicit none

   integer,dimension (:) :: a  
   integer::i, arraySize
   arraySize = size(a)
   
   do i = 1, arraySize
     Print *, a(i)
   end do
   
end subroutine printArray

Należy pamiętać, że program używa rozszerzenia size funkcja, aby uzyskać rozmiar tablicy.

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

1
2
3
4
5
6
7
8
9
10

Sekcje tablicy

Jak dotąd odnosiliśmy się do całej tablicy, Fortran zapewnia łatwy sposób na odwołanie się do kilku elementów lub sekcji tablicy za pomocą pojedynczej instrukcji.

Aby uzyskać dostęp do sekcji tablicy, musisz podać dolną i górną granicę sekcji, a także krok (przyrost) dla wszystkich wymiarów. Ten zapis nazywa się asubscript triplet:

array ([lower]:[upper][:stride], ...)

Gdy nie są wymienione dolne i górne granice, domyślnie jest to zadeklarowany zakres, a domyślna wartość kroku to 1.

Poniższy przykład ilustruje koncepcję -

program arraySubsection

   real, dimension(10) :: a, b
   integer:: i, asize, bsize
   
   a(1:7) = 5.0 ! a(1) to a(7) assigned 5.0
   a(8:) = 0.0  ! rest are 0.0 
   b(2:10:2) = 3.9
   b(1:9:2) = 2.5
   
   !display
   asize = size(a)
   bsize = size(b)
   
   do i = 1, asize
      Print *, a(i)
   end do
   
   do i = 1, bsize
      Print *, b(i)
   end do
   
end program arraySubsection

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

5.00000000    
5.00000000    
5.00000000    
5.00000000    
5.00000000    
5.00000000    
5.00000000    
0.00000000E+00
0.00000000E+00
0.00000000E+00
2.50000000    
3.90000010    
2.50000000    
3.90000010    
2.50000000    
3.90000010    
2.50000000    
3.90000010    
2.50000000    
3.90000010

Funkcje wewnętrzne tablicy

Fortran 90/95 zapewnia kilka wewnętrznych procedur. Można je podzielić na 7 kategorii.

  • Mnożenie wektora i macierzy

  • Reduction

  • Inquiry

  • Construction

  • Reshape

  • Manipulation

  • Location