Учебники

Фортран — Массивы

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

Все массивы состоят из смежных областей памяти. Самый низкий адрес соответствует первому элементу, а самый высокий адрес — последнему.

Числа (1) Числа (2) Числа (3) Числа (4)

Массивы могут быть одномерными (как векторы), двумерными (как матрицы) и Fortran позволяет создавать до 7-мерных массивов.

Объявление массивов

Массивы объявляются с атрибутом измерения .

Например, чтобы объявить одномерный массив с именем number из действительных чисел, содержащий 5 элементов, вы пишете:

real, dimension(5) :: numbers

На отдельные элементы массивов ссылаются путем указания их индексов. Первый элемент массива имеет нижний индекс один. Числа массива содержат пять действительных переменных — числа (1), числа (2), числа (3), числа (4) и числа (5).

Чтобы создать двумерный массив целых чисел 5 x 5 с именем matrix, вы пишете:

integer, dimension (5,5) :: matrix  

Вы также можете объявить массив с некоторой явной нижней границей, например —

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

Присвоение значений

Вы можете назначить значения отдельным членам, например,

numbers(1) = 2.0

или вы можете использовать цикл,

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

Одномерным элементам массива могут быть непосредственно присвоены значения с использованием сокращенного символа, называемого конструктором массива, например,

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

обратите внимание, что между скобками не должно быть пробелов ‘(‘ и обратной косой черты ‘/’

пример

Следующий пример демонстрирует концепции, обсужденные выше.

Live Demo

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

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

 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    

Некоторые термины, связанные с массивом

В следующей таблице приведены некоторые термины, связанные с массивом:

Срок Имея в виду
Ранг Это количество измерений в массиве. Например, для массива с именем matrix ранг равен 2, а для массива с именем numbers ранг равен 1.
степень Это количество элементов в измерении. Например, номера массивов имеют экстент 5, а массив с именем matrix имеет экстент 3 в обоих измерениях.
форма Форма массива представляет собой одномерный целочисленный массив, содержащий количество элементов (экстент) в каждом измерении. Например, для матрицы массива shape равен (3, 3), а для номеров массива — (5).
Размер Это количество элементов в массиве. Для матрицы массива это 9, а для номеров массива это 5.

Передача массивов в процедуры

Вы можете передать массив процедуре в качестве аргумента. Следующий пример демонстрирует концепцию —

Live Demo

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

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

1
2
3
4
5

В приведенном выше примере подпрограммы fillArray и printArray могут вызываться только для массивов с измерением 5. Однако для записи подпрограмм, которые можно использовать для массивов любого размера, вы можете переписать их, используя следующую технику:

Live Demo

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

Обратите внимание, что программа использует функцию размера, чтобы получить размер массива.

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

1
2
3
4
5
6
7
8
9
10

Разделы массива

Пока мы ссылались на весь массив, Fortran предоставляет простой способ ссылаться на несколько элементов или часть массива, используя один оператор.

Чтобы получить доступ к разделу массива, вам необходимо указать нижнюю и верхнюю границу раздела, а также шаг (приращение) для всех измерений. Эта нотация называется индексом триплета:

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

Когда не упоминаются нижняя и верхняя границы, по умолчанию используются объявленные вами экстенты, а для значения шага по умолчанию используется значение 1.

Следующий пример демонстрирует концепцию —

Live Demo

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

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

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 

Встроенные функции массива

Fortran 90/95 предоставляет несколько внутренних процедур. Их можно разделить на 7 категорий.

Векторное и матричное умножение

снижение

запрос

строительство

Переформуйте

манипуляция

Место нахождения