Массивы и строки#
Чаще всего нам нужно хранить и использовать длинные списки чисел, а не отдельные скалярные переменные, которые мы использовали ранее; в языках программирования такие списки называют arrays (массивы).
Массивы – многомерные переменные, содержащие более одного значения, при этом доступ к каждому значению осуществляется с помощью одного или нескольких индексов.
Массивы в Fortran используют нумерацию с отчётом от 1 по умолчанию; это означает, что первый элемент вдоль любого измерения будет иметь индекс 1.
Объявление массива#
Мы можем объявить массивы любого типа. Существуют два распространённых способа (нотации) для объявления массива: использование атрибута dimension
или указание размерности массива в круглых скобках после имени переменной обозначающей массив.
Пример: объявление статического массива
program arrays
implicit none
! 1D integer array
integer, dimension(10) :: array1
! An equivalent array declaration
integer :: array2(10)
! 2D real array
real, dimension(10, 10) :: array3
! Custom lower and upper index bounds
real :: array4(0:9)
real :: array5(-5:5)
end program arrays
Срез массива#
Мощной особенностью языка Fortran является встроенная поддержка операций над массивами; мы можем выполнять операции над всем массивом или его частью, используя операцию получения среза slicing, указав в скобках после имени массива диапазон индексов, и, если необходимо, шаг, разделив начальный, конечный индексы и шаг двоеточием (:
):
Пример: срез массива
program array_slice
implicit none
integer :: i
integer :: array1(10) ! 1D integer array of 10 elements
integer :: array2(10, 10) ! 2D integer array of 100 elements
array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ! Array constructor
print *, "Array at odd indices"
print *, array1(1:10:2) ! Print out elements at odd indices, start at element 1, go up to element 10, in strides of 2
print *, "Array in reverse!"
print *, array1(10:1:-1) ! Print an array in reverse
array1(:) = 0 ! Set all elements to zero
print *, "Reset array to 0!"
print *, array1
array1 = [(i, i = 1, 10)] ! Implied do loop constructor
print *, "Now back to 1 to 10!"
print *, array1
array1(1:5) = 1 ! Set first five elements to one
print *, "Set first five elements to 1"
print *, array1
array1(6:) = 2 ! Set all elements after five to two
print *, "Set all elements after 5 to 2"
print *, array1
print *, "First column of 2d array"
print *, array2(:,1) ! Print out the first column in a 2D array
end program array_slice
Массивы в Fortran хранятся в памяти по столбцам; первый индекс меняется быстрее.
Выделяемые (динамические) массивы#
До сих пор мы указывали размер массива в коде программы — такой массив называется статическим массивом, так как его размер фиксирован при компиляции нашей программы.
Достаточно часто нам неизвестно какого размера должен быть массив, до запуска программы, например, если мы читаем данные из файла неизвестного размера.
Для решения этой проблемы нам нужны выделяемые
(динамические) массивы. Память под них выделяется во время выполнения программы, когда мы узнаём какого размера должен быть массив.
Пример: выделяемые (динамические) массивы
program allocatable
implicit none
integer, allocatable :: array1(:)
integer, allocatable :: array2(:,:)
allocate(array1(10))
allocate(array2(10,10))
! ...
deallocate(array1)
deallocate(array2)
end program allocatable
Память выделенная под локальные динамические массивы высвобождается автоматически когда происходит выход из области их видимости.
Символьные строки#
Пример: статические символьные строки
program string
implicit none
character(len=4) :: first_name
character(len=5) :: last_name
character(10) :: full_name
first_name = 'John'
last_name = 'Smith'
! String concatenation
full_name = first_name//' '//last_name
print *, full_name
end program string
Пример: выделяемые (динамические) символьные строки
program allocatable_string
implicit none
character(:), allocatable :: first_name
character(:), allocatable :: last_name
! Explicit allocation statement
allocate(character(4) :: first_name)
first_name = 'John'
! Allocation on assignment
last_name = 'Smith'
print *, first_name//' '//last_name
end program allocatable_string
Массив строк#
Массив строк в Fortran может быть представлен как массив переменных символьного типа character
. Все элементы в массиве типа character
имеют одинаковую длину. Однако в конструктор массива можно ввести строки разной длины, как показано в примере ниже. Они будут усечены или дополнены пробелами справа, если они длиннее или короче, соответственно, чем объявленная длина character
(символьного) массива. Наконец, мы используем встроенную функцию trim
, для удаления лишних пробелов при печати значений в стандартный вывод.
Пример: массив строк
program string_array
implicit none
character(len=10), dimension(2) :: keys, vals
keys = [character(len=10) :: "user", "dbname"]
vals = [character(len=10) :: "ben", "motivation"]
call show(keys, vals)
contains
subroutine show(akeys, avals)
character(len=*), intent(in) :: akeys(:), avals(:)
integer :: i
do i = 1, size(akeys)
print *, trim(akeys(i)), ": ", trim(avals(i))
end do
end subroutine show
end program string_array